Introduce primary actions (#15826)
- These actions are displayed in the accent color - Added new context store state `contextStoreIsPageInEditModeComponentState` - Reverted the order in which the actions are displayed (the first action should appear to the right of the top bar action menu) https://github.com/user-attachments/assets/3a0769cf-61ed-4619-8c4d-e3a01765b63c
This commit is contained in:
+4
-2
@@ -24,6 +24,8 @@ export const ActionButton = ({
|
||||
? getActionLabel(action.shortLabel)
|
||||
: undefined;
|
||||
|
||||
const buttonAccent = action.isPrimaryCTA ? 'blue' : 'default';
|
||||
|
||||
return (
|
||||
<>
|
||||
{action.shortLabel ? (
|
||||
@@ -31,7 +33,7 @@ export const ActionButton = ({
|
||||
Icon={action.Icon}
|
||||
size="small"
|
||||
variant="secondary"
|
||||
accent="default"
|
||||
accent={buttonAccent}
|
||||
to={to}
|
||||
onClick={onClick}
|
||||
title={shortLabel}
|
||||
@@ -43,7 +45,7 @@ export const ActionButton = ({
|
||||
Icon={action.Icon}
|
||||
size="small"
|
||||
variant="secondary"
|
||||
accent="default"
|
||||
accent={buttonAccent}
|
||||
to={to}
|
||||
onClick={onClick}
|
||||
ariaLabel={label}
|
||||
|
||||
+1
@@ -15,6 +15,7 @@ export type ActionDisplayProps = {
|
||||
shortLabel?: MessageDescriptor | string;
|
||||
description?: MessageDescriptor | string;
|
||||
Icon: IconComponent;
|
||||
isPrimaryCTA?: boolean;
|
||||
accent?: MenuItemAccent;
|
||||
hotKeys?: string[];
|
||||
};
|
||||
|
||||
+53
-73
@@ -1,5 +1,4 @@
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { AddToFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/components/AddToFavoritesSingleRecordAction';
|
||||
import { CancelDashboardSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/dashboard-actions/components/CancelDashboardSingleRecordAction';
|
||||
import { EditDashboardSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/dashboard-actions/components/EditDashboardSingleRecordAction';
|
||||
import { SaveDashboardSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/dashboard-actions/components/SaveDashboardSingleRecordAction';
|
||||
@@ -11,37 +10,16 @@ import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import { PageLayoutSingleRecordActionKeys } from '@/page-layout/actions/PageLayoutSingleRecordActionKeys';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconDeviceFloppy,
|
||||
IconHeart,
|
||||
IconPencil,
|
||||
IconX,
|
||||
} from 'twenty-ui/display';
|
||||
import { IconDeviceFloppy, IconPencil, IconX } from 'twenty-ui/display';
|
||||
|
||||
export const DASHBOARD_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
config: {
|
||||
[PageLayoutSingleRecordActionKeys.ADD_TO_FAVORITES_READ_MODE]: {
|
||||
key: PageLayoutSingleRecordActionKeys.ADD_TO_FAVORITES_READ_MODE,
|
||||
label: msg`Add to favorites`,
|
||||
shortLabel: msg`Add to favorites`,
|
||||
isPinned: true,
|
||||
position: 0,
|
||||
Icon: IconHeart,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) &&
|
||||
!selectedRecord?.isRemote &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <AddToFavoritesSingleRecordAction />,
|
||||
},
|
||||
[PageLayoutSingleRecordActionKeys.EDIT_LAYOUT]: {
|
||||
key: PageLayoutSingleRecordActionKeys.EDIT_LAYOUT,
|
||||
label: msg`Edit Dashboard`,
|
||||
shortLabel: msg`Edit`,
|
||||
isPinned: true,
|
||||
position: 1,
|
||||
position: 3,
|
||||
Icon: IconPencil,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -53,29 +31,13 @@ export const DASHBOARD_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <EditDashboardSingleRecordAction />,
|
||||
},
|
||||
[PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION]: {
|
||||
key: PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION,
|
||||
label: msg`Cancel Edition`,
|
||||
shortLabel: msg`Cancel`,
|
||||
isPinned: true,
|
||||
position: 0,
|
||||
Icon: IconX,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) &&
|
||||
!selectedRecord?.isRemote &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
isDefined(selectedRecord?.pageLayoutId),
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <CancelDashboardSingleRecordAction />,
|
||||
},
|
||||
[PageLayoutSingleRecordActionKeys.SAVE_LAYOUT]: {
|
||||
key: PageLayoutSingleRecordActionKeys.SAVE_LAYOUT,
|
||||
label: msg`Save Dashboard`,
|
||||
shortLabel: msg`Save`,
|
||||
isPinned: true,
|
||||
position: 1,
|
||||
isPrimaryCTA: true,
|
||||
position: 4,
|
||||
Icon: IconDeviceFloppy,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -84,9 +46,26 @@ export const DASHBOARD_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
!selectedRecord?.isRemote &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
isDefined(selectedRecord?.pageLayoutId),
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
availableOn: [ActionViewType.PAGE_EDIT_MODE],
|
||||
component: <SaveDashboardSingleRecordAction />,
|
||||
},
|
||||
[PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION]: {
|
||||
key: PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION,
|
||||
label: msg`Cancel Edition`,
|
||||
shortLabel: msg`Cancel`,
|
||||
isPinned: true,
|
||||
position: 5,
|
||||
Icon: IconX,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) &&
|
||||
!selectedRecord?.isRemote &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
isDefined(selectedRecord?.pageLayoutId),
|
||||
availableOn: [ActionViewType.PAGE_EDIT_MODE],
|
||||
component: <CancelDashboardSingleRecordAction />,
|
||||
},
|
||||
},
|
||||
actionKeys: [
|
||||
NoSelectionRecordActionKeys.CREATE_NEW_RECORD,
|
||||
@@ -107,61 +86,62 @@ export const DASHBOARD_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
NoSelectionRecordActionKeys.GO_TO_NOTES,
|
||||
],
|
||||
propertiesToOverwrite: {
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_RECORD]: {
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
position: 0,
|
||||
label: msg`Navigate to next dashboard`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
position: 1,
|
||||
label: msg`Navigate to previous dashboard`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_RECORD]: {
|
||||
position: 2,
|
||||
label: msg`Create new dashboard`,
|
||||
},
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
position: 3,
|
||||
isPinned: false,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
position: 4,
|
||||
},
|
||||
[SingleRecordActionKeys.DELETE]: {
|
||||
position: 2,
|
||||
position: 6,
|
||||
label: msg`Delete dashboard`,
|
||||
},
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
position: 7,
|
||||
isPinned: true,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
position: 8,
|
||||
isPinned: true,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: {
|
||||
position: 5,
|
||||
position: 9,
|
||||
label: msg`Export dashboard`,
|
||||
},
|
||||
[SingleRecordActionKeys.DESTROY]: {
|
||||
position: 6,
|
||||
position: 10,
|
||||
label: msg`Permanently destroy dashboard`,
|
||||
},
|
||||
[SingleRecordActionKeys.RESTORE]: {
|
||||
position: 7,
|
||||
position: 11,
|
||||
label: msg`Restore dashboard`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
position: 8,
|
||||
label: msg`Navigate to previous dashboard`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
position: 9,
|
||||
label: msg`Navigate to next dashboard`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_WORKFLOWS]: {
|
||||
position: 10,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_PEOPLE]: {
|
||||
position: 11,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 12,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_PEOPLE]: {
|
||||
position: 13,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 14,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
position: 15,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_NOTES]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
position: 16,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
position: 17,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_NOTES]: {
|
||||
position: 18,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
+302
-295
@@ -65,13 +65,37 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
| MultipleRecordsActionKeys,
|
||||
ActionConfig
|
||||
> = {
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
label: msg`Navigate to next record`,
|
||||
position: 0,
|
||||
isPinned: true,
|
||||
Icon: IconChevronDown,
|
||||
shouldBeRegistered: ({ isInRightDrawer }) => !isInRightDrawer,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <NavigateToNextRecordSingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
label: msg`Navigate to previous record`,
|
||||
position: 1,
|
||||
isPinned: true,
|
||||
Icon: IconChevronUp,
|
||||
shouldBeRegistered: ({ isInRightDrawer }) => !isInRightDrawer,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <NavigateToPreviousRecordSingleRecordAction />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_RECORD]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.CREATE_NEW_RECORD,
|
||||
label: msg`Create new record`,
|
||||
shortLabel: msg`New record`,
|
||||
position: 0,
|
||||
position: 2,
|
||||
isPinned: true,
|
||||
Icon: IconPlus,
|
||||
shouldBeRegistered: ({ objectPermissions, hasAnySoftDeleteFilterOnView }) =>
|
||||
@@ -81,180 +105,13 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <CreateNewTableRecordNoSelectionRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_NOTE_TO_PDF]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT_NOTE_TO_PDF,
|
||||
label: msg`Export to PDF`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 1,
|
||||
isPinned: false,
|
||||
Icon: IconFileExport,
|
||||
shouldBeRegistered: ({ selectedRecord, isNoteOrTask }) =>
|
||||
isDefined(isNoteOrTask) &&
|
||||
isNoteOrTask &&
|
||||
isNonEmptyString(selectedRecord?.bodyV2?.blocknote),
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <ExportNoteActionSingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
label: msg`Add to favorites`,
|
||||
shortLabel: msg`Add to favorites`,
|
||||
position: 2,
|
||||
isPinned: true,
|
||||
Icon: IconHeart,
|
||||
shouldBeRegistered: ({
|
||||
selectedRecord,
|
||||
isFavorite,
|
||||
hasAnySoftDeleteFilterOnView,
|
||||
}) =>
|
||||
!selectedRecord?.isRemote &&
|
||||
!isFavorite &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
component: <AddToFavoritesSingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
label: msg`Remove from favorites`,
|
||||
shortLabel: msg`Remove from favorites`,
|
||||
isPinned: true,
|
||||
position: 3,
|
||||
Icon: IconHeartOff,
|
||||
shouldBeRegistered: ({
|
||||
selectedRecord,
|
||||
isFavorite,
|
||||
hasAnySoftDeleteFilterOnView,
|
||||
}) =>
|
||||
isDefined(selectedRecord) &&
|
||||
!selectedRecord?.isRemote &&
|
||||
isDefined(isFavorite) &&
|
||||
isFavorite &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
component: <RemoveFromFavoritesSingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX,
|
||||
label: msg`Export`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 4,
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && !selectedRecord.isRemote,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION],
|
||||
component: <ExportMultipleRecordsAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW,
|
||||
label: msg`Export`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 4,
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && !selectedRecord.isRemote,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <ExportSingleRecordAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
|
||||
},
|
||||
[MultipleRecordsActionKeys.MERGE]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.MERGE,
|
||||
label: msg`Merge records`,
|
||||
shortLabel: msg`Merge`,
|
||||
position: 5,
|
||||
Icon: IconArrowMerge,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({
|
||||
objectMetadataItem,
|
||||
numberOfSelectedRecords,
|
||||
objectPermissions,
|
||||
}) =>
|
||||
isDefined(objectMetadataItem?.duplicateCriteria) &&
|
||||
isDefined(numberOfSelectedRecords) &&
|
||||
Boolean(objectPermissions.canUpdateObjectRecords) &&
|
||||
Boolean(objectPermissions.canDestroyObjectRecords) &&
|
||||
numberOfSelectedRecords <= MUTATION_MAX_MERGE_RECORDS,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
component: <MergeMultipleRecordsAction />,
|
||||
},
|
||||
[MultipleRecordsActionKeys.EXPORT]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.EXPORT,
|
||||
label: msg`Export records`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 6,
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
component: <ExportMultipleRecordsAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.IMPORT_RECORDS]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.IMPORT_RECORDS,
|
||||
label: msg`Import records`,
|
||||
shortLabel: msg`Import`,
|
||||
position: 7,
|
||||
Icon: IconFileImport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ hasAnySoftDeleteFilterOnView }) =>
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <ImportRecordsNoSelectionRecordAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.IMPORT_CSV,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.EXPORT_VIEW]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.EXPORT_VIEW,
|
||||
label: msg`Export view`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 8,
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <ExportMultipleRecordsAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
|
||||
},
|
||||
[SingleRecordActionKeys.DELETE]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.DELETE,
|
||||
label: msg`Delete`,
|
||||
shortLabel: msg`Delete`,
|
||||
position: 9,
|
||||
position: 3,
|
||||
Icon: IconTrash,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
@@ -281,7 +138,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: MultipleRecordsActionKeys.DELETE,
|
||||
label: msg`Delete records`,
|
||||
shortLabel: msg`Delete`,
|
||||
position: 10,
|
||||
position: 4,
|
||||
Icon: IconTrash,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
@@ -300,129 +157,13 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
component: <DeleteMultipleRecordsAction />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.SEE_DELETED_RECORDS]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
label: msg`See deleted records`,
|
||||
shortLabel: msg`Deleted records`,
|
||||
position: 11,
|
||||
Icon: IconRotate2,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ hasAnySoftDeleteFilterOnView }) =>
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <SeeDeletedRecordsNoSelectionRecordAction />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_VIEW]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.CREATE_NEW_VIEW,
|
||||
label: msg`Create View`,
|
||||
shortLabel: msg`Create View`,
|
||||
position: 12,
|
||||
Icon: IconLayout,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ hasAnySoftDeleteFilterOnView }) =>
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <CreateNewViewNoSelectionRecord />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
label: msg`Hide deleted records`,
|
||||
shortLabel: msg`Hide deleted`,
|
||||
position: 13,
|
||||
Icon: IconEyeOff,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ hasAnySoftDeleteFilterOnView }) =>
|
||||
isDefined(hasAnySoftDeleteFilterOnView) && hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <HideDeletedRecordsNoSelectionRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.DESTROY]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.DESTROY,
|
||||
label: msg`Permanently destroy record`,
|
||||
shortLabel: msg`Destroy`,
|
||||
position: 14,
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({ selectedRecord, objectPermissions, isRemote }) =>
|
||||
(objectPermissions.canDestroyObjectRecords &&
|
||||
!isRemote &&
|
||||
isDefined(selectedRecord?.deletedAt)) ??
|
||||
false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
component: <DestroySingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
label: msg`Navigate to previous record`,
|
||||
position: 15,
|
||||
isPinned: true,
|
||||
Icon: IconChevronUp,
|
||||
shouldBeRegistered: ({ isInRightDrawer }) => !isInRightDrawer,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <NavigateToPreviousRecordSingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
label: msg`Navigate to next record`,
|
||||
position: 16,
|
||||
isPinned: true,
|
||||
Icon: IconChevronDown,
|
||||
shouldBeRegistered: ({ isInRightDrawer }) => !isInRightDrawer,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <NavigateToNextRecordSingleRecordAction />,
|
||||
},
|
||||
[MultipleRecordsActionKeys.DESTROY]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.DESTROY,
|
||||
label: msg`Permanently destroy records`,
|
||||
shortLabel: msg`Destroy`,
|
||||
position: 17,
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({
|
||||
objectPermissions,
|
||||
isRemote,
|
||||
hasAnySoftDeleteFilterOnView,
|
||||
numberOfSelectedRecords,
|
||||
}) =>
|
||||
(objectPermissions.canDestroyObjectRecords &&
|
||||
!isRemote &&
|
||||
isDefined(hasAnySoftDeleteFilterOnView) &&
|
||||
hasAnySoftDeleteFilterOnView &&
|
||||
isDefined(numberOfSelectedRecords) &&
|
||||
numberOfSelectedRecords < BACKEND_BATCH_REQUEST_MAX_COUNT) ??
|
||||
false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
component: <DestroyMultipleRecordsAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.RESTORE]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.RESTORE,
|
||||
label: msg`Restore record`,
|
||||
shortLabel: msg`Restore`,
|
||||
position: 18,
|
||||
position: 5,
|
||||
Icon: IconRefresh,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
@@ -452,7 +193,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: MultipleRecordsActionKeys.RESTORE,
|
||||
label: msg`Restore records`,
|
||||
shortLabel: msg`Restore`,
|
||||
position: 19,
|
||||
position: 6,
|
||||
Icon: IconRefresh,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
@@ -472,13 +213,273 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
component: <RestoreMultipleRecordsAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.DESTROY]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.DESTROY,
|
||||
label: msg`Permanently destroy record`,
|
||||
shortLabel: msg`Destroy`,
|
||||
position: 7,
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({ selectedRecord, objectPermissions, isRemote }) =>
|
||||
(objectPermissions.canDestroyObjectRecords &&
|
||||
!isRemote &&
|
||||
isDefined(selectedRecord?.deletedAt)) ??
|
||||
false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
component: <DestroySingleRecordAction />,
|
||||
},
|
||||
[MultipleRecordsActionKeys.DESTROY]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.DESTROY,
|
||||
label: msg`Permanently destroy records`,
|
||||
shortLabel: msg`Destroy`,
|
||||
position: 8,
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({
|
||||
objectPermissions,
|
||||
isRemote,
|
||||
hasAnySoftDeleteFilterOnView,
|
||||
numberOfSelectedRecords,
|
||||
}) =>
|
||||
(objectPermissions.canDestroyObjectRecords &&
|
||||
!isRemote &&
|
||||
isDefined(hasAnySoftDeleteFilterOnView) &&
|
||||
hasAnySoftDeleteFilterOnView &&
|
||||
isDefined(numberOfSelectedRecords) &&
|
||||
numberOfSelectedRecords < BACKEND_BATCH_REQUEST_MAX_COUNT) ??
|
||||
false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
component: <DestroyMultipleRecordsAction />,
|
||||
},
|
||||
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
label: msg`Add to favorites`,
|
||||
shortLabel: msg`Add to favorites`,
|
||||
position: 9,
|
||||
isPinned: true,
|
||||
Icon: IconHeart,
|
||||
shouldBeRegistered: ({
|
||||
selectedRecord,
|
||||
isFavorite,
|
||||
hasAnySoftDeleteFilterOnView,
|
||||
}) =>
|
||||
!selectedRecord?.isRemote &&
|
||||
!isFavorite &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
component: <AddToFavoritesSingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
label: msg`Remove from favorites`,
|
||||
shortLabel: msg`Remove from favorites`,
|
||||
isPinned: true,
|
||||
position: 10,
|
||||
Icon: IconHeartOff,
|
||||
shouldBeRegistered: ({
|
||||
selectedRecord,
|
||||
isFavorite,
|
||||
hasAnySoftDeleteFilterOnView,
|
||||
}) =>
|
||||
isDefined(selectedRecord) &&
|
||||
!selectedRecord?.isRemote &&
|
||||
isDefined(isFavorite) &&
|
||||
isFavorite &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
component: <RemoveFromFavoritesSingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_NOTE_TO_PDF]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT_NOTE_TO_PDF,
|
||||
label: msg`Export to PDF`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 11,
|
||||
isPinned: false,
|
||||
Icon: IconFileExport,
|
||||
shouldBeRegistered: ({ selectedRecord, isNoteOrTask }) =>
|
||||
isDefined(isNoteOrTask) &&
|
||||
isNoteOrTask &&
|
||||
isNonEmptyString(selectedRecord?.bodyV2?.blocknote),
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <ExportNoteActionSingleRecordAction />,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX,
|
||||
label: msg`Export`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 12,
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && !selectedRecord.isRemote,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION],
|
||||
component: <ExportMultipleRecordsAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW,
|
||||
label: msg`Export`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 13,
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && !selectedRecord.isRemote,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <ExportSingleRecordAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
|
||||
},
|
||||
[MultipleRecordsActionKeys.MERGE]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.MERGE,
|
||||
label: msg`Merge records`,
|
||||
shortLabel: msg`Merge`,
|
||||
position: 14,
|
||||
Icon: IconArrowMerge,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({
|
||||
objectMetadataItem,
|
||||
numberOfSelectedRecords,
|
||||
objectPermissions,
|
||||
}) =>
|
||||
isDefined(objectMetadataItem?.duplicateCriteria) &&
|
||||
isDefined(numberOfSelectedRecords) &&
|
||||
Boolean(objectPermissions.canUpdateObjectRecords) &&
|
||||
Boolean(objectPermissions.canDestroyObjectRecords) &&
|
||||
numberOfSelectedRecords <= MUTATION_MAX_MERGE_RECORDS,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
component: <MergeMultipleRecordsAction />,
|
||||
},
|
||||
[MultipleRecordsActionKeys.EXPORT]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.EXPORT,
|
||||
label: msg`Export records`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 15,
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
component: <ExportMultipleRecordsAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.IMPORT_RECORDS]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.IMPORT_RECORDS,
|
||||
label: msg`Import records`,
|
||||
shortLabel: msg`Import`,
|
||||
position: 16,
|
||||
Icon: IconFileImport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ hasAnySoftDeleteFilterOnView }) =>
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <ImportRecordsNoSelectionRecordAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.IMPORT_CSV,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.EXPORT_VIEW]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.EXPORT_VIEW,
|
||||
label: msg`Export view`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 17,
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <ExportMultipleRecordsAction />,
|
||||
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.SEE_DELETED_RECORDS]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
label: msg`See deleted records`,
|
||||
shortLabel: msg`Deleted records`,
|
||||
position: 18,
|
||||
Icon: IconRotate2,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ hasAnySoftDeleteFilterOnView }) =>
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <SeeDeletedRecordsNoSelectionRecordAction />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_VIEW]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.CREATE_NEW_VIEW,
|
||||
label: msg`Create View`,
|
||||
shortLabel: msg`Create View`,
|
||||
position: 19,
|
||||
Icon: IconLayout,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ hasAnySoftDeleteFilterOnView }) =>
|
||||
!hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <CreateNewViewNoSelectionRecord />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
label: msg`Hide deleted records`,
|
||||
shortLabel: msg`Hide deleted`,
|
||||
position: 20,
|
||||
Icon: IconEyeOff,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ hasAnySoftDeleteFilterOnView }) =>
|
||||
isDefined(hasAnySoftDeleteFilterOnView) && hasAnySoftDeleteFilterOnView,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <HideDeletedRecordsNoSelectionRecordAction />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_WORKFLOWS]: {
|
||||
type: ActionType.Navigation,
|
||||
scope: ActionScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_WORKFLOWS,
|
||||
label: msg`Go to Workflows`,
|
||||
shortLabel: msg`See Workflows`,
|
||||
position: 20,
|
||||
position: 21,
|
||||
Icon: IconSettingsAutomation,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
@@ -495,6 +496,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.PAGE_EDIT_MODE,
|
||||
],
|
||||
component: (
|
||||
<ActionLink
|
||||
@@ -510,7 +512,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
label: msg`Go to People`,
|
||||
shortLabel: msg`People`,
|
||||
position: 21,
|
||||
position: 22,
|
||||
Icon: IconUser,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@@ -518,6 +520,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.PAGE_EDIT_MODE,
|
||||
],
|
||||
shouldBeRegistered: ({
|
||||
objectMetadataItem,
|
||||
@@ -541,7 +544,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
label: msg`Go to Companies`,
|
||||
shortLabel: msg`Companies`,
|
||||
position: 22,
|
||||
position: 23,
|
||||
Icon: IconBuildingSkyscraper,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@@ -549,6 +552,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.PAGE_EDIT_MODE,
|
||||
],
|
||||
shouldBeRegistered: ({
|
||||
objectMetadataItem,
|
||||
@@ -603,7 +607,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
label: msg`Go to Opportunities`,
|
||||
shortLabel: msg`Opportunities`,
|
||||
position: 23,
|
||||
position: 25,
|
||||
Icon: IconTargetArrow,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@@ -611,6 +615,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.PAGE_EDIT_MODE,
|
||||
],
|
||||
shouldBeRegistered: ({
|
||||
objectMetadataItem,
|
||||
@@ -635,7 +640,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
label: msg`Go to Settings`,
|
||||
shortLabel: msg`Settings`,
|
||||
position: 25,
|
||||
position: 26,
|
||||
Icon: IconSettings,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@@ -661,7 +666,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
label: msg`Go to Tasks`,
|
||||
shortLabel: msg`Tasks`,
|
||||
position: 26,
|
||||
position: 27,
|
||||
Icon: IconCheckbox,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@@ -669,6 +674,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.PAGE_EDIT_MODE,
|
||||
],
|
||||
shouldBeRegistered: ({
|
||||
objectMetadataItem,
|
||||
@@ -692,7 +698,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_NOTES,
|
||||
label: msg`Go to Notes`,
|
||||
shortLabel: msg`Notes`,
|
||||
position: 27,
|
||||
position: 28,
|
||||
Icon: IconCheckbox,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@@ -700,6 +706,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.PAGE_EDIT_MODE,
|
||||
],
|
||||
shouldBeRegistered: ({
|
||||
objectMetadataItem,
|
||||
|
||||
+4
-4
@@ -19,7 +19,7 @@ export const RECORD_PAGE_LAYOUT_ACTIONS_CONFIG =
|
||||
label: msg`Edit Layout`,
|
||||
shortLabel: msg`Edit`,
|
||||
isPinned: true,
|
||||
position: 0,
|
||||
position: 2,
|
||||
Icon: IconPencil,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -47,7 +47,7 @@ export const RECORD_PAGE_LAYOUT_ACTIONS_CONFIG =
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
// TODO: Once backend is ready, uncomment the line below
|
||||
// isDefined(selectedRecord?.pageLayoutId),
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
availableOn: [ActionViewType.PAGE_EDIT_MODE],
|
||||
component: <SaveRecordPageLayoutSingleRecordAction />,
|
||||
},
|
||||
[PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION]: {
|
||||
@@ -55,7 +55,7 @@ export const RECORD_PAGE_LAYOUT_ACTIONS_CONFIG =
|
||||
label: msg`Cancel Edition`,
|
||||
shortLabel: msg`Cancel`,
|
||||
isPinned: true,
|
||||
position: 2,
|
||||
position: 0,
|
||||
Icon: IconX,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -65,7 +65,7 @@ export const RECORD_PAGE_LAYOUT_ACTIONS_CONFIG =
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
// TODO: Once backend is ready, uncomment the line below
|
||||
// isDefined(selectedRecord?.pageLayoutId),
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
availableOn: [ActionViewType.PAGE_EDIT_MODE],
|
||||
component: <CancelRecordPageLayoutSingleRecordAction />,
|
||||
},
|
||||
},
|
||||
|
||||
+116
-113
@@ -28,6 +28,7 @@ import { msg } from '@lingui/core/macro';
|
||||
import { AppPath } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconCopy,
|
||||
IconHistoryToggle,
|
||||
IconNoteOff,
|
||||
IconPlayerPause,
|
||||
@@ -36,7 +37,6 @@ import {
|
||||
IconPower,
|
||||
IconReorder,
|
||||
IconVersions,
|
||||
IconCopy,
|
||||
} from 'twenty-ui/display';
|
||||
|
||||
const areWorkflowTriggerAndStepsDefined = (
|
||||
@@ -61,7 +61,8 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
label: msg`Activate Workflow`,
|
||||
shortLabel: msg`Activate`,
|
||||
isPinned: true,
|
||||
position: 1,
|
||||
isPrimaryCTA: true,
|
||||
position: 3,
|
||||
Icon: IconPower,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -83,7 +84,7 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
label: msg`Deactivate Workflow`,
|
||||
shortLabel: msg`Deactivate`,
|
||||
isPinned: true,
|
||||
position: 2,
|
||||
position: 4,
|
||||
Icon: IconPlayerPause,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -102,7 +103,7 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
label: msg`Discard Draft`,
|
||||
shortLabel: msg`Discard Draft`,
|
||||
isPinned: true,
|
||||
position: 3,
|
||||
position: 5,
|
||||
Icon: IconNoteOff,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -117,86 +118,12 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
],
|
||||
component: <DiscardDraftWorkflowSingleRecordAction />,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.DUPLICATE_WORKFLOW]: {
|
||||
key: WorkflowSingleRecordActionKeys.DUPLICATE_WORKFLOW,
|
||||
label: msg`Duplicate Workflow`,
|
||||
shortLabel: msg`Duplicate`,
|
||||
isPinned: false,
|
||||
position: 10,
|
||||
Icon: IconCopy,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord, workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
isDefined(workflowWithCurrentVersion.currentVersion) &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <DuplicateWorkflowSingleRecordAction />,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.SEE_ACTIVE_VERSION]: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_ACTIVE_VERSION,
|
||||
label: msg`See active version`,
|
||||
shortLabel: msg`See active version`,
|
||||
isPinned: false,
|
||||
position: 4,
|
||||
Icon: IconVersions,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion, selectedRecord }) =>
|
||||
(workflowWithCurrentVersion?.statuses?.includes('ACTIVE') || false) &&
|
||||
(workflowWithCurrentVersion?.statuses?.includes('DRAFT') || false) &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeActiveVersionWorkflowSingleRecordAction />,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.SEE_RUNS]: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_RUNS,
|
||||
label: msg`See runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
isPinned: true,
|
||||
position: 5,
|
||||
Icon: IconHistoryToggle,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord, workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeRunsWorkflowSingleRecordAction />,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.SEE_VERSIONS]: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_VERSIONS,
|
||||
label: msg`See versions history`,
|
||||
shortLabel: msg`See versions`,
|
||||
isPinned: false,
|
||||
position: 6,
|
||||
Icon: IconVersions,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord, workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeVersionsWorkflowSingleRecordAction />,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.TEST]: {
|
||||
key: WorkflowSingleRecordActionKeys.TEST,
|
||||
label: msg`Test Workflow`,
|
||||
shortLabel: msg`Test`,
|
||||
isPinned: true,
|
||||
position: 7,
|
||||
position: 6,
|
||||
Icon: IconPlayerPlay,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -217,12 +144,69 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
],
|
||||
component: <TestWorkflowSingleRecordAction />,
|
||||
},
|
||||
|
||||
[WorkflowSingleRecordActionKeys.SEE_ACTIVE_VERSION]: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_ACTIVE_VERSION,
|
||||
label: msg`See active version`,
|
||||
shortLabel: msg`See active version`,
|
||||
isPinned: false,
|
||||
position: 7,
|
||||
Icon: IconVersions,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion, selectedRecord }) =>
|
||||
(workflowWithCurrentVersion?.statuses?.includes('ACTIVE') || false) &&
|
||||
(workflowWithCurrentVersion?.statuses?.includes('DRAFT') || false) &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeActiveVersionWorkflowSingleRecordAction />,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.SEE_RUNS]: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_RUNS,
|
||||
label: msg`See runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
isPinned: true,
|
||||
position: 8,
|
||||
Icon: IconHistoryToggle,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord, workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeRunsWorkflowSingleRecordAction />,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.SEE_VERSIONS]: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_VERSIONS,
|
||||
label: msg`See versions history`,
|
||||
shortLabel: msg`See versions`,
|
||||
isPinned: false,
|
||||
position: 9,
|
||||
Icon: IconVersions,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord, workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeVersionsWorkflowSingleRecordAction />,
|
||||
},
|
||||
|
||||
[WorkflowSingleRecordActionKeys.ADD_NODE]: {
|
||||
key: WorkflowSingleRecordActionKeys.ADD_NODE,
|
||||
label: msg`Add a node`,
|
||||
shortLabel: msg`Add a node`,
|
||||
isPinned: false,
|
||||
position: 8,
|
||||
position: 10,
|
||||
Icon: IconPlus,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -237,7 +221,7 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
label: msg`Tidy up workflow`,
|
||||
shortLabel: msg`Tidy up`,
|
||||
isPinned: false,
|
||||
position: 9,
|
||||
position: 11,
|
||||
Icon: IconReorder,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -247,6 +231,25 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <TidyUpWorkflowSingleRecordAction />,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.DUPLICATE_WORKFLOW]: {
|
||||
key: WorkflowSingleRecordActionKeys.DUPLICATE_WORKFLOW,
|
||||
label: msg`Duplicate Workflow`,
|
||||
shortLabel: msg`Duplicate`,
|
||||
isPinned: false,
|
||||
position: 12,
|
||||
Icon: IconCopy,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
shouldBeRegistered: ({ selectedRecord, workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
isDefined(workflowWithCurrentVersion.currentVersion) &&
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <DuplicateWorkflowSingleRecordAction />,
|
||||
},
|
||||
[NoSelectionWorkflowRecordActionKeys.GO_TO_RUNS]: {
|
||||
type: ActionType.Navigation,
|
||||
scope: ActionScope.Global,
|
||||
@@ -294,16 +297,18 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
NoSelectionRecordActionKeys.GO_TO_NOTES,
|
||||
],
|
||||
propertiesToOverwrite: {
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_RECORD]: {
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
position: 0,
|
||||
label: msg`Navigate to next workflow`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
position: 1,
|
||||
label: msg`Navigate to previous workflow`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_RECORD]: {
|
||||
position: 2,
|
||||
label: msg`Create new workflow`,
|
||||
},
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
position: 10,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
position: 11,
|
||||
},
|
||||
[SingleRecordActionKeys.DELETE]: {
|
||||
position: 12,
|
||||
label: msg`Delete workflow`,
|
||||
@@ -312,72 +317,70 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
position: 13,
|
||||
label: msg`Delete workflows`,
|
||||
},
|
||||
[SingleRecordActionKeys.DESTROY]: {
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
position: 14,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
position: 15,
|
||||
},
|
||||
[SingleRecordActionKeys.DESTROY]: {
|
||||
position: 16,
|
||||
label: msg`Permanently destroy workflow`,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX]: {
|
||||
position: 15,
|
||||
position: 17,
|
||||
label: msg`Export workflow`,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
!isDefined(selectedRecord?.deletedAt),
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: {
|
||||
position: 16,
|
||||
position: 18,
|
||||
label: msg`Export workflow`,
|
||||
},
|
||||
[MultipleRecordsActionKeys.EXPORT]: {
|
||||
position: 17,
|
||||
position: 19,
|
||||
label: msg`Export workflows`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.EXPORT_VIEW]: {
|
||||
position: 17,
|
||||
position: 20,
|
||||
label: msg`Export view`,
|
||||
},
|
||||
[MultipleRecordsActionKeys.DESTROY]: {
|
||||
position: 18,
|
||||
position: 21,
|
||||
label: msg`Permanently destroy workflows`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
position: 19,
|
||||
label: msg`Navigate to previous workflow`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
position: 20,
|
||||
label: msg`Navigate to next workflow`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.SEE_DELETED_RECORDS]: {
|
||||
position: 21,
|
||||
position: 22,
|
||||
label: msg`See deleted workflows`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: {
|
||||
position: 22,
|
||||
position: 23,
|
||||
label: msg`Hide deleted workflows`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.IMPORT_RECORDS]: {
|
||||
position: 23,
|
||||
position: 24,
|
||||
label: msg`Import workflows`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_PEOPLE]: {
|
||||
position: 24,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 25,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 26,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_DASHBOARDS]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
position: 27,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_DASHBOARDS]: {
|
||||
position: 28,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
position: 29,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_NOTES]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
position: 30,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_NOTES]: {
|
||||
position: 31,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
+34
-33
@@ -18,11 +18,44 @@ import {
|
||||
|
||||
export const WORKFLOW_RUNS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
config: {
|
||||
[WorkflowRunSingleRecordActionKeys.SEE_VERSION]: {
|
||||
key: WorkflowRunSingleRecordActionKeys.SEE_VERSION,
|
||||
label: msg`See version`,
|
||||
shortLabel: msg`See version`,
|
||||
position: 0,
|
||||
isPinned: true,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
Icon: IconVersions,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeVersionWorkflowRunSingleRecordAction />,
|
||||
},
|
||||
|
||||
[WorkflowRunSingleRecordActionKeys.SEE_WORKFLOW]: {
|
||||
key: WorkflowRunSingleRecordActionKeys.SEE_WORKFLOW,
|
||||
label: msg`See workflow`,
|
||||
shortLabel: msg`See workflow`,
|
||||
position: 1,
|
||||
isPinned: true,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
Icon: IconSettingsAutomation,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeWorkflowWorkflowRunSingleRecordAction />,
|
||||
},
|
||||
[WorkflowRunSingleRecordActionKeys.STOP]: {
|
||||
key: WorkflowRunSingleRecordActionKeys.STOP,
|
||||
label: msg`Stop`,
|
||||
shortLabel: msg`Stop`,
|
||||
position: 0,
|
||||
position: 2,
|
||||
isPinned: true,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
@@ -42,38 +75,6 @@ export const WORKFLOW_RUNS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
],
|
||||
component: <StopWorkflowRunSingleRecordAction />,
|
||||
},
|
||||
[WorkflowRunSingleRecordActionKeys.SEE_WORKFLOW]: {
|
||||
key: WorkflowRunSingleRecordActionKeys.SEE_WORKFLOW,
|
||||
label: msg`See workflow`,
|
||||
shortLabel: msg`See workflow`,
|
||||
position: 1,
|
||||
isPinned: true,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
Icon: IconSettingsAutomation,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeWorkflowWorkflowRunSingleRecordAction />,
|
||||
},
|
||||
[WorkflowRunSingleRecordActionKeys.SEE_VERSION]: {
|
||||
key: WorkflowRunSingleRecordActionKeys.SEE_VERSION,
|
||||
label: msg`See version`,
|
||||
shortLabel: msg`See version`,
|
||||
position: 2,
|
||||
isPinned: true,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
Icon: IconVersions,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeVersionWorkflowRunSingleRecordAction />,
|
||||
},
|
||||
},
|
||||
actionKeys: [
|
||||
SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
|
||||
+26
-26
@@ -26,22 +26,22 @@ import {
|
||||
export const WORKFLOW_VERSIONS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig(
|
||||
{
|
||||
config: {
|
||||
[WorkflowVersionSingleRecordActionKeys.USE_AS_DRAFT]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.USE_AS_DRAFT,
|
||||
label: msg`Use as draft`,
|
||||
shortLabel: msg`Use as draft`,
|
||||
[WorkflowVersionSingleRecordActionKeys.SEE_RUNS]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_RUNS,
|
||||
label: msg`See runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
position: 1,
|
||||
isPinned: true,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
Icon: IconPencil,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && selectedRecord.status !== 'DRAFT',
|
||||
Icon: IconHistoryToggle,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <UseAsDraftWorkflowVersionSingleRecordAction />,
|
||||
component: <SeeRunsWorkflowVersionSingleRecordAction />,
|
||||
},
|
||||
[WorkflowVersionSingleRecordActionKeys.SEE_WORKFLOW]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_WORKFLOW,
|
||||
@@ -60,22 +60,22 @@ export const WORKFLOW_VERSIONS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig(
|
||||
],
|
||||
component: <SeeWorkflowWorkflowVersionSingleRecordAction />,
|
||||
},
|
||||
[WorkflowVersionSingleRecordActionKeys.SEE_RUNS]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_RUNS,
|
||||
label: msg`See runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
[WorkflowVersionSingleRecordActionKeys.USE_AS_DRAFT]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.USE_AS_DRAFT,
|
||||
label: msg`Use as draft`,
|
||||
shortLabel: msg`Use as draft`,
|
||||
position: 3,
|
||||
isPinned: true,
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.RecordSelection,
|
||||
Icon: IconHistoryToggle,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion),
|
||||
Icon: IconPencil,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && selectedRecord.status !== 'DRAFT',
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
component: <SeeRunsWorkflowVersionSingleRecordAction />,
|
||||
component: <UseAsDraftWorkflowVersionSingleRecordAction />,
|
||||
},
|
||||
[WorkflowVersionSingleRecordActionKeys.SEE_VERSIONS]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_VERSIONS,
|
||||
@@ -99,7 +99,7 @@ export const WORKFLOW_VERSIONS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig(
|
||||
key: NoSelectionWorkflowRecordActionKeys.GO_TO_RUNS,
|
||||
label: msg`Go to runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
position: 15,
|
||||
position: 14,
|
||||
Icon: IconHistoryToggle,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
@@ -172,30 +172,30 @@ export const WORKFLOW_VERSIONS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig(
|
||||
label: msg`Navigate to next version`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_WORKFLOWS]: {
|
||||
position: 14,
|
||||
position: 15,
|
||||
isPinned: true,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_PEOPLE]: {
|
||||
position: 15,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 16,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 17,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_DASHBOARDS]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
position: 18,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_DASHBOARDS]: {
|
||||
position: 19,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
position: 20,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_NOTES]: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
position: 21,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_NOTES]: {
|
||||
position: 22,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@ export type ActionConfig = {
|
||||
position: number;
|
||||
Icon: IconComponent;
|
||||
isPinned?: boolean;
|
||||
isPrimaryCTA?: boolean;
|
||||
accent?: MenuItemAccent;
|
||||
availableOn?: ActionViewType[];
|
||||
shouldBeRegistered: (params: ShouldBeRegisteredFunctionParams) => boolean;
|
||||
|
||||
@@ -4,4 +4,5 @@ export enum ActionViewType {
|
||||
INDEX_PAGE_SINGLE_RECORD_SELECTION = 'INDEX_PAGE_SINGLE_RECORD_SELECTION',
|
||||
INDEX_PAGE_NO_SELECTION = 'INDEX_PAGE_NO_SELECTION',
|
||||
SHOW_PAGE = 'SHOW_PAGE',
|
||||
PAGE_EDIT_MODE = 'PAGE_EDIT_MODE',
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ export const PageHeaderActionMenuButtons = () => {
|
||||
const { actions } = useContext(ActionMenuContext);
|
||||
const theme = useTheme();
|
||||
|
||||
const pinnedActions = actions.filter((entry) => entry.isPinned);
|
||||
const pinnedActions = actions.filter((entry) => entry.isPinned).toReversed();
|
||||
|
||||
const actionsWithPositionForAnimation = pinnedActions.map(
|
||||
(action, index) => ({
|
||||
|
||||
@@ -5,6 +5,7 @@ import { type ShouldBeRegisteredFunctionParams } from '@/action-menu/actions/typ
|
||||
import { getActionConfig } from '@/action-menu/actions/utils/getActionConfig';
|
||||
import { getActionViewType } from '@/action-menu/actions/utils/getActionViewType';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { usePermissionFlagMap } from '@/settings/roles/hooks/usePermissionFlagMap';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
@@ -29,6 +30,10 @@ export const useRegisteredActions = (
|
||||
contextStoreCurrentViewTypeComponentState,
|
||||
);
|
||||
|
||||
const isFullTabWidgetInEditMode = useRecoilComponentValue(
|
||||
contextStoreIsPageInEditModeComponentState,
|
||||
);
|
||||
|
||||
const isRecordPageLayoutEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_RECORD_PAGE_LAYOUT_ENABLED,
|
||||
);
|
||||
@@ -59,13 +64,23 @@ export const useRegisteredActions = (
|
||||
|
||||
const permissionMap = usePermissionFlagMap();
|
||||
|
||||
const actionsToRegister = isDefined(viewType)
|
||||
? Object.values(actionsConfig).filter(
|
||||
(action) =>
|
||||
action.availableOn?.includes(viewType) ||
|
||||
action.availableOn?.includes(ActionViewType.GLOBAL),
|
||||
)
|
||||
: [];
|
||||
const actionsToRegister = Object.values(actionsConfig).filter((action) => {
|
||||
if (isFullTabWidgetInEditMode) {
|
||||
return (
|
||||
isDefined(action.availableOn) &&
|
||||
action.availableOn.includes(ActionViewType.PAGE_EDIT_MODE)
|
||||
);
|
||||
}
|
||||
|
||||
if (isDefined(viewType)) {
|
||||
return (
|
||||
action.availableOn?.includes(viewType) ||
|
||||
action.availableOn?.includes(ActionViewType.GLOBAL)
|
||||
);
|
||||
}
|
||||
|
||||
return action.availableOn?.includes(ActionViewType.GLOBAL);
|
||||
});
|
||||
|
||||
const actions = actionsToRegister
|
||||
.filter((action) => {
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
|
||||
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
||||
|
||||
export const useExecuteTasksOnAnyLocationChange = () => {
|
||||
const { closeAnyOpenDropdown } = useCloseAnyOpenDropdown();
|
||||
|
||||
const resetIsPageInEditMode = useRecoilCallback(
|
||||
({ set }) =>
|
||||
() => {
|
||||
set(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
/**
|
||||
* Be careful to put idempotent tasks here.
|
||||
*
|
||||
@@ -10,6 +27,7 @@ export const useExecuteTasksOnAnyLocationChange = () => {
|
||||
*/
|
||||
const executeTasksOnAnyLocationChange = () => {
|
||||
closeAnyOpenDropdown();
|
||||
resetIsPageInEditMode();
|
||||
};
|
||||
|
||||
return { executeTasksOnAnyLocationChange };
|
||||
|
||||
+16
@@ -4,6 +4,7 @@ import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
@@ -137,6 +138,21 @@ export const useCopyContextStoreStates = () => {
|
||||
}),
|
||||
contextStoreCurrentViewType,
|
||||
);
|
||||
|
||||
const contextStoreIsFullTabWidgetInEditMode = snapshot
|
||||
.getLoadable(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
|
||||
set(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreIsFullTabWidgetInEditMode,
|
||||
);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
@@ -8,6 +8,7 @@ import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainCo
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
@@ -141,6 +142,19 @@ export const useOpenRecordInCommandMenu = () => {
|
||||
.getValue(),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
snapshot
|
||||
.getLoadable(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
)
|
||||
.getValue(),
|
||||
);
|
||||
|
||||
const currentMorphItems = snapshot
|
||||
.getLoadable(commandMenuNavigationMorphItemsByPageState)
|
||||
.getValue();
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const contextStoreIsPageInEditModeComponentState =
|
||||
createComponentState<boolean>({
|
||||
key: 'contextStoreIsPageInEditModeComponentState',
|
||||
defaultValue: false,
|
||||
componentInstanceContext: ContextStoreComponentInstanceContext,
|
||||
});
|
||||
+11
-15
@@ -1,6 +1,5 @@
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { forceRegisteredActionsByKeyState } from '@/action-menu/actions/states/forceRegisteredActionsMapComponentState';
|
||||
import { PageLayoutSingleRecordActionKeys } from '@/page-layout/actions/PageLayoutSingleRecordActionKeys';
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
|
||||
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
|
||||
import { isPageLayoutInEditModeComponentState } from '@/page-layout/states/isPageLayoutInEditModeComponentState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
@@ -18,23 +17,20 @@ export const useSetIsPageLayoutInEditMode = (pageLayoutIdFromProps: string) => {
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const contextStoreIsFullTabWidgetInEditModeState =
|
||||
useRecoilComponentCallbackState(
|
||||
contextStoreIsPageInEditModeComponentState,
|
||||
MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const setIsPageLayoutInEditMode = useRecoilCallback(
|
||||
({ set }) =>
|
||||
(value: boolean) => {
|
||||
set(isPageLayoutInEditModeState, value);
|
||||
set(forceRegisteredActionsByKeyState, (prev) => ({
|
||||
...prev,
|
||||
[PageLayoutSingleRecordActionKeys.EDIT_LAYOUT]: !value,
|
||||
[PageLayoutSingleRecordActionKeys.SAVE_LAYOUT]: value,
|
||||
[PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION]: value,
|
||||
[PageLayoutSingleRecordActionKeys.ADD_TO_FAVORITES_READ_MODE]: !value,
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: value,
|
||||
[SingleRecordActionKeys.DELETE]: !value,
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: !value,
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: !value,
|
||||
}));
|
||||
|
||||
set(contextStoreIsFullTabWidgetInEditModeState, value);
|
||||
},
|
||||
[isPageLayoutInEditModeState],
|
||||
[isPageLayoutInEditModeState, contextStoreIsFullTabWidgetInEditModeState],
|
||||
);
|
||||
|
||||
return { setIsPageLayoutInEditMode };
|
||||
|
||||
Reference in New Issue
Block a user