refactor: remove "core" naming from views and eliminate converter layer (#18667)

## Summary

- **Remove all "core" prefixes** from the views system — the
metadata-based storage migration is complete, so `CoreView`,
`coreViewsSelector`, `getCoreViews`, etc. are now just `View`,
`viewsSelector`, `getViews`
- **Eliminate the entire converter layer** (15 files, ~850 lines
deleted) — `convertCoreViewToView` and all sub-converters were either
no-ops or trivially adding `__typename` / mapping identical enum values.
Local enums now re-export from generated GraphQL types directly (single
source of truth)
- **Unify `View` and `ViewWithRelations`** into one type —
`ViewWithRelations` is now a type alias for `View`, selectors return
data directly without conversion

### Backend
- Rename `@ObjectType('CoreView')` → `@ObjectType('View')` (and all
sub-entities)
- Rename resolver methods: `getCoreViews` → `getViews`, `createCoreView`
→ `createView`, etc.
- Rename `FIND_ALL_CORE_VIEWS_GRAPHQL_OPERATION` →
`FIND_ALL_VIEWS_GRAPHQL_OPERATION`

### Frontend
- Delete 15 converter files (`convertGqlView*ToView*`,
`convertView*ToGql`, `convertViewWithRelationsToView`)
- Re-export `ViewType`, `ViewKey`, `ViewFilterGroupLogicalOperator` from
generated enums (no more duplicate enum definitions with different
casing)
- Replace `ViewOpenRecordInType` with `ViewOpenRecordIn` from generated
- Remove `__typename` from all local view sub-types
- Remove unused `variant` from `ViewFilter`, make `displayValue` and
`definition` optional
- Rename ~45 GraphQL query/mutation files and all selectors to drop
"core" prefix
- Delete unused `viewsWithRelationsSelector`
This commit is contained in:
Charles Bochet
2026-03-16 09:57:18 +01:00
committed by GitHub
parent 6340b9e2f7
commit 5c745059ad
440 changed files with 2934 additions and 3856 deletions
@@ -6,7 +6,7 @@ import { recordIndexOpenRecordInState } from '@/object-record/record-index/state
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { canOpenObjectInSidePanel } from '@/object-record/utils/canOpenObjectInSidePanel';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewOpenRecordIn } from '~/generated-metadata/graphql';
import { t } from '@lingui/core/macro';
import { type MouseEvent } from 'react';
import { isDefined } from 'twenty-shared/utils';
@@ -62,13 +62,13 @@ export const RecordChip = ({
);
const canOpenInSidePanel = canOpenObjectInSidePanel(objectNameSingular);
const isSidePanelViewOpenRecordInType =
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL &&
const isSidePanelViewOpenRecordIn =
recordIndexOpenRecordIn === ViewOpenRecordIn.SIDE_PANEL &&
canOpenInSidePanel;
const handleCustomClick = isDefined(onClick)
? onClick
: isSidePanelViewOpenRecordInType
: isSidePanelViewOpenRecordIn
? (_event: MouseEvent<HTMLElement>) => {
openRecordInSidePanel({
recordId: record.id,
@@ -14,7 +14,7 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { coreViewsFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreViewsFromObjectMetadataItemFamilySelector';
import { viewsFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/viewsFromObjectMetadataItemFamilySelector';
import { ViewKey } from '@/views/types/ViewKey';
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
import { useDestroyViewFromCurrentState } from '@/views/view-picker/hooks/useDestroyViewFromCurrentState';
@@ -51,7 +51,7 @@ export const ObjectOptionsDropdownCustomView = ({
const customViewData = currentView
? {
...currentView,
key: ViewKey.Custom,
key: null,
name: currentView.name || t`Custom View`,
}
: null;
@@ -67,11 +67,11 @@ export const ObjectOptionsDropdownCustomView = ({
: undefined;
const viewsOnCurrentObject = useAtomFamilySelectorValue(
coreViewsFromObjectMetadataItemFamilySelector,
viewsFromObjectMetadataItemFamilySelector,
{ objectMetadataItemId: objectMetadataItem.id },
);
const isDefaultView = currentView?.key === ViewKey.Index;
const isDefaultView = currentView?.key === ViewKey.INDEX;
const isLastView = viewsOnCurrentObject.length <= 1;
const recordIndexCalendarLayout = useAtomStateValue(
@@ -106,10 +106,10 @@ export const ObjectOptionsDropdownCustomView = ({
'Layout',
'Visibility',
'Fields',
...(customViewData?.type === ViewType.Calendar
...(customViewData?.type === ViewType.CALENDAR
? ['CalendarDateField', 'CalendarView']
: []),
...(customViewData?.type !== ViewType.Calendar ? ['Group'] : []),
...(customViewData?.type !== ViewType.CALENDAR ? ['Group'] : []),
'Delete view',
];
@@ -140,7 +140,7 @@ export const ObjectOptionsDropdownCustomView = ({
focused={selectedItemId === 'Layout'}
onClick={() => onContentChange('layout')}
LeftIcon={viewTypeIconMapping(
customViewData?.type ?? ViewType.Table,
customViewData?.type ?? ViewType.TABLE,
)}
text={t`Layout`}
contextualText={`${capitalize(customViewData?.type ?? '')}`}
@@ -169,7 +169,7 @@ export const ObjectOptionsDropdownCustomView = ({
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
{customViewData?.type === ViewType.Calendar && (
{customViewData?.type === ViewType.CALENDAR && (
<>
<div id="calendar-date-field-picker-menu-item">
<SelectableListItem
@@ -227,7 +227,7 @@ export const ObjectOptionsDropdownCustomView = ({
hasSubMenu
/>
</SelectableListItem>
{customViewData?.type !== ViewType.Calendar && (
{customViewData?.type !== ViewType.CALENDAR && (
<div id="group-by-menu-item">
<SelectableListItem
itemId="Group"
@@ -17,7 +17,6 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
import { type GraphQLView } from '@/views/types/GraphQLView';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
import { useGetAvailableFieldsForCalendar } from '@/views/view-picker/hooks/useGetAvailableFieldsForCalendar';
import { useGetAvailableFieldsToGroupRecordsBy } from '@/views/view-picker/hooks/useGetAvailableFieldsToGroupRecordsBy';
@@ -37,7 +36,10 @@ import {
OverflowingTextWithTooltip,
} from 'twenty-ui/display';
import { MenuItem, MenuItemSelect, MenuItemToggle } from 'twenty-ui/navigation';
import { ViewCalendarLayout } from '~/generated-metadata/graphql';
import {
ViewCalendarLayout,
ViewOpenRecordIn,
} from '~/generated-metadata/graphql';
export const ObjectOptionsDropdownLayoutContent = () => {
const { t } = useLingui();
@@ -92,8 +94,8 @@ export const ObjectOptionsDropdownLayoutContent = () => {
closeDropdown(dropdownId);
return;
}
if (currentView?.type !== ViewType.Kanban) {
await setAndPersistViewType(ViewType.Kanban);
if (currentView?.type !== ViewType.KANBAN) {
await setAndPersistViewType(ViewType.KANBAN);
}
};
@@ -106,8 +108,8 @@ export const ObjectOptionsDropdownLayoutContent = () => {
closeDropdown(dropdownId);
return;
}
if (currentView?.type !== ViewType.Calendar) {
await setAndPersistViewType(ViewType.Calendar);
if (currentView?.type !== ViewType.CALENDAR) {
await setAndPersistViewType(ViewType.CALENDAR);
}
};
@@ -115,15 +117,15 @@ export const ObjectOptionsDropdownLayoutContent = () => {
const nbsp = '\u00A0';
const selectableItemIdArray = [
ViewType.Table,
...(isDefaultView ? [] : [ViewType.Kanban]),
...(!isDefaultView ? [ViewType.Calendar] : []),
ViewOpenRecordInType.SIDE_PANEL,
...(currentView?.type === ViewType.Kanban ? ['Group'] : []),
...(currentView?.type === ViewType.Calendar
ViewType.TABLE,
...(isDefaultView ? [] : [ViewType.KANBAN]),
...(!isDefaultView ? [ViewType.CALENDAR] : []),
ViewOpenRecordIn.SIDE_PANEL,
...(currentView?.type === ViewType.KANBAN ? ['Group'] : []),
...(currentView?.type === ViewType.CALENDAR
? ['CalendarView', 'CalendarDateField']
: []),
...(currentView?.type !== ViewType.Table ? ['Compact view'] : []),
...(currentView?.type !== ViewType.TABLE ? ['Compact view'] : []),
];
const selectedItemId = useAtomComponentStateValue(
@@ -152,48 +154,48 @@ export const ObjectOptionsDropdownLayoutContent = () => {
>
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId={ViewType.Table}
itemId={ViewType.TABLE}
onEnter={() => {
setAndPersistViewType(ViewType.Table);
setAndPersistViewType(ViewType.TABLE);
}}
>
<MenuItemSelect
LeftIcon={IconTable}
text={t`Table`}
selected={currentView?.type === ViewType.Table}
focused={selectedItemId === ViewType.Table}
selected={currentView?.type === ViewType.TABLE}
focused={selectedItemId === ViewType.TABLE}
onClick={async () => {
if (currentView?.type !== ViewType.Table) {
await setAndPersistViewType(ViewType.Table);
if (currentView?.type !== ViewType.TABLE) {
await setAndPersistViewType(ViewType.TABLE);
}
}}
/>
</SelectableListItem>
<SelectableListItem
itemId={ViewType.Calendar}
itemId={ViewType.CALENDAR}
onEnter={() => {
setAndPersistViewType(ViewType.Calendar);
setAndPersistViewType(ViewType.CALENDAR);
}}
>
<MenuItemSelect
LeftIcon={viewTypeIconMapping(ViewType.Calendar)}
LeftIcon={viewTypeIconMapping(ViewType.CALENDAR)}
text={t`Calendar`}
selected={currentView?.type === ViewType.Calendar}
focused={selectedItemId === ViewType.Calendar}
selected={currentView?.type === ViewType.CALENDAR}
focused={selectedItemId === ViewType.CALENDAR}
onClick={handleSelectCalendarViewType}
/>
</SelectableListItem>
<SelectableListItem
itemId={ViewType.Kanban}
itemId={ViewType.KANBAN}
onEnter={() => {
setAndPersistViewType(ViewType.Kanban);
setAndPersistViewType(ViewType.KANBAN);
}}
>
<MenuItemSelect
LeftIcon={viewTypeIconMapping(ViewType.Kanban)}
LeftIcon={viewTypeIconMapping(ViewType.KANBAN)}
text={t`Kanban`}
disabled={isDefaultView}
focused={selectedItemId === ViewType.Kanban}
focused={selectedItemId === ViewType.KANBAN}
contextualText={
isDefaultView ? (
<>
@@ -207,14 +209,14 @@ export const ObjectOptionsDropdownLayoutContent = () => {
) : undefined
}
contextualTextPosition="right"
selected={currentView?.type === ViewType.Kanban}
selected={currentView?.type === ViewType.KANBAN}
onClick={handleSelectKanbanViewType}
/>
</SelectableListItem>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
{currentView?.type === ViewType.Calendar && (
{currentView?.type === ViewType.CALENDAR && (
<>
<SelectableListItem
itemId="CalendarDateField"
@@ -253,15 +255,15 @@ export const ObjectOptionsDropdownLayoutContent = () => {
</>
)}
<SelectableListItem
itemId={ViewOpenRecordInType.SIDE_PANEL}
itemId={ViewOpenRecordIn.SIDE_PANEL}
onEnter={() => {
onContentChange('layoutOpenIn');
}}
>
<MenuItem
focused={selectedItemId === ViewOpenRecordInType.SIDE_PANEL}
focused={selectedItemId === ViewOpenRecordIn.SIDE_PANEL}
LeftIcon={
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
recordIndexOpenRecordIn === ViewOpenRecordIn.SIDE_PANEL
? IconLayoutSidebarRight
: IconLayoutNavbar
}
@@ -270,7 +272,7 @@ export const ObjectOptionsDropdownLayoutContent = () => {
onContentChange('layoutOpenIn');
}}
contextualText={
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
recordIndexOpenRecordIn === ViewOpenRecordIn.SIDE_PANEL
? t`Side Panel`
: t`Record Page`
}
@@ -278,7 +280,7 @@ export const ObjectOptionsDropdownLayoutContent = () => {
hasSubMenu
/>
</SelectableListItem>
{currentView?.type === ViewType.Kanban && (
{currentView?.type === ViewType.KANBAN && (
<SelectableListItem
itemId="Group"
onEnter={() => {
@@ -302,7 +304,7 @@ export const ObjectOptionsDropdownLayoutContent = () => {
/>
</SelectableListItem>
)}
{currentView?.type !== ViewType.Table && (
{currentView?.type !== ViewType.TABLE && (
<SelectableListItem
itemId="Compact view"
onEnter={() => {
@@ -14,7 +14,7 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewOpenRecordIn } from '~/generated-metadata/graphql';
import { t } from '@lingui/core/macro';
import {
IconChevronLeft,
@@ -41,8 +41,8 @@ export const ObjectOptionsDropdownLayoutOpenInContent = () => {
);
const selectableItemIdArray = [
ViewOpenRecordInType.SIDE_PANEL,
ViewOpenRecordInType.RECORD_PAGE,
ViewOpenRecordIn.SIDE_PANEL,
ViewOpenRecordIn.RECORD_PAGE,
];
return (
@@ -64,13 +64,13 @@ export const ObjectOptionsDropdownLayoutOpenInContent = () => {
selectableItemIdArray={selectableItemIdArray}
>
<SelectableListItem
itemId={ViewOpenRecordInType.SIDE_PANEL}
itemId={ViewOpenRecordIn.SIDE_PANEL}
onEnter={() => {
if (!canOpenInSidePanel) {
return;
}
setAndPersistOpenRecordIn(
ViewOpenRecordInType.SIDE_PANEL,
ViewOpenRecordIn.SIDE_PANEL,
currentView,
);
}}
@@ -78,17 +78,15 @@ export const ObjectOptionsDropdownLayoutOpenInContent = () => {
<MenuItemSelect
LeftIcon={IconLayoutSidebarRight}
text={t`Side Panel`}
selected={
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
}
focused={selectedItemId === ViewOpenRecordInType.SIDE_PANEL}
selected={recordIndexOpenRecordIn === ViewOpenRecordIn.SIDE_PANEL}
focused={selectedItemId === ViewOpenRecordIn.SIDE_PANEL}
onClick={() => {
if (!canOpenInSidePanel) {
return;
}
setAndPersistOpenRecordIn(
ViewOpenRecordInType.SIDE_PANEL,
ViewOpenRecordIn.SIDE_PANEL,
currentView,
);
}}
@@ -96,10 +94,10 @@ export const ObjectOptionsDropdownLayoutOpenInContent = () => {
/>
</SelectableListItem>
<SelectableListItem
itemId={ViewOpenRecordInType.RECORD_PAGE}
itemId={ViewOpenRecordIn.RECORD_PAGE}
onEnter={() =>
setAndPersistOpenRecordIn(
ViewOpenRecordInType.RECORD_PAGE,
ViewOpenRecordIn.RECORD_PAGE,
currentView,
)
}
@@ -108,15 +106,15 @@ export const ObjectOptionsDropdownLayoutOpenInContent = () => {
LeftIcon={IconLayoutNavbar}
text={t`Record Page`}
selected={
recordIndexOpenRecordIn === ViewOpenRecordInType.RECORD_PAGE
recordIndexOpenRecordIn === ViewOpenRecordIn.RECORD_PAGE
}
onClick={() =>
setAndPersistOpenRecordIn(
ViewOpenRecordInType.RECORD_PAGE,
ViewOpenRecordIn.RECORD_PAGE,
currentView,
)
}
focused={selectedItemId === ViewOpenRecordInType.RECORD_PAGE}
focused={selectedItemId === ViewOpenRecordIn.RECORD_PAGE}
/>
</SelectableListItem>
</SelectableList>
@@ -6,7 +6,7 @@ import { ViewKey } from '@/views/types/ViewKey';
export const ObjectOptionsDropdownMenuContent = () => {
const { currentView } = useGetCurrentViewOnly();
const isDefaultView = currentView?.key === ViewKey.Index;
const isDefaultView = currentView?.key === ViewKey.INDEX;
if (isDefaultView) {
return <ObjectOptionsDropdownDefaultView />;
@@ -127,7 +127,7 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer>
{viewType === ViewType.Table && (
{viewType === ViewType.TABLE && (
<MenuItemSelect
text={t`None`}
selected={!isDefined(recordIndexGroupFieldMetadataItem)}
@@ -108,7 +108,7 @@ const createStory = (contentId: ObjectOptionsContentId | null): Story => ({
>
<ObjectOptionsDropdownContext.Provider
value={{
viewType: ViewType.Table,
viewType: ViewType.TABLE,
objectMetadataItem: companyObjectMetadataItem,
recordIndexId: instanceId,
currentContentId: contentId,
@@ -5,10 +5,9 @@ import { useRecordIndexContextOrThrow } from '@/object-record/record-index/conte
import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/useLoadRecordIndexStates';
import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState';
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
import { coreViewsSelector } from '@/views/states/selectors/coreViewsSelector';
import { viewsSelector } from '@/views/states/selectors/viewsSelector';
import { type GraphQLView } from '@/views/types/GraphQLView';
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
import { useGetAvailableFieldsForCalendar } from '@/views/view-picker/hooks/useGetAvailableFieldsForCalendar';
import { useGetAvailableFieldsToGroupRecordsBy } from '@/views/view-picker/hooks/useGetAvailableFieldsToGroupRecordsBy';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
@@ -38,27 +37,25 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => {
}),
);
const existingCoreViews = store.get(coreViewsSelector.atom);
const existingViews = store.get(viewsSelector.atom);
if (!isDefined(currentViewId)) {
throw new Error('No view id found');
}
const currentCoreView = existingCoreViews.find(
(coreView) => coreView.id === currentViewId,
const currentView = existingViews.find(
(view) => view.id === currentViewId,
);
if (!isDefined(currentCoreView)) {
if (!isDefined(currentView)) {
throw new Error('No current view found');
}
const currentView = convertCoreViewToView(currentCoreView);
const updateCurrentViewParams: Partial<GraphQLView> = {};
updateCurrentViewParams.type = viewType;
switch (viewType) {
case ViewType.Kanban: {
case ViewType.KANBAN: {
if (availableFieldsForGrouping.length === 0) {
throw new Error('No fields for kanban - should not happen');
}
@@ -76,7 +73,7 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => {
await updateCurrentView(updateCurrentViewParams);
return;
}
case ViewType.Table: {
case ViewType.TABLE: {
if (shouldChangeIcon(currentView.icon, currentView.type)) {
updateCurrentViewParams.icon =
viewTypeIconMapping(viewType).displayName;
@@ -86,7 +83,7 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => {
setRecordIndexViewType(viewType);
return;
}
case ViewType.Calendar: {
case ViewType.CALENDAR: {
if (availableFieldsForCalendar.length === 0) {
throw new Error('No date fields for calendar');
}
@@ -115,7 +112,7 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => {
updateCurrentViewParams.mainGroupByFieldMetadataId = null;
return await updateCurrentView(updateCurrentViewParams);
}
case ViewType.FieldsWidget: {
case ViewType.FIELDS_WIDGET: {
return;
}
default: {
@@ -139,20 +136,20 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => {
oldViewType: ViewType,
): boolean => {
if (
oldViewType === ViewType.Kanban &&
oldIcon === viewTypeIconMapping(ViewType.Kanban).displayName
oldViewType === ViewType.KANBAN &&
oldIcon === viewTypeIconMapping(ViewType.KANBAN).displayName
) {
return true;
}
if (
oldViewType === ViewType.Table &&
oldIcon === viewTypeIconMapping(ViewType.Table).displayName
oldViewType === ViewType.TABLE &&
oldIcon === viewTypeIconMapping(ViewType.TABLE).displayName
) {
return true;
}
if (
oldViewType === ViewType.Calendar &&
oldIcon === viewTypeIconMapping(ViewType.Calendar).displayName
oldViewType === ViewType.CALENDAR &&
oldIcon === viewTypeIconMapping(ViewType.CALENDAR).displayName
) {
return true;
}
@@ -4,7 +4,7 @@ import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomStat
import { useStore } from 'jotai';
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
import { type GraphQLView } from '@/views/types/GraphQLView';
import { type ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { type ViewOpenRecordIn } from '~/generated-metadata/graphql';
import { viewPickerInputNameComponentState } from '@/views/view-picker/states/viewPickerInputNameComponentState';
import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states/viewPickerSelectedIconComponentState';
import { useCallback } from 'react';
@@ -27,7 +27,7 @@ export const useUpdateObjectViewOptions = () => {
const { updateCurrentView } = useUpdateCurrentView();
const setAndPersistOpenRecordIn = useCallback(
(openRecordIn: ViewOpenRecordInType, view: GraphQLView | undefined) => {
(openRecordIn: ViewOpenRecordIn, view: GraphQLView | undefined) => {
if (!view) return;
setRecordIndexOpenRecordIn(openRecordIn);
store.set(recordIndexOpenRecordInState.atom, openRecordIn);
@@ -16,7 +16,7 @@ const StyledColumnContainer = styled.div`
export const RecordBoardColumns = () => {
const visibleRecordGroupIds = useAtomComponentFamilySelectorValue(
visibleRecordGroupIdsComponentFamilySelector,
ViewType.Kanban,
ViewType.KANBAN,
);
return (
@@ -41,7 +41,7 @@ export const RecordBoardFetchMoreInViewTriggerComponent = () => {
const visibleRecordGroupIds = useAtomComponentFamilySelectorValue(
visibleRecordGroupIdsComponentFamilySelector,
ViewType.Kanban,
ViewType.KANBAN,
);
const componentWidth =
@@ -29,7 +29,7 @@ const StyledHeaderContainer = styled.div`
export const RecordBoardHeader = () => {
const visibleRecordGroupIds = useAtomComponentFamilySelectorValue(
visibleRecordGroupIdsComponentFamilySelector,
ViewType.Kanban,
ViewType.KANBAN,
);
return (
@@ -24,7 +24,7 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => {
const visibleRecordGroupIds = useAtomComponentFamilySelectorValue(
visibleRecordGroupIdsComponentFamilySelector,
ViewType.Kanban,
ViewType.KANBAN,
);
const recordIdsByGroupState = useAtomComponentFamilyStateCallbackState(
@@ -17,7 +17,7 @@ import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomC
import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewOpenRecordIn } from '~/generated-metadata/graphql';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
@@ -76,7 +76,7 @@ export const RecordBoardCardHeader = () => {
const recordStore = useAtomFamilyStateValue(recordStoreFamilyState, recordId);
const triggerEvent =
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
recordIndexOpenRecordIn === ViewOpenRecordIn.SIDE_PANEL
? 'CLICK'
: 'MOUSE_DOWN';
@@ -6,7 +6,7 @@ import { MenuItem } from 'twenty-ui/navigation';
export const RecordBoardColumnDropdownMenu = () => {
const recordGroupActions = useRecordGroupActions({
viewType: ViewType.Kanban,
viewType: ViewType.KANBAN,
});
return (
@@ -25,9 +25,9 @@ import { ContextStoreDecorator } from '~/testing/decorators/ContextStoreDecorato
import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { mockedCoreViews } from '~/testing/mock-data/generated/metadata/views/mock-views-data';
import { mockedViews } from '~/testing/mock-data/generated/metadata/views/mock-views-data';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { setTestCoreViewsInMetadataStore } from '~/testing/utils/setTestCoreViewsInMetadataStore';
import { setTestViewsInMetadataStore } from '~/testing/utils/setTestViewsInMetadataStore';
const meta: Meta<typeof RecordCalendarMonth> = {
title: 'Modules/ObjectRecord/RecordCalendar/Month',
@@ -44,9 +44,7 @@ const meta: Meta<typeof RecordCalendarMonth> = {
instanceId,
);
const mockCoreView = mockedCoreViews.find(
(v) => v.name === 'All Companies',
)!;
const mockView = mockedViews.find((v) => v.name === 'All Companies')!;
const setContextStoreCurrentViewId = useSetAtomComponentState(
contextStoreCurrentViewIdComponentState,
@@ -71,14 +69,14 @@ const meta: Meta<typeof RecordCalendarMonth> = {
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
setTestCoreViewsInMetadataStore(jotaiStore, [mockCoreView]);
setContextStoreCurrentViewId(mockCoreView.id);
setTestViewsInMetadataStore(jotaiStore, [mockView]);
setContextStoreCurrentViewId(mockView.id);
setCurrentRecordFields(columns);
setIsLoaded(true);
}, [
setContextStoreCurrentViewId,
setCurrentRecordFields,
mockCoreView,
mockView,
columns,
]);
@@ -22,7 +22,7 @@ import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDrop
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { coreIndexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreIndexViewIdFromObjectMetadataItemFamilySelector';
import { indexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/indexViewIdFromObjectMetadataItemFamilySelector';
import { useLingui } from '@lingui/react/macro';
import {
AppPath,
@@ -107,7 +107,7 @@ export const RecordDetailRelationSection = ({
);
const indexViewId = useAtomFamilySelectorValue(
coreIndexViewIdFromObjectMetadataItemFamilySelector,
indexViewIdFromObjectMetadataItemFamilySelector,
{ objectMetadataItemId: relationObjectMetadataItem.id },
);
@@ -54,7 +54,7 @@ export const RecordIndexContainer = () => {
<ObjectOptionsDropdown
recordIndexId={recordIndexId}
objectMetadataItem={objectMetadataItem}
viewType={recordIndexViewType ?? ViewType.Table}
viewType={recordIndexViewType ?? ViewType.TABLE}
/>
}
/>
@@ -64,12 +64,12 @@ export const RecordIndexContainer = () => {
/>
</SpreadsheetImportProvider>
<RecordIndexFiltersToContextStoreEffect />
{recordIndexViewType === ViewType.Table && (
{recordIndexViewType === ViewType.TABLE && (
<>
<RecordIndexTableContainer recordTableId={recordIndexId} />
</>
)}
{recordIndexViewType === ViewType.Kanban && (
{recordIndexViewType === ViewType.KANBAN && (
<StyledContainerWithPadding>
<RecordBoardContainer
recordBoardId={recordIndexId}
@@ -78,7 +78,7 @@ export const RecordIndexContainer = () => {
/>
</StyledContainerWithPadding>
)}
{recordIndexViewType === ViewType.Calendar && (
{recordIndexViewType === ViewType.CALENDAR && (
<StyledContainerWithPadding>
<RecordIndexCalendarContainer
recordCalendarInstanceId={recordIndexId}
@@ -4,7 +4,7 @@ import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/use
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
import { useCreateDefaultViewForObject } from '@/views/hooks/useCreateDefaultViewForObject';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
import { viewFromViewIdFamilySelector } from '@/views/states/selectors/viewFromViewIdFamilySelector';
import { useEffect, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
@@ -18,7 +18,7 @@ export const RecordIndexLoadBaseOnContextStoreEffect = () => {
undefined,
);
const view = useAtomFamilySelectorValue(coreViewFromViewIdFamilySelector, {
const view = useAtomFamilySelectorValue(viewFromViewIdFamilySelector, {
viewId: contextStoreCurrentViewId ?? '',
});
@@ -5,7 +5,7 @@ import { useNavigationMenuItemsData } from '@/navigation-menu-item/hooks/useNavi
import { getStandardObjectIconColor } from '@/navigation-menu-item/utils/getStandardObjectIconColor';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
import { coreIndexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreIndexViewIdFromObjectMetadataItemFamilySelector';
import { indexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/indexViewIdFromObjectMetadataItemFamilySelector';
import { isDefined } from 'twenty-shared/utils';
import { useIcons } from 'twenty-ui/display';
@@ -16,7 +16,7 @@ export const RecordIndexPageHeaderIcon = ({
}) => {
const { workspaceNavigationMenuItems } = useNavigationMenuItemsData();
const coreIndexViewId = useAtomFamilySelectorValue(
coreIndexViewIdFromObjectMetadataItemFamilySelector,
indexViewIdFromObjectMetadataItemFamilySelector,
{ objectMetadataItemId: objectMetadataItem?.id ?? '' },
);
const { getIcon } = useIcons();
@@ -109,7 +109,7 @@ describe('useRecordData', () => {
pageSize: 30,
callback,
delayMs: 0,
viewType: ViewType.Kanban,
viewType: ViewType.KANBAN,
}),
{
wrapper: Wrapper,
@@ -51,7 +51,7 @@ export const useRecordIndexLazyFetchRecords = ({
pageSize = EXPORT_TABLE_DATA_DEFAULT_PAGE_SIZE,
recordIndexId,
callback,
viewType = ViewType.Table,
viewType = ViewType.TABLE,
}: UseRecordDataOptions) => {
const { hiddenBoardFields } = useObjectOptionsForBoard({
objectNameSingular: objectMetadataItem.nameSingular,
@@ -129,7 +129,7 @@ export const useRecordIndexLazyFetchRecords = ({
};
})
.filter(isDefined),
...(hiddenKanbanFieldColumn && viewType === ViewType.Kanban
...(hiddenKanbanFieldColumn && viewType === ViewType.KANBAN
? [hiddenKanbanFieldColumn]
: []),
];
@@ -7,12 +7,11 @@ import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/h
import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useGetViewFromState } from '@/views/hooks/useGetViewFromState';
import { type ViewGroup } from '@/views/types/ViewGroup';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { type CoreView } from '~/generated-metadata/graphql';
import { type View as GqlView } from '~/generated-metadata/graphql';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const useHandleRecordGroupField = () => {
@@ -60,12 +59,11 @@ export const useHandleRecordGroupField = () => {
});
if (updatedViewResult.status === 'successful') {
const updatedCoreView = updatedViewResult.response.data
?.updateCoreView as CoreView;
const updatedView = updatedViewResult.response.data
?.updateView as GqlView;
if (isDefined(updatedCoreView)) {
const updatedViewConverted = convertCoreViewToView(updatedCoreView);
await loadRecordIndexStates(updatedViewConverted, objectMetadataItem);
if (isDefined(updatedView)) {
await loadRecordIndexStates(updatedView, objectMetadataItem);
}
}
@@ -84,7 +82,6 @@ export const useHandleRecordGroupField = () => {
.map(
(option, index) =>
({
__typename: 'ViewGroup',
id: v4(),
fieldValue: option.value,
isVisible: true,
@@ -97,7 +94,6 @@ export const useHandleRecordGroupField = () => {
fieldMetadataItem.isNullable === true
) {
viewGroupsToCreate.push({
__typename: 'ViewGroup',
id: v4(),
fieldValue: '',
isVisible: true,
@@ -9,7 +9,7 @@ import { recordIndexOpenRecordInState } from '@/object-record/record-index/state
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
import { canOpenObjectInSidePanel } from '@/object-record/utils/canOpenObjectInSidePanel';
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewOpenRecordIn } from '~/generated-metadata/graphql';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { AppPath } from 'twenty-shared/types';
@@ -72,7 +72,7 @@ export const useOpenRecordFromIndexView = () => {
if (
!isMobile &&
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL &&
recordIndexOpenRecordIn === ViewOpenRecordIn.SIDE_PANEL &&
canOpenObjectInSidePanel(objectNameSingular)
) {
openRecordInSidePanel({
@@ -1,8 +1,7 @@
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
import { ViewOpenRecordIn } from '~/generated-metadata/graphql';
export const recordIndexOpenRecordInState =
createAtomState<ViewOpenRecordInType>({
key: 'recordIndexOpenRecordInState',
defaultValue: ViewOpenRecordInType.SIDE_PANEL,
});
export const recordIndexOpenRecordInState = createAtomState<ViewOpenRecordIn>({
key: 'recordIndexOpenRecordInState',
defaultValue: ViewOpenRecordIn.SIDE_PANEL,
});
@@ -12,10 +12,10 @@ import { RecordTableDecorator } from '~/testing/decorators/RecordTableDecorator'
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
import { mockedCompanyRecords } from '~/testing/mock-data/generated/data/companies/mock-companies-data';
import { mockedCoreViews } from '~/testing/mock-data/generated/metadata/views/mock-views-data';
import { mockedViews } from '~/testing/mock-data/generated/metadata/views/mock-views-data';
import { sleep } from '~/utils/sleep';
const companyView = mockedCoreViews.find((v) => v.name === 'All Companies')!;
const companyView = mockedViews.find((v) => v.name === 'All Companies')!;
const meta: Meta = {
title: 'Modules/ObjectRecord/RecordTable/RecordTable',
@@ -12,7 +12,7 @@ import { RECORD_TABLE_CELL_INPUT_ID_PREFIX } from '@/object-record/record-table/
import { RECORD_TABLE_COLUMN_MIN_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnMinWidth';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewOpenRecordIn } from '~/generated-metadata/graphql';
type RecordTableContextProviderProps = {
viewBarId: string;
@@ -47,7 +47,7 @@ export const RecordTableContextProvider = ({
recordIndexOpenRecordInState,
);
const triggerEvent =
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
recordIndexOpenRecordIn === ViewOpenRecordIn.SIDE_PANEL
? 'CLICK'
: 'MOUSE_DOWN';
@@ -15,7 +15,7 @@ import { canOpenObjectInSidePanel } from '@/object-record/utils/canOpenObjectInS
import { useAtomComponentFamilyStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateCallbackState';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewOpenRecordIn } from '~/generated-metadata/graphql';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { AppPath } from 'twenty-shared/types';
@@ -88,7 +88,7 @@ export const useCreateNewIndexRecord = ({
});
if (
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL &&
recordIndexOpenRecordIn === ViewOpenRecordIn.SIDE_PANEL &&
canOpenObjectInSidePanel(objectMetadataItem.nameSingular)
) {
openRecordInSidePanel({
@@ -26,7 +26,7 @@ export const RecordTableRecordGroupsBody = () => {
const visibleRecordGroupIds = useAtomComponentFamilySelectorValue(
visibleRecordGroupIdsComponentFamilySelector,
ViewType.Table,
ViewType.TABLE,
);
if (isRecordTableInitialLoading && allRecordIds.length === 0) {
@@ -27,7 +27,7 @@ import { clickOutsideListenerIsActivatedComponentState } from '@/ui/utilities/po
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewOpenRecordIn } from '~/generated-metadata/graphql';
export type OpenTableCellArgs = {
initialValue?: string;
@@ -110,7 +110,7 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
const openRecordIn = store.get(recordIndexOpenRecordInState.atom);
if (openRecordIn === ViewOpenRecordInType.SIDE_PANEL) {
if (openRecordIn === ViewOpenRecordIn.SIDE_PANEL) {
activateRecordTableRow(cellPosition.row);
unfocusRecordTableRow();
}