410 open in side panel (#10363)

Closes https://github.com/twentyhq/core-team-issues/issues/410

- Added `openRecordIn` column in the `view` entity, which is set to
`SIDE_PANEL` by default
- Created a new option inside the view option dropdown to be able to set
`openRecordIn`
- Updated all record show page openings to reflect the setting behavior
- For `workflow`, `workflowVersion` and `workflowRun` (what I call
workflow objects), we want the default view `openRecordIn` to be set to
`RECORD_PAGE`. When seeding the views for the new workspaces, we set
`openRecordIn` to `RECORD_PAGE` for workflow objects. Since the workflow
objects views `openRecordIn` will be set to the default value
`SIDE_PANEL` for the existing workspaces when the sync metadata runs, I
created a script to run in the 0.43 update to update this value.
- Updated `closeCommandMenu` because of problems introduced by the
animate presence wrapper around the command menu. We now reset the
states at the end of the animation.

Note: We want to be able to open all workflow objects pages in the side
panel, but this requires some refactoring of the workflow module. For
now @Bonapara wanted to allow the possibility to change the
`openRecordIn` setting to `SIDE_PANEL` even for the workflows even if
it's buggy and not ready for the moment. Since this is an experimental
feature, it shouldn't cause too many problems.
This commit is contained in:
Raphaël Bosi
2025-02-21 10:27:33 +01:00
committed by GitHub
parent e301c7856b
commit 9f454c565b
102 changed files with 921 additions and 218 deletions

View File

@ -48,7 +48,11 @@ export const CommandMenuContainer = ({
}: {
children: React.ReactNode;
}) => {
const { toggleCommandMenu, closeCommandMenu } = useCommandMenu();
const {
toggleCommandMenu,
closeCommandMenu,
onCommandMenuCloseAnimationComplete,
} = useCommandMenu();
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
@ -98,7 +102,7 @@ export const CommandMenuContainer = ({
>
<ActionMenuContext.Provider
value={{
isInRightDrawer: false,
isInRightDrawer: true,
onActionExecutedCallback: ({ key }) => {
if (
key !== RecordAgnosticActionsKey.SEARCH_RECORDS &&
@ -121,7 +125,10 @@ export const CommandMenuContainer = ({
<RunWorkflowRecordAgnosticActionMenuEntriesSetter />
)}
<ActionMenuConfirmationModals />
<AnimatePresence mode="wait">
<AnimatePresence
mode="wait"
onExitComplete={onCommandMenuCloseAnimationComplete}
>
{isCommandMenuOpened && (
<StyledCommandMenu
data-testid="command-menu"

View File

@ -34,16 +34,17 @@ export const CommandMenuContextChipGroupsWithRecordSelection = ({
/>
));
const recordSelectionContextChip = totalCount
? {
text: getSelectedRecordsContextText(
objectMetadataItem,
records,
totalCount,
),
Icons: Avatars,
}
: undefined;
const recordSelectionContextChip =
totalCount && records.length > 0
? {
text: getSelectedRecordsContextText(
objectMetadataItem,
records,
totalCount,
),
Icons: Avatars,
}
: undefined;
const contextChipsWithRecordSelection = [
recordSelectionContextChip,

View File

@ -21,7 +21,7 @@ export const CommandMenuContextRecordChip = ({
instanceId,
});
if (loading || !totalCount) {
if (loading || !totalCount || records.length === 0) {
return null;
}

View File

@ -192,6 +192,7 @@ describe('useCommandMenu', () => {
act(() => {
result.current.commandMenu.goBackFromCommandMenu();
result.current.commandMenu.onCommandMenuCloseAnimationComplete();
});
expect(result.current.commandMenuNavigationStack).toEqual([]);

View File

@ -74,31 +74,33 @@ export const useCommandMenu = () => {
);
const closeCommandMenu = useRecoilCallback(
({ snapshot, set }) =>
({ set }) =>
() => {
const isCommandMenuOpened = snapshot
.getLoadable(isCommandMenuOpenedState)
.getValue();
set(isCommandMenuOpenedState, false);
},
[],
);
if (isCommandMenuOpened) {
resetContextStoreStates('command-menu');
resetContextStoreStates('command-menu-previous');
const onCommandMenuCloseAnimationComplete = useRecoilCallback(
({ set }) =>
() => {
resetContextStoreStates('command-menu');
resetContextStoreStates('command-menu-previous');
set(viewableRecordIdState, null);
set(commandMenuPageState, CommandMenuPages.Root);
set(commandMenuPageInfoState, {
title: undefined,
Icon: undefined,
});
set(isCommandMenuOpenedState, false);
set(commandMenuSearchState, '');
set(commandMenuNavigationStackState, []);
resetSelectedItem();
set(hasUserSelectedCommandState, false);
goBackToPreviousHotkeyScope();
set(viewableRecordIdState, null);
set(commandMenuPageState, CommandMenuPages.Root);
set(commandMenuPageInfoState, {
title: undefined,
Icon: undefined,
});
set(isCommandMenuOpenedState, false);
set(commandMenuSearchState, '');
set(commandMenuNavigationStackState, []);
resetSelectedItem();
set(hasUserSelectedCommandState, false);
goBackToPreviousHotkeyScope();
emitRightDrawerCloseEvent();
}
emitRightDrawerCloseEvent();
},
[goBackToPreviousHotkeyScope, resetContextStoreStates, resetSelectedItem],
);
@ -109,7 +111,10 @@ export const useCommandMenu = () => {
page,
pageTitle,
pageIcon,
}: CommandMenuNavigationStackItem) => {
resetNavigationStack = false,
}: CommandMenuNavigationStackItem & {
resetNavigationStack?: boolean;
}) => {
set(commandMenuPageState, page);
set(commandMenuPageInfoState, {
title: pageTitle,
@ -120,10 +125,14 @@ export const useCommandMenu = () => {
.getLoadable(commandMenuNavigationStackState)
.getValue();
set(commandMenuNavigationStackState, [
...currentNavigationStack,
{ page, pageTitle, pageIcon },
]);
if (resetNavigationStack) {
set(commandMenuNavigationStackState, [{ page, pageTitle, pageIcon }]);
} else {
set(commandMenuNavigationStackState, [
...currentNavigationStack,
{ page, pageTitle, pageIcon },
]);
}
openCommandMenu();
};
},
@ -248,6 +257,7 @@ export const useCommandMenu = () => {
? t`New ${capitalizedObjectNameSingular}`
: capitalizedObjectNameSingular,
pageIcon: Icon,
resetNavigationStack: true,
});
};
},
@ -315,6 +325,7 @@ export const useCommandMenu = () => {
return {
openRootCommandMenu,
closeCommandMenu,
onCommandMenuCloseAnimationComplete,
navigateCommandMenu,
navigateCommandMenuHistory,
goBackFromCommandMenu,

View File

@ -7,6 +7,7 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations';
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { AppPath } from '@/types/AppPath';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import { getCompanyObjectMetadataItem } from '~/testing/mock-data/companies';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
@ -38,6 +39,7 @@ const renderHooks = ({
type: ViewType.Table,
key: null,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFields: [],
viewGroups: [],
viewSorts: [],

View File

@ -1,9 +1,13 @@
import { AvatarChip, AvatarChipVariant } from 'twenty-ui';
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { getLinkToShowPage } from '@/object-metadata/utils/getLinkToShowPage';
import { useRecordChipData } from '@/object-record/hooks/useRecordChipData';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { MouseEvent } from 'react';
import { useRecoilValue } from 'recoil';
export type RecordChipProps = {
objectNameSingular: string;
@ -23,8 +27,18 @@ export const RecordChip = ({
record,
});
const { openRecordInCommandMenu } = useCommandMenu();
const recordIndexOpenRecordIn = useRecoilValue(recordIndexOpenRecordInState);
const handleClick = (e: MouseEvent<Element>) => {
e.stopPropagation();
if (recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL) {
openRecordInCommandMenu({
recordId: record.id,
objectNameSingular,
});
}
};
return (
@ -36,7 +50,11 @@ export const RecordChip = ({
className={className}
variant={variant}
onClick={handleClick}
to={getLinkToShowPage(objectNameSingular, record)}
to={
recordIndexOpenRecordIn === ViewOpenRecordInType.RECORD_PAGE
? getLinkToShowPage(objectNameSingular, record)
: undefined
}
/>
);
};

View File

@ -6,6 +6,7 @@ import { ObjectOptionsDropdownRecordGroupFieldsContent } from '@/object-record/o
import { ObjectOptionsDropdownRecordGroupsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupsContent';
import { ObjectOptionsDropdownRecordGroupSortContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupSortContent';
import { ObjectOptionsDropdownViewSettingsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownViewSettingsContent';
import { ObjectOptionsDropdownViewSettingsOpenInContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownViewSettingsOpenInContent';
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
export const ObjectOptionsDropdownContent = () => {
@ -14,6 +15,8 @@ export const ObjectOptionsDropdownContent = () => {
switch (currentContentId) {
case 'viewSettings':
return <ObjectOptionsDropdownViewSettingsContent />;
case 'viewSettingsOpenIn':
return <ObjectOptionsDropdownViewSettingsOpenInContent />;
case 'fields':
return <ObjectOptionsDropdownFieldsContent />;
case 'hiddenFields':

View File

@ -31,7 +31,6 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { ViewType } from '@/views/types/ViewType';
import { isDefined } from 'twenty-shared';
export const ObjectOptionsDropdownMenuContent = () => {
@ -104,20 +103,17 @@ export const ObjectOptionsDropdownMenuContent = () => {
<DropdownMenuHeader StartIcon={CurrentViewIcon ?? IconList}>
{currentView?.name}
</DropdownMenuHeader>
{/** TODO: Should be removed when view settings contains more options */}
{viewType === ViewType.Kanban && (
<>
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem
onClick={() => onContentChange('viewSettings')}
LeftIcon={IconLayout}
text="View settings"
hasSubMenu
/>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
</>
)}
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem
onClick={() => onContentChange('viewSettings')}
LeftIcon={IconLayout}
text="View settings"
hasSubMenu
/>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem
onClick={() => onContentChange('fields')}

View File

@ -1,21 +1,32 @@
import {
IconBaselineDensitySmall,
IconChevronLeft,
IconLayoutNavbar,
IconLayoutSidebarRight,
MenuItem,
MenuItemToggle,
} from 'twenty-ui';
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import { useRecoilValue } from 'recoil';
export const ObjectOptionsDropdownViewSettingsContent = () => {
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
const { recordIndexId, objectMetadataItem, viewType, resetContent } =
useOptionsDropdown();
const {
recordIndexId,
objectMetadataItem,
viewType,
resetContent,
onContentChange,
} = useOptionsDropdown();
const { isCompactModeActive, setAndPersistIsCompactModeActive } =
useObjectOptionsForBoard({
@ -24,12 +35,29 @@ export const ObjectOptionsDropdownViewSettingsContent = () => {
viewBarId: recordIndexId,
});
const recordIndexOpenRecordIn = useRecoilValue(recordIndexOpenRecordInState);
return (
<>
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={resetContent}>
View settings
</DropdownMenuHeader>
<DropdownMenuItemsContainer>
<MenuItem
onClick={() => onContentChange('viewSettingsOpenIn')}
LeftIcon={
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
? IconLayoutSidebarRight
: IconLayoutNavbar
}
text="Open in"
contextualText={
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
? 'Side Panel'
: 'Record Page'
}
hasSubMenu
/>
{viewType === ViewType.Kanban && (
<MenuItemToggle
LeftIcon={IconBaselineDensitySmall}

View File

@ -0,0 +1,60 @@
import {
IconChevronLeft,
IconLayoutNavbar,
IconLayoutSidebarRight,
MenuItemSelect,
} from 'twenty-ui';
import { useObjectOptions } from '@/object-record/object-options-dropdown/hooks/useObjectOptions';
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { t } from '@lingui/core/macro';
import { useRecoilValue } from 'recoil';
export const ObjectOptionsDropdownViewSettingsOpenInContent = () => {
const { onContentChange } = useOptionsDropdown();
const recordIndexOpenRecordIn = useRecoilValue(recordIndexOpenRecordInState);
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
const { setAndPersistOpenRecordIn } = useObjectOptions();
return (
<>
<DropdownMenuHeader
StartIcon={IconChevronLeft}
onClick={() => onContentChange('viewSettings')}
>
{t`Open in`}
</DropdownMenuHeader>
<DropdownMenuItemsContainer>
<MenuItemSelect
LeftIcon={IconLayoutSidebarRight}
text="Side Panel"
selected={recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL}
onClick={() =>
setAndPersistOpenRecordIn(
ViewOpenRecordInType.SIDE_PANEL,
currentViewWithCombinedFiltersAndSorts,
)
}
/>
<MenuItemSelect
LeftIcon={IconLayoutNavbar}
text="Record Page"
selected={
recordIndexOpenRecordIn === ViewOpenRecordInType.RECORD_PAGE
}
onClick={() =>
setAndPersistOpenRecordIn(
ViewOpenRecordInType.RECORD_PAGE,
currentViewWithCombinedFiltersAndSorts,
)
}
/>
</DropdownMenuItemsContainer>
</>
);
};

View File

@ -0,0 +1,29 @@
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
import { GraphQLView } from '@/views/types/GraphQLView';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { useCallback } from 'react';
import { useSetRecoilState } from 'recoil';
export const useObjectOptions = () => {
const setRecordIndexOpenRecordIn = useSetRecoilState(
recordIndexOpenRecordInState,
);
const { updateCurrentView } = useUpdateCurrentView();
const setAndPersistOpenRecordIn = useCallback(
(openRecordIn: ViewOpenRecordInType, view: GraphQLView | undefined) => {
if (!view) return;
setRecordIndexOpenRecordIn(openRecordIn);
updateCurrentView({
openRecordIn,
});
},
[setRecordIndexOpenRecordIn, updateCurrentView],
);
return {
setAndPersistOpenRecordIn,
};
};

View File

@ -1,5 +1,6 @@
export type ObjectOptionsContentId =
| 'viewSettings'
| 'viewSettingsOpenIn'
| 'fields'
| 'hiddenFields'
| 'recordGroups'

View File

@ -1,42 +1,45 @@
import {
AvatarChipVariant,
Checkbox,
CheckboxVariant,
LightIconButton,
IconEye,
IconEyeOff,
} from 'twenty-ui';
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
import { RecordBoardCardHeaderContainer } from '@/object-record/record-board/record-board-card/components/RecordBoardCardHeaderContainer';
import { RecordInlineCellEditMode } from '@/object-record/record-inline-cell/components/RecordInlineCellEditMode';
import styled from '@emotion/styled';
import { TextInput } from '@/ui/input/components/TextInput';
import { Dispatch, SetStateAction, useContext, useState } from 'react';
import { StopPropagationContainer } from '@/object-record/record-board/record-board-card/components/StopPropagationContainer';
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard';
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
import { RecordBoardFieldDefinition } from '@/object-record/record-board/types/RecordBoardFieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import {
FieldContext,
RecordUpdateHook,
RecordUpdateHookParams,
} from '@/object-record/record-field/contexts/FieldContext';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { getFieldButtonIcon } from '@/object-record/record-field/utils/getFieldButtonIcon';
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
import { useRecoilValue } from 'recoil';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
import { RecordIdentifierChip } from '@/object-record/record-index/components/RecordIndexRecordChip';
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2';
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
import { RecordInlineCellEditMode } from '@/object-record/record-inline-cell/components/RecordInlineCellEditMode';
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { TextInput } from '@/ui/input/components/TextInput';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
import { StopPropagationContainer } from '@/object-record/record-board/record-board-card/components/StopPropagationContainer';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import styled from '@emotion/styled';
import { Dispatch, SetStateAction, useContext, useState } from 'react';
import { useRecoilValue } from 'recoil';
import {
AvatarChipVariant,
Checkbox,
CheckboxVariant,
IconEye,
IconEyeOff,
LightIconButton,
} from 'twenty-ui';
const StyledTextInput = styled(TextInput)`
border-radius: ${({ theme }) => theme.border.radius.sm};
@ -116,6 +119,10 @@ export const RecordBoardCardHeader = ({
return [updateEntity, { loading: false }];
};
const recordIndexOpenRecordIn = useRecoilValue(recordIndexOpenRecordInState);
const { openRecordInCommandMenu } = useCommandMenu();
return (
<RecordBoardCardHeaderContainer showCompactView={showCompactView}>
<StopPropagationContainer>
@ -178,7 +185,21 @@ export const RecordBoardCardHeader = ({
record={record as ObjectRecord}
variant={AvatarChipVariant.Transparent}
maxWidth={150}
to={indexIdentifierUrl(recordId)}
onClick={
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
? () => {
openRecordInCommandMenu({
recordId,
objectNameSingular: objectMetadataItem.nameSingular,
});
}
: undefined
}
to={
recordIndexOpenRecordIn === ViewOpenRecordInType.RECORD_PAGE
? indexIdentifierUrl(recordId)
: undefined
}
/>
)}
</StopPropagationContainer>

View File

@ -1,6 +1,10 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { RecordChip } from '@/object-record/components/RecordChip';
import { useChipFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useChipFieldDisplay';
import { RecordIdentifierChip } from '@/object-record/record-index/components/RecordIndexRecordChip';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { useRecoilValue } from 'recoil';
import { ChipSize } from 'twenty-ui';
export const ChipFieldDisplay = () => {
@ -11,6 +15,10 @@ export const ChipFieldDisplay = () => {
labelIdentifierLink,
} = useChipFieldDisplay();
const recordIndexOpenRecordIn = useRecoilValue(recordIndexOpenRecordInState);
const { openRecordInCommandMenu } = useCommandMenu();
if (!recordValue) {
return null;
}
@ -20,7 +28,21 @@ export const ChipFieldDisplay = () => {
objectNameSingular={objectNameSingular}
record={recordValue}
size={ChipSize.Small}
to={labelIdentifierLink}
to={
recordIndexOpenRecordIn === ViewOpenRecordInType.RECORD_PAGE
? labelIdentifierLink
: undefined
}
onClick={
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
? () => {
openRecordInCommandMenu({
recordId: recordValue.id,
objectNameSingular,
});
}
: undefined
}
/>
) : (
<RecordChip objectNameSingular={objectNameSingular} record={recordValue} />

View File

@ -11,6 +11,7 @@ export type RecordIdentifierChipProps = {
size?: ChipSize;
to?: string;
maxWidth?: number;
onClick?: () => void;
};
export const RecordIdentifierChip = ({
@ -18,6 +19,7 @@ export const RecordIdentifierChip = ({
record,
variant,
size,
onClick,
to,
maxWidth,
}: RecordIdentifierChipProps) => {
@ -40,6 +42,7 @@ export const RecordIdentifierChip = ({
avatarType={recordChipData.avatarType}
avatarUrl={recordChipData.avatarUrl ?? ''}
to={to}
onClick={onClick}
variant={variant}
LeftIcon={LeftIcon}
LeftIconColor={LeftIconColor}

View File

@ -10,6 +10,7 @@ import { recordIndexFiltersState } from '@/object-record/record-index/states/rec
import { recordIndexIsCompactModeActiveState } from '@/object-record/record-index/states/recordIndexIsCompactModeActiveState';
import { recordIndexKanbanAggregateOperationState } from '@/object-record/record-index/states/recordIndexKanbanAggregateOperationState';
import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState';
import { recordIndexViewFilterGroupsState } from '@/object-record/record-index/states/recordIndexViewFilterGroupsState';
import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState';
@ -48,6 +49,9 @@ export const useLoadRecordIndexStates = () => {
recordIndexIsCompactModeActiveState,
);
const setRecordIndexViewType = useSetRecoilState(recordIndexViewTypeState);
const setRecordIndexOpenRecordIn = useSetRecoilState(
recordIndexOpenRecordInState,
);
const setRecordIndexViewKanbanFieldMetadataIdState = useSetRecoilState(
recordIndexKanbanFieldMetadataIdState,
);
@ -242,6 +246,7 @@ export const useLoadRecordIndexStates = () => {
mapViewSortsToSorts(view.viewSorts, sortDefinitions),
);
setRecordIndexViewType(view.type);
setRecordIndexOpenRecordIn(view.openRecordIn);
setRecordIndexViewKanbanFieldMetadataIdState(
view.kanbanFieldMetadataId,
);
@ -272,6 +277,7 @@ export const useLoadRecordIndexStates = () => {
setRecordIndexViewKanbanAggregateOperationState,
setRecordIndexViewKanbanFieldMetadataIdState,
setRecordIndexViewType,
setRecordIndexOpenRecordIn,
],
);

View File

@ -0,0 +1,8 @@
import { createState } from '@ui/utilities/state/utils/createState';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
export const recordIndexOpenRecordInState = createState<ViewOpenRecordInType>({
key: 'recordIndexOpenRecordInState',
defaultValue: ViewOpenRecordInType.SIDE_PANEL,
});

View File

@ -1,18 +1,19 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { DEFAULT_CELL_SCOPE } from '@/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2';
import { useSelectedTableCellEditMode } from '@/object-record/record-table/record-table-cell/hooks/useSelectedTableCellEditMode';
import { recordTablePendingRecordIdByGroupComponentFamilyState } from '@/object-record/record-table/states/recordTablePendingRecordIdByGroupComponentFamilyState';
import { recordTablePendingRecordIdComponentState } from '@/object-record/record-table/states/recordTablePendingRecordIdComponentState';
import { useRecordTitleCell } from '@/object-record/record-title-cell/hooks/useRecordTitleCell';
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
import { shouldRedirectToShowPageOnCreation } from '@/object-record/utils/shouldRedirectToShowPageOnCreation';
import { AppPath } from '@/types/AppPath';
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared';
@ -62,62 +63,71 @@ export const useCreateNewTableRecord = ({
const { openRecordTitleCell } = useRecordTitleCell();
const createNewTableRecord = async () => {
const recordId = v4();
const createNewTableRecord = useRecoilCallback(
({ snapshot }) =>
async () => {
const recordId = v4();
if (isCommandMenuV2Enabled) {
// TODO: Generalize this behaviour, there will be a view setting to specify
// if the new record should be displayed in the side panel or on the record page
if (shouldRedirectToShowPageOnCreation(objectMetadataItem.nameSingular)) {
await createOneRecord({
id: recordId,
name: 'Untitled',
});
if (isCommandMenuV2Enabled) {
const recordIndexOpenRecordIn = snapshot
.getLoadable(recordIndexOpenRecordInState)
.getValue();
navigate(AppPath.RecordShowPage, {
objectNameSingular: objectMetadataItem.nameSingular,
objectRecordId: recordId,
});
await createOneRecord({ id: recordId });
// TODO: we should open the record title cell here but because
// we are redirecting to the record show page, the hotkey scope will
// be overridden by the hotkey scope on mount. We need to deprecate
// the useHotkeyScopeOnMount hook.
if (recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL) {
openRecordInCommandMenu({
recordId,
objectNameSingular: objectMetadataItem.nameSingular,
isNewRecord: true,
});
return;
}
openRecordTitleCell({
recordId,
fieldMetadataId:
objectMetadataItem.labelIdentifierFieldMetadataId,
});
} else {
navigate(AppPath.RecordShowPage, {
objectNameSingular: objectMetadataItem.nameSingular,
objectRecordId: recordId,
});
}
await createOneRecord({ id: recordId });
return;
}
openRecordInCommandMenu({
recordId,
objectNameSingular: objectMetadataItem.nameSingular,
isNewRecord: true,
});
openRecordTitleCell({
recordId,
fieldMetadataId: objectMetadataItem.labelIdentifierFieldMetadataId,
});
return;
}
setPendingRecordId(recordId);
setSelectedTableCellEditMode(-1, 0);
setHotkeyScope(DEFAULT_CELL_SCOPE.scope, DEFAULT_CELL_SCOPE.customScopes);
if (isDefined(objectMetadataItem.labelIdentifierFieldMetadataId)) {
setActiveDropdownFocusIdAndMemorizePrevious(
getDropdownFocusIdForRecordField(
recordId,
objectMetadataItem.labelIdentifierFieldMetadataId,
'table-cell',
),
);
}
};
setPendingRecordId(recordId);
setSelectedTableCellEditMode(-1, 0);
setHotkeyScope(
DEFAULT_CELL_SCOPE.scope,
DEFAULT_CELL_SCOPE.customScopes,
);
if (isDefined(objectMetadataItem.labelIdentifierFieldMetadataId)) {
setActiveDropdownFocusIdAndMemorizePrevious(
getDropdownFocusIdForRecordField(
recordId,
objectMetadataItem.labelIdentifierFieldMetadataId,
'table-cell',
),
);
}
},
[
createOneRecord,
isCommandMenuV2Enabled,
navigate,
objectMetadataItem.labelIdentifierFieldMetadataId,
objectMetadataItem.nameSingular,
openRecordInCommandMenu,
openRecordTitleCell,
setActiveDropdownFocusIdAndMemorizePrevious,
setHotkeyScope,
setPendingRecordId,
setSelectedTableCellEditMode,
],
);
const createNewTableRecordInGroup = useRecoilCallback(
({ set }) =>
(recordGroupId: string) => {

View File

@ -20,11 +20,14 @@ import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useC
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { isDefined } from 'twenty-shared';
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId';
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
import { useClickOustideListenerStates } from '@/ui/utilities/pointer-event/hooks/useClickOustideListenerStates';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { useNavigate } from 'react-router-dom';
import { IconList } from 'twenty-ui';
import { TableHotkeyScope } from '../../types/TableHotkeyScope';
@ -75,6 +78,8 @@ export const useOpenRecordTableCellV2 = (tableScopeId: string) => {
const { setActiveDropdownFocusIdAndMemorizePrevious } =
useSetActiveDropdownFocusIdAndMemorizePrevious();
const { openRecordInCommandMenu } = useCommandMenu();
const openTableCell = useRecoilCallback(
({ snapshot, set }) =>
({
@ -115,7 +120,20 @@ export const useOpenRecordTableCellV2 = (tableScopeId: string) => {
) {
leaveTableFocus();
navigate(indexIdentifierUrl(recordId));
const openRecordIn = snapshot
.getLoadable(recordIndexOpenRecordInState)
.getValue();
if (openRecordIn === ViewOpenRecordInType.RECORD_PAGE) {
navigate(indexIdentifierUrl(recordId));
}
if (openRecordIn === ViewOpenRecordInType.SIDE_PANEL) {
openRecordInCommandMenu({
recordId,
objectNameSingular,
});
}
return;
}
@ -170,14 +188,15 @@ export const useOpenRecordTableCellV2 = (tableScopeId: string) => {
moveEditModeToTableCellPosition,
initDraftValue,
toggleClickOutsideListener,
setActiveDropdownFocusIdAndMemorizePrevious,
leaveTableFocus,
navigate,
indexIdentifierUrl,
openRecordInCommandMenu,
setViewableRecordId,
setViewableRecordNameSingular,
openRightDrawer,
setHotkeyScope,
setActiveDropdownFocusIdAndMemorizePrevious,
],
);

View File

@ -1,11 +0,0 @@
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const shouldRedirectToShowPageOnCreation = (
objectNameSingular: string,
) => {
if (objectNameSingular === CoreObjectNameSingular.Workflow) {
return true;
}
return false;
};

View File

@ -10,6 +10,7 @@ export const findAllViewsOperationSignatureFactory: RecordGqlOperationSignatureF
createdAt: true,
updatedAt: true,
isCompact: true,
openRecordIn: true,
objectMetadataId: true,
position: true,
type: true,

View File

@ -10,6 +10,7 @@ import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/
import { View } from '@/views/types/View';
import { ViewFilter } from '@/views/types/ViewFilter';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import { act } from 'react';
import { isDefined } from 'twenty-shared';
@ -51,6 +52,7 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
type: ViewType.Table,
key: null,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFields: [],
viewGroups: [],
viewSorts: [],

View File

@ -4,6 +4,7 @@ import { ViewFilter } from '@/views/types/ViewFilter';
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
import { ViewGroup } from '@/views/types/ViewGroup';
import { ViewKey } from '@/views/types/ViewKey';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewSort } from '@/views/types/ViewSort';
import { ViewType } from '@/views/types/ViewType';
@ -20,6 +21,7 @@ export type GraphQLView = {
kanbanAggregateOperationFieldMetadataId?: string | null;
objectMetadataId: string;
isCompact: boolean;
openRecordIn: ViewOpenRecordInType;
viewFields: ViewField[];
viewFilters: ViewFilter[];
viewFilterGroups?: ViewFilterGroup[];

View File

@ -4,6 +4,7 @@ import { ViewFilter } from '@/views/types/ViewFilter';
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
import { ViewGroup } from '@/views/types/ViewGroup';
import { ViewKey } from '@/views/types/ViewKey';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewSort } from '@/views/types/ViewSort';
import { ViewType } from '@/views/types/ViewType';
@ -27,5 +28,6 @@ export type View = {
kanbanAggregateOperationFieldMetadataId: string | null;
position: number;
icon: string;
openRecordIn: ViewOpenRecordInType;
__typename: 'View';
};

View File

@ -0,0 +1,4 @@
export enum ViewOpenRecordInType {
SIDE_PANEL = 'SIDE_PANEL',
RECORD_PAGE = 'RECORD_PAGE',
}

View File

@ -1,3 +1,4 @@
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
@ -16,7 +17,7 @@ import { getWorkflowNodeIconKey } from '@/workflow/workflow-diagram/utils/getWor
import { isCreateStepNode } from '@/workflow/workflow-diagram/utils/isCreateStepNode';
import { useLingui } from '@lingui/react/macro';
import { OnSelectionChangeParams, useOnSelectionChange } from '@xyflow/react';
import { useCallback } from 'react';
import { useCallback, useContext } from 'react';
import { useSetRecoilState } from 'recoil';
import { isDefined } from 'twenty-shared';
import { IconBolt, useIcons } from 'twenty-ui';
@ -37,12 +38,16 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
commandMenuNavigationStackState,
);
const { isInRightDrawer } = useContext(ActionMenuContext);
const handleSelectionChange = useCallback(
({ nodes }: OnSelectionChangeParams) => {
const selectedNode = nodes[0] as WorkflowDiagramNode;
const isClosingStep = isDefined(selectedNode) === false;
setCommandMenuNavigationStack([]);
if (!isInRightDrawer) {
setCommandMenuNavigationStack([]);
}
if (isClosingStep) {
closeRightDrawer();
@ -76,11 +81,12 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
});
},
[
setCommandMenuNavigationStack,
isInRightDrawer,
setWorkflowSelectedNode,
setHotkeyScope,
openRightDrawer,
getIcon,
setCommandMenuNavigationStack,
closeRightDrawer,
closeCommandMenu,
t,

View File

@ -1,6 +1,7 @@
import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations';
import { View } from '@/views/types/View';
import { ViewKey } from '@/views/types/ViewKey';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
@ -29,6 +30,7 @@ export const mockedViewsData: View[] = [
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFilterGroups: [],
viewGroups: [],
viewFields: [],
@ -48,6 +50,7 @@ export const mockedViewsData: View[] = [
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFilterGroups: [],
viewGroups: [],
viewFields: [],
@ -67,6 +70,7 @@ export const mockedViewsData: View[] = [
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFilterGroups: [],
viewGroups: [],
viewFields: [],
@ -86,6 +90,7 @@ export const mockedViewsData: View[] = [
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFilterGroups: [],
viewGroups: [],
viewFields: [],

View File

@ -0,0 +1,128 @@
import { InjectRepository } from '@nestjs/typeorm';
import chalk from 'chalk';
import { Command } from 'nest-commander';
import { In, Repository } from 'typeorm';
import {
ActiveWorkspacesCommandOptions,
ActiveWorkspacesCommandRunner,
} from 'src/database/commands/active-workspaces.command';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewOpenRecordInType } from 'src/modules/view/standard-objects/view.workspace-entity';
@Command({
name: 'upgrade-0.43:update-default-view-record-opening-on-workflow-objects',
description:
'Update default view record opening on workflow objects to record page',
})
export class UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand extends ActiveWorkspacesCommandRunner {
constructor(
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
@InjectRepository(ObjectMetadataEntity, 'metadata')
protected readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
) {
super(workspaceRepository);
}
async executeActiveWorkspacesCommand(
_passedParam: string[],
_options: ActiveWorkspacesCommandOptions,
workspaceIds: string[],
): Promise<void> {
this.logger.log(
'Running command to update default view record opening on workflow objects to record page',
);
for (const [index, workspaceId] of workspaceIds.entries()) {
await this.processWorkspace(workspaceId, index, workspaceIds.length);
}
this.logger.log(chalk.green('Command completed!'));
}
async processWorkspace(
workspaceId: string,
index: number,
total: number,
): Promise<void> {
try {
this.logger.log(
`Running command for workspace ${workspaceId} ${index + 1}/${total}`,
);
const workflowObjectsMetadata = await this.objectMetadataRepository.find({
select: ['id'],
where: {
workspaceId,
standardId: In([
STANDARD_OBJECT_IDS.workflow,
STANDARD_OBJECT_IDS.workflowVersion,
STANDARD_OBJECT_IDS.workflowRun,
]),
},
});
if (workflowObjectsMetadata.length === 0) {
this.logger.log(
chalk.yellow(
`No workflow objects found for workspace ${workspaceId}`,
),
);
return;
}
await this.updateDefaultViewsRecordOpening(
workflowObjectsMetadata.map((metadata) => metadata.id),
workspaceId,
);
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
workspaceId,
);
await this.workspaceMetadataVersionService.incrementMetadataVersion(
workspaceId,
);
this.logger.log(
chalk.green(`Command completed for workspace ${workspaceId}.`),
);
} catch (error) {
this.logger.log(
chalk.red(`Error in workspace ${workspaceId} - ${error.message}`),
);
}
}
private async updateDefaultViewsRecordOpening(
workflowObjectMetadataIds: string[],
workspaceId: string,
): Promise<void> {
const viewRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace(
workspaceId,
'view',
);
await viewRepository.update(
{
objectMetadataId: In(workflowObjectMetadataIds),
key: 'INDEX',
},
{
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
},
);
}
}

View File

@ -7,6 +7,8 @@ import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-work
import { BaseCommandOptions } from 'src/database/commands/base.command';
import { StandardizationOfActorCompositeContextTypeCommand } from 'src/database/commands/upgrade-version/0-42/0-42-standardization-of-actor-composite-context-type';
import { AddTasksAssignedToMeViewCommand } from 'src/database/commands/upgrade-version/0-43/0-43-add-tasks-assigned-to-me-view.command';
import { MigrateSearchVectorOnNoteAndTaskEntitiesCommand } from 'src/database/commands/upgrade-version/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command';
import { UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand } from 'src/database/commands/upgrade-version/0-43/0-43-update-default-view-record-opening-on-workflow-objects.command';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Command({
@ -18,6 +20,8 @@ export class UpgradeTo0_43Command extends ActiveWorkspacesCommandRunner {
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
private readonly addTasksAssignedToMeViewCommand: AddTasksAssignedToMeViewCommand,
private readonly migrateSearchVectorOnNoteAndTaskEntitiesCommand: MigrateSearchVectorOnNoteAndTaskEntitiesCommand,
private readonly updateDefaultViewRecordOpeningOnWorkflowObjectsCommand: UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand,
private readonly standardizationOfActorCompositeContextTypeCommand: StandardizationOfActorCompositeContextTypeCommand,
) {
super(workspaceRepository);
@ -36,6 +40,18 @@ export class UpgradeTo0_43Command extends ActiveWorkspacesCommandRunner {
workspaceIds,
);
await this.migrateSearchVectorOnNoteAndTaskEntitiesCommand.executeActiveWorkspacesCommand(
passedParam,
options,
workspaceIds,
);
await this.updateDefaultViewRecordOpeningOnWorkflowObjectsCommand.executeActiveWorkspacesCommand(
passedParam,
options,
workspaceIds,
);
// Note: Introduced in 0.42, ran manually on prod. Introduced to self-host globally on 0.43
await this.standardizationOfActorCompositeContextTypeCommand.executeActiveWorkspacesCommand(
passedParam,

View File

@ -4,6 +4,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { StandardizationOfActorCompositeContextTypeCommand } from 'src/database/commands/upgrade-version/0-42/0-42-standardization-of-actor-composite-context-type';
import { AddTasksAssignedToMeViewCommand } from 'src/database/commands/upgrade-version/0-43/0-43-add-tasks-assigned-to-me-view.command';
import { MigrateSearchVectorOnNoteAndTaskEntitiesCommand } from 'src/database/commands/upgrade-version/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command';
import { UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand } from 'src/database/commands/upgrade-version/0-43/0-43-update-default-view-record-opening-on-workflow-objects.command';
import { UpgradeTo0_43Command } from 'src/database/commands/upgrade-version/0-43/0-43-upgrade-version.command';
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@ -30,6 +31,7 @@ import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/wor
UpgradeTo0_43Command,
AddTasksAssignedToMeViewCommand,
MigrateSearchVectorOnNoteAndTaskEntitiesCommand,
UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand,
StandardizationOfActorCompositeContextTypeCommand,
],
})

View File

@ -586,6 +586,10 @@ msgstr "Rigting"
msgid "Display Name"
msgstr "Wys Naam"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Vertoon Waarde"
@ -1327,6 +1331,10 @@ msgstr "Objek Metadata Id"
msgid "Object name"
msgstr "Objek naam"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operant"

View File

@ -586,6 +586,10 @@ msgstr "الاتجاه"
msgid "Display Name"
msgstr "اسم العرض"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "قيمة العرض"
@ -1327,6 +1331,10 @@ msgstr "معرف بيانات الكائن"
msgid "Object name"
msgstr "اسم الكائن"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "العملية"
@ -1584,7 +1592,9 @@ msgstr "مؤشر التزامن"
#: src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts
msgid "Sync Cursor. Used for syncing events from the calendar provider"
msgstr "\n"
msgstr ""
"\n"
""
#: src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts
#: src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts

View File

@ -586,6 +586,10 @@ msgstr "Direcció"
msgid "Display Name"
msgstr "Nom Visible"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Valor Visible"
@ -1327,6 +1331,10 @@ msgstr "Id de Metadades de l'Objecte"
msgid "Object name"
msgstr "Nom de l'objecte"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operador"

View File

@ -586,6 +586,10 @@ msgstr "Směr"
msgid "Display Name"
msgstr "Zobrazovaný název"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Zobrazovaná hodnota"
@ -1327,6 +1331,10 @@ msgstr "ID metadat objektu"
msgid "Object name"
msgstr "Název objektu"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operand"

View File

@ -586,6 +586,10 @@ msgstr "Retning"
msgid "Display Name"
msgstr "Visningsnavn"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Visningsværdi"
@ -1327,6 +1331,10 @@ msgstr "Objekt Metadata-id"
msgid "Object name"
msgstr "Objektnavn"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operand"
@ -1540,7 +1548,8 @@ msgstr "Køringer"
#: src/modules/connected-account/standard-objects/connected-account.workspace-entity.ts
#: src/modules/connected-account/standard-objects/connected-account.workspace-entity.ts
msgid "Scopes"
msgstr "R\n"
msgstr ""
"R\n"
"ettigheder"
#: src/engine/metadata-modules/constants/search-vector-field.constants.ts

View File

@ -586,6 +586,10 @@ msgstr "Richtung"
msgid "Display Name"
msgstr "Anzeigename"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Anzeigewert"
@ -1327,6 +1331,10 @@ msgstr "Objekt-Metadaten-ID"
msgid "Object name"
msgstr "Objektname"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operand"

View File

@ -586,6 +586,10 @@ msgstr "Κατεύθυνση"
msgid "Display Name"
msgstr "Εμφανιζόμενο Όνομα"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Εμφανιζόμενη Αξία"
@ -1327,6 +1331,10 @@ msgstr "Αναγνωριστικό Μετα-δεδομένων Αντικειμ
msgid "Object name"
msgstr "Όνομα αντικειμένου"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Οπεράνδος"

View File

@ -581,6 +581,10 @@ msgstr "Direction"
msgid "Display Name"
msgstr "Display Name"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr "Display the records in a side panel or in a record page"
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Display Value"
@ -1322,6 +1326,10 @@ msgstr "Object Metadata Id"
msgid "Object name"
msgstr "Object name"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr "Open Record In"
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operand"

View File

@ -586,6 +586,10 @@ msgstr "Dirección"
msgid "Display Name"
msgstr "Nombre para mostrar"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Valor para mostrar"
@ -1327,6 +1331,10 @@ msgstr "ID de metadatos del objeto"
msgid "Object name"
msgstr "Nombre del objeto"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operando"

View File

@ -586,6 +586,10 @@ msgstr "Suunta"
msgid "Display Name"
msgstr "Näyttönimi"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Näyttöarvo"
@ -1327,6 +1331,10 @@ msgstr "Kohdemetadatatunniste"
msgid "Object name"
msgstr "Kohteen nimi"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operaattori"

View File

@ -586,6 +586,10 @@ msgstr "Direction"
msgid "Display Name"
msgstr "Nom d'affichage"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Valeur affichée"
@ -1327,6 +1331,10 @@ msgstr "ID des métadonnées de l'objet"
msgid "Object name"
msgstr "Nom de l'objet"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Opérande"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -586,6 +586,10 @@ msgstr "כיוון"
msgid "Display Name"
msgstr "שם תצוגה"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "ערך תצוגה"
@ -1327,6 +1331,10 @@ msgstr "מזהה מטא-נתונים של אובייקט"
msgid "Object name"
msgstr "שם האובייקט"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "אופרנד"

View File

@ -586,6 +586,10 @@ msgstr "Irány"
msgid "Display Name"
msgstr "Megjelenítendő név"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Megjelenítési érték"
@ -1327,6 +1331,10 @@ msgstr "Objektum Metaadat Azonosító"
msgid "Object name"
msgstr "Objektum neve"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operándus"

View File

@ -586,6 +586,10 @@ msgstr "Direzione"
msgid "Display Name"
msgstr "Nome visualizzato"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Valore visualizzato"
@ -1327,6 +1331,10 @@ msgstr "ID metadati dell'oggetto"
msgid "Object name"
msgstr "Nome oggetto"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operando"

View File

@ -586,6 +586,10 @@ msgstr "方向"
msgid "Display Name"
msgstr "表示名"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "表示値"
@ -1327,6 +1331,10 @@ msgstr "オブジェクトメタデータID"
msgid "Object name"
msgstr "オブジェクト名"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "オペランド"

View File

@ -586,6 +586,10 @@ msgstr "방향"
msgid "Display Name"
msgstr "표시 이름"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "표시 값"
@ -1327,6 +1331,10 @@ msgstr "객체 메타데이터 ID"
msgid "Object name"
msgstr "객체 이름"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "피연산자"

View File

@ -586,6 +586,10 @@ msgstr "Richting"
msgid "Display Name"
msgstr "Weergavenaam"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Weergavewaarde"
@ -1327,6 +1331,10 @@ msgstr "Object Metadata-ID"
msgid "Object name"
msgstr "Object naam"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operand"

View File

@ -586,6 +586,10 @@ msgstr "Retning"
msgid "Display Name"
msgstr "Visningsnavn"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Visningsverdi"
@ -1327,6 +1331,10 @@ msgstr "Objekt Metadata-id"
msgid "Object name"
msgstr "Objektnavn"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operant"

View File

@ -586,6 +586,10 @@ msgstr "Kierunek"
msgid "Display Name"
msgstr "Nazwa wyświetlana"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Wartość wyświetlana"
@ -1327,6 +1331,10 @@ msgstr "Identyfikator metadanych obiektu"
msgid "Object name"
msgstr "Nazwa obiektu"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Składnik"

View File

@ -581,6 +581,10 @@ msgstr ""
msgid "Display Name"
msgstr ""
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr ""
@ -1322,6 +1326,10 @@ msgstr ""
msgid "Object name"
msgstr ""
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr ""

View File

@ -586,6 +586,10 @@ msgstr "Direção"
msgid "Display Name"
msgstr "Nome de Exibição"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Valor de Exibição"
@ -1327,6 +1331,10 @@ msgstr "ID de Metadados do Objeto"
msgid "Object name"
msgstr "Nome do Objeto"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operando"

View File

@ -586,6 +586,10 @@ msgstr "Direção"
msgid "Display Name"
msgstr "Nome de Exibição"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Valor de Exibição"
@ -1327,6 +1331,10 @@ msgstr "ID de Metadados do Objeto"
msgid "Object name"
msgstr "Nome do Objeto"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operando"

View File

@ -586,6 +586,10 @@ msgstr "Direcție"
msgid "Display Name"
msgstr "Nume afișat"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Valoare afișată"
@ -1327,6 +1331,10 @@ msgstr "Id-ul Metadatelor Obiectului"
msgid "Object name"
msgstr "Numele obiectului"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operand"

View File

@ -586,6 +586,10 @@ msgstr "Направление"
msgid "Display Name"
msgstr "Отображаемое имя"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Отображаемое значение"
@ -1327,6 +1331,10 @@ msgstr "Идентификатор метаданных объекта"
msgid "Object name"
msgstr "Имя объекта"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Операнд"

View File

@ -586,6 +586,10 @@ msgstr "Смер"
msgid "Display Name"
msgstr "Приказно име"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Приказна вредност"
@ -1327,6 +1331,10 @@ msgstr "Идентификатор метаподатака објекта"
msgid "Object name"
msgstr "Назив објекта"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Операнд"

View File

@ -586,6 +586,10 @@ msgstr "Riktning"
msgid "Display Name"
msgstr "Visningsnamn"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Visningsvärde"
@ -1327,6 +1331,10 @@ msgstr "Objektmetadata-id"
msgid "Object name"
msgstr "Objektnamn"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Operand"
@ -1481,7 +1489,8 @@ msgstr "F\"or\"aldrade f\"argschema"
#: src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts
msgid "Preferred language"
msgstr "F\"or\"aldrat spr\n"
msgstr ""
"F\"or\"aldrat spr\n"
"k"
#: src/modules/opportunity/standard-objects/opportunity.workspace-entity.ts
@ -1585,7 +1594,8 @@ msgstr "Synkkurs"
#: src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts
msgid "Sync Cursor. Used for syncing events from the calendar provider"
msgstr "Synkkurs. Anv\"ands f\"or att synkronisera h\"andelser fr\n"
msgstr ""
"Synkkurs. Anv\"ands f\"or att synkronisera h\"andelser fr\n"
"n kalenderleverant\"oren"
#: src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts

View File

@ -586,6 +586,10 @@ msgstr "Yön"
msgid "Display Name"
msgstr "Görünen Ad"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Görüntü Değeri"
@ -1327,6 +1331,10 @@ msgstr "Nesne Metaveri Kimliği"
msgid "Object name"
msgstr "Nesne adı"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "İşlenen"

View File

@ -586,6 +586,10 @@ msgstr "Напрямок"
msgid "Display Name"
msgstr "Назва для відображення"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Значення для відображення"
@ -1327,6 +1331,10 @@ msgstr "ID метаданих об'єкту"
msgid "Object name"
msgstr "Назва об'єкта"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Операнд"

View File

@ -586,6 +586,10 @@ msgstr "Hướng"
msgid "Display Name"
msgstr "Tên hiển thị"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "Giá trị hiển thị"
@ -1327,6 +1331,10 @@ msgstr "Mã Id Metadata Đối Tượng"
msgid "Object name"
msgstr "Tên đối tượng"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "Toán hạng"

View File

@ -586,6 +586,10 @@ msgstr "方向"
msgid "Display Name"
msgstr "显示名称"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "显示值"
@ -1327,6 +1331,10 @@ msgstr "对象元数据 ID"
msgid "Object name"
msgstr "对象名称"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "操作数"

View File

@ -586,6 +586,10 @@ msgstr "方向"
msgid "Display Name"
msgstr "顯示名稱"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Display the records in a side panel or in a record page"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Display Value"
msgstr "顯示值"
@ -1327,6 +1331,10 @@ msgstr "對象元數據 ID"
msgid "Object name"
msgstr "對象名稱"
#: src/modules/view/standard-objects/view.workspace-entity.ts
msgid "Open Record In"
msgstr ""
#: src/modules/view/standard-objects/view-filter.workspace-entity.ts
msgid "Operand"
msgstr "操作數"

View File

@ -24,6 +24,7 @@ export const createWorkspaceViews = async (
'key',
'position',
'icon',
'openRecordIn',
'kanbanFieldMetadataId',
'kanbanAggregateOperation',
'kanbanAggregateOperationFieldMetadataId',
@ -38,6 +39,7 @@ export const createWorkspaceViews = async (
key,
position,
icon,
openRecordIn,
kanbanFieldMetadataId,
kanbanAggregateOperation,
kanbanAggregateOperationFieldMetadataId,
@ -49,6 +51,7 @@ export const createWorkspaceViews = async (
key,
position,
icon,
openRecordIn,
kanbanFieldMetadataId,
kanbanAggregateOperation,
kanbanAggregateOperationFieldMetadataId,

View File

@ -1,4 +1,5 @@
import { AGGREGATE_OPERATIONS } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { ViewOpenRecordInType } from 'src/modules/view/standard-objects/view.workspace-entity';
export interface ViewDefinition {
id?: string;
@ -8,6 +9,7 @@ export interface ViewDefinition {
key: string | null;
position: number;
icon?: string;
openRecordIn?: ViewOpenRecordInType;
kanbanFieldMetadataId?: string;
kanbanAggregateOperation?: AGGREGATE_OPERATIONS;
kanbanAggregateOperationFieldMetadataId?: string;

View File

@ -2,6 +2,7 @@ import { ObjectMetadataStandardIdToIdMap } from 'src/engine/metadata-modules/obj
import { WORKFLOW_RUN_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewOpenRecordInType } from 'src/modules/view/standard-objects/view.workspace-entity';
export const workflowRunsAllView = (
objectMetadataStandardIdToIdMap: ObjectMetadataStandardIdToIdMap,
@ -14,6 +15,7 @@ export const workflowRunsAllView = (
key: 'INDEX',
position: 0,
icon: 'IconHistory',
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
kanbanFieldMetadataId: '',
filters: [],
fields: [

View File

@ -5,6 +5,7 @@ import {
WORKFLOW_VERSION_STANDARD_FIELD_IDS,
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewOpenRecordInType } from 'src/modules/view/standard-objects/view.workspace-entity';
export const workflowVersionsAllView = (
objectMetadataStandardIdToIdMap: ObjectMetadataStandardIdToIdMap,
@ -17,6 +18,7 @@ export const workflowVersionsAllView = (
key: 'INDEX',
position: 0,
icon: 'IconVersions',
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
kanbanFieldMetadataId: '',
filters: [],
fields: [

View File

@ -5,6 +5,7 @@ import {
WORKFLOW_STANDARD_FIELD_IDS,
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewOpenRecordInType } from 'src/modules/view/standard-objects/view.workspace-entity';
export const workflowsAllView = (
objectMetadataStandardIdToIdMap: ObjectMetadataStandardIdToIdMap,
@ -17,6 +18,7 @@ export const workflowsAllView = (
key: 'INDEX',
position: 0,
icon: 'IconSettingsAutomation',
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
kanbanFieldMetadataId: '',
filters: [],
fields: [

View File

@ -435,6 +435,7 @@ export const VIEW_STANDARD_FIELD_IDS = {
'20202020-b1b3-4bf3-85e4-dc7d58aa9b02',
position: '20202020-e9db-4303-b271-e8250c450172',
isCompact: '20202020-674e-4314-994d-05754ea7b22b',
openRecordIn: '20202020-086d-4eef-9f03-56c6392eacb8',
viewFields: '20202020-542b-4bdc-b177-b63175d48edf',
viewGroups: '20202020-e1a1-419f-ac81-1986a5ea59a8',
viewFilters: '20202020-ff23-4154-b63c-21fb36cd0967',

View File

@ -1,3 +1,5 @@
import { registerEnumType } from '@nestjs/graphql';
import { msg } from '@lingui/core/macro';
import { FieldMetadataType } from 'twenty-shared';
@ -25,6 +27,15 @@ import { ViewFilterWorkspaceEntity } from 'src/modules/view/standard-objects/vie
import { ViewGroupWorkspaceEntity } from 'src/modules/view/standard-objects/view-group.workspace-entity';
import { ViewSortWorkspaceEntity } from 'src/modules/view/standard-objects/view-sort.workspace-entity';
export enum ViewOpenRecordInType {
SIDE_PANEL = 'SIDE_PANEL',
RECORD_PAGE = 'RECORD_PAGE',
}
registerEnumType(ViewOpenRecordInType, {
name: 'ViewOpenRecordInType',
});
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.view,
namePlural: 'views',
@ -111,6 +122,29 @@ export class ViewWorkspaceEntity extends BaseWorkspaceEntity {
})
isCompact: boolean;
@WorkspaceField({
standardId: VIEW_STANDARD_FIELD_IDS.openRecordIn,
type: FieldMetadataType.SELECT,
label: msg`Open Record In`,
description: msg`Display the records in a side panel or in a record page`,
defaultValue: `'${ViewOpenRecordInType.SIDE_PANEL}'`,
options: [
{
value: ViewOpenRecordInType.SIDE_PANEL,
label: 'Side Panel',
position: 0,
color: 'green',
},
{
value: ViewOpenRecordInType.RECORD_PAGE,
label: 'Record Page',
position: 1,
color: 'blue',
},
],
})
openRecordIn: ViewOpenRecordInType;
@WorkspaceRelation({
standardId: VIEW_STANDARD_FIELD_IDS.viewFields,
type: RelationMetadataType.ONE_TO_MANY,

Some files were not shown because too many files have changed in this diff Show More