690 extract shouldberegistered from the useaction hooks (#11355)
Closes https://github.com/twentyhq/core-team-issues/issues/690 This PR is the first part of a refactoring on the actions system https://github.com/twentyhq/core-team-issues/issues/683. It: - Removes `shouldBeRegistered` from the useAction hook - Instead `shouldBeRegistered` becomes a function to which we can pass parameters which describe the context of the app (the object, the selected record, information about favorites ...). It returns a boolean. - `useShouldActionBeRegisteredParams` returns the parameters to pass to the `shouldBeRegistered` - Introduces a way to inherit actions from the default config and to overwrite its properties, closing https://github.com/twentyhq/core-team-issues/issues/72 Some tests testing if an action was registered correctly have been removed, we should add them back at the end of the global refactoring.
This commit is contained in:
@ -10,8 +10,8 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const RecordActionMenuEntriesSetter = () => {
|
||||
const localContextStoreCurrentObjectMetadataItemId =
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
import { ActionHook } from '@/action-menu/actions/types/ActionHook';
|
||||
import { RecordConfigAction } from '@/action-menu/actions/types/RecordConfigAction';
|
||||
import { wrapActionInCallbacks } from '@/action-menu/actions/utils/wrapActionInCallbacks';
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
|
||||
import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry';
|
||||
import { useShouldActionBeRegisteredParams } from '@/action-menu/hooks/useShouldActionBeRegisteredParams';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { useContext, useEffect } from 'react';
|
||||
|
||||
type RegisterRecordActionEffectProps = {
|
||||
action: ActionMenuEntry & {
|
||||
useAction: ActionHook;
|
||||
};
|
||||
action: RecordConfigAction;
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
};
|
||||
|
||||
@ -17,7 +15,7 @@ export const RegisterRecordActionEffect = ({
|
||||
action,
|
||||
objectMetadataItem,
|
||||
}: RegisterRecordActionEffectProps) => {
|
||||
const { shouldBeRegistered, onClick, ConfirmationModal } = action.useAction({
|
||||
const { onClick, ConfirmationModal } = action.useAction({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
@ -36,6 +34,12 @@ export const RegisterRecordActionEffect = ({
|
||||
onActionExecutedCallback,
|
||||
});
|
||||
|
||||
const params = useShouldActionBeRegisteredParams({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const shouldBeRegistered = action.shouldBeRegistered(params);
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldBeRegistered) {
|
||||
addActionMenuEntry(wrappedAction);
|
||||
|
||||
@ -13,7 +13,7 @@ import { useHideDeletedRecordsNoSelectionRecordAction } from '@/action-menu/acti
|
||||
import { useImportRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useImportRecordsNoSelectionRecordAction';
|
||||
import { useSeeDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeDeletedRecordsNoSelectionRecordAction';
|
||||
import { useSeeWorkflowsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeWorkflowsNoSelectionRecordAction';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKey';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { useAddToFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction';
|
||||
import { useDeleteSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction';
|
||||
import { useDestroySingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDestroySingleRecordAction';
|
||||
@ -23,14 +23,16 @@ import { useNavigateToPreviousRecordSingleRecordAction } from '@/action-menu/act
|
||||
import { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction';
|
||||
import { useRestoreSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRestoreSingleRecordAction';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { ActionHook } from '@/action-menu/actions/types/ActionHook';
|
||||
import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import { RecordConfigAction } from '@/action-menu/actions/types/RecordConfigAction';
|
||||
import {
|
||||
ActionMenuEntry,
|
||||
ActionMenuEntryScope,
|
||||
ActionMenuEntryType,
|
||||
} from '@/action-menu/types/ActionMenuEntry';
|
||||
import { BACKEND_BATCH_REQUEST_MAX_COUNT } from '@/object-record/constants/BackendBatchRequestMaxCount';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconBuildingSkyscraper,
|
||||
IconCheckbox,
|
||||
@ -52,13 +54,13 @@ import {
|
||||
IconUser,
|
||||
} from 'twenty-ui';
|
||||
|
||||
export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
string,
|
||||
ActionMenuEntry & {
|
||||
useAction: ActionHook;
|
||||
}
|
||||
export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
| NoSelectionRecordActionKeys
|
||||
| SingleRecordActionKeys
|
||||
| MultipleRecordsActionKeys,
|
||||
RecordConfigAction
|
||||
> = {
|
||||
createNewRecord: {
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_RECORD]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.CREATE_NEW_RECORD,
|
||||
@ -67,10 +69,12 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
position: 0,
|
||||
isPinned: true,
|
||||
Icon: IconPlus,
|
||||
shouldBeRegistered: ({ hasObjectReadOnlyPermission }) =>
|
||||
!hasObjectReadOnlyPermission,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useCreateNewTableRecordNoSelectionRecordAction,
|
||||
},
|
||||
exportNoteToPdf: {
|
||||
[SingleRecordActionKeys.EXPORT_NOTE_TO_PDF]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT_NOTE_TO_PDF,
|
||||
@ -79,10 +83,14 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
position: 1,
|
||||
isPinned: false,
|
||||
Icon: IconFileExport,
|
||||
shouldBeRegistered: ({ selectedRecord, isNoteOrTask }) =>
|
||||
isDefined(isNoteOrTask) &&
|
||||
isNoteOrTask &&
|
||||
isNonEmptyString(selectedRecord?.bodyV2?.blocknote),
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useExportNoteAction,
|
||||
},
|
||||
addToFavoritesSingleRecord: {
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
@ -91,13 +99,15 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
position: 2,
|
||||
isPinned: true,
|
||||
Icon: IconHeart,
|
||||
shouldBeRegistered: ({ selectedRecord, isFavorite }) =>
|
||||
!selectedRecord?.isRemote && !isFavorite,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useAddToFavoritesSingleRecordAction,
|
||||
},
|
||||
removeFromFavoritesSingleRecord: {
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
@ -106,13 +116,18 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
isPinned: true,
|
||||
position: 3,
|
||||
Icon: IconHeartOff,
|
||||
shouldBeRegistered: ({ selectedRecord, isFavorite }) =>
|
||||
isDefined(selectedRecord) &&
|
||||
!selectedRecord?.isRemote &&
|
||||
isDefined(isFavorite) &&
|
||||
isFavorite,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useRemoveFromFavoritesSingleRecordAction,
|
||||
},
|
||||
exportSingleRecord: {
|
||||
[SingleRecordActionKeys.EXPORT]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT,
|
||||
@ -122,13 +137,15 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && !selectedRecord.isRemote,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
exportMultipleRecords: {
|
||||
[MultipleRecordsActionKeys.EXPORT]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.EXPORT,
|
||||
@ -138,10 +155,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
exportView: {
|
||||
[NoSelectionRecordActionKeys.EXPORT_VIEW]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.EXPORT_VIEW,
|
||||
@ -151,10 +169,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconFileExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
deleteSingleRecord: {
|
||||
[SingleRecordActionKeys.DELETE]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.DELETE,
|
||||
@ -164,13 +183,15 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconTrash,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && !selectedRecord.isRemote,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useDeleteSingleRecordAction,
|
||||
},
|
||||
deleteMultipleRecords: {
|
||||
[MultipleRecordsActionKeys.DELETE]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.DELETE,
|
||||
@ -180,10 +201,21 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconTrash,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({
|
||||
hasObjectReadOnlyPermission,
|
||||
isRemote,
|
||||
isSoftDeleteFilterActive,
|
||||
numberOfSelectedRecords,
|
||||
}) =>
|
||||
!hasObjectReadOnlyPermission &&
|
||||
!isRemote &&
|
||||
!isSoftDeleteFilterActive &&
|
||||
isDefined(numberOfSelectedRecords) &&
|
||||
numberOfSelectedRecords < BACKEND_BATCH_REQUEST_MAX_COUNT,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useDeleteMultipleRecordsAction,
|
||||
},
|
||||
seeDeletedRecords: {
|
||||
[NoSelectionRecordActionKeys.SEE_DELETED_RECORDS]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
@ -193,10 +225,12 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconRotate2,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ isSoftDeleteFilterActive }) =>
|
||||
!isSoftDeleteFilterActive,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
hideDeletedRecords: {
|
||||
[NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
@ -206,10 +240,12 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconEyeOff,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ isSoftDeleteFilterActive }) =>
|
||||
isDefined(isSoftDeleteFilterActive) && isSoftDeleteFilterActive,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useHideDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
importRecords: {
|
||||
[NoSelectionRecordActionKeys.IMPORT_RECORDS]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.IMPORT_RECORDS,
|
||||
@ -219,10 +255,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconFileImport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useImportRecordsNoSelectionRecordAction,
|
||||
},
|
||||
destroySingleRecord: {
|
||||
[SingleRecordActionKeys.DESTROY]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.DESTROY,
|
||||
@ -232,13 +269,21 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({
|
||||
selectedRecord,
|
||||
hasObjectReadOnlyPermission,
|
||||
isRemote,
|
||||
}) =>
|
||||
!hasObjectReadOnlyPermission &&
|
||||
!isRemote &&
|
||||
isDefined(selectedRecord?.deletedAt),
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useDestroySingleRecordAction,
|
||||
},
|
||||
navigateToPreviousRecord: {
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
@ -246,10 +291,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
position: 13,
|
||||
isPinned: true,
|
||||
Icon: IconChevronUp,
|
||||
shouldBeRegistered: ({ isInRightDrawer }) => !isInRightDrawer,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useNavigateToPreviousRecordSingleRecordAction,
|
||||
},
|
||||
navigateToNextRecord: {
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
@ -257,10 +303,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
position: 14,
|
||||
isPinned: true,
|
||||
Icon: IconChevronDown,
|
||||
shouldBeRegistered: ({ isInRightDrawer }) => !isInRightDrawer,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useNavigateToNextRecordSingleRecordAction,
|
||||
},
|
||||
destroyMultipleRecords: {
|
||||
[MultipleRecordsActionKeys.DESTROY]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.DESTROY,
|
||||
@ -270,10 +317,22 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({
|
||||
hasObjectReadOnlyPermission,
|
||||
isRemote,
|
||||
isSoftDeleteFilterActive,
|
||||
numberOfSelectedRecords,
|
||||
}) =>
|
||||
!hasObjectReadOnlyPermission &&
|
||||
!isRemote &&
|
||||
isDefined(isSoftDeleteFilterActive) &&
|
||||
isSoftDeleteFilterActive &&
|
||||
isDefined(numberOfSelectedRecords) &&
|
||||
numberOfSelectedRecords < BACKEND_BATCH_REQUEST_MAX_COUNT,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useDestroyMultipleRecordsAction,
|
||||
},
|
||||
restoreSingleRecord: {
|
||||
[SingleRecordActionKeys.RESTORE]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.RESTORE,
|
||||
@ -283,13 +342,25 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconRefresh,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({
|
||||
selectedRecord,
|
||||
hasObjectReadOnlyPermission,
|
||||
isRemote,
|
||||
isShowPage,
|
||||
isSoftDeleteFilterActive,
|
||||
}) =>
|
||||
!isRemote &&
|
||||
isDefined(selectedRecord?.deletedAt) &&
|
||||
!hasObjectReadOnlyPermission &&
|
||||
((isDefined(isShowPage) && isShowPage) ||
|
||||
(isDefined(isSoftDeleteFilterActive) && isSoftDeleteFilterActive)),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useRestoreSingleRecordAction,
|
||||
},
|
||||
restoreMultipleRecords: {
|
||||
[MultipleRecordsActionKeys.RESTORE]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.RESTORE,
|
||||
@ -299,10 +370,22 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconRefresh,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: ({
|
||||
hasObjectReadOnlyPermission,
|
||||
isRemote,
|
||||
isSoftDeleteFilterActive,
|
||||
numberOfSelectedRecords,
|
||||
}) =>
|
||||
!hasObjectReadOnlyPermission &&
|
||||
!isRemote &&
|
||||
isDefined(isSoftDeleteFilterActive) &&
|
||||
isSoftDeleteFilterActive &&
|
||||
isDefined(numberOfSelectedRecords) &&
|
||||
numberOfSelectedRecords < BACKEND_BATCH_REQUEST_MAX_COUNT,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useRestoreMultipleRecordsAction,
|
||||
},
|
||||
seeAllWorkflows: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_WORKFLOWS]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_WORKFLOWS,
|
||||
@ -312,11 +395,12 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
Icon: IconSettingsAutomation,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeWorkflowsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'W'],
|
||||
},
|
||||
goToPeople: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_PEOPLE]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
@ -331,10 +415,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
shouldBeRegistered: () => true,
|
||||
useAction: useGoToPeopleNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'P'],
|
||||
},
|
||||
goToCompanies: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
@ -349,10 +434,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
shouldBeRegistered: () => true,
|
||||
useAction: useGoToCompaniesNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'C'],
|
||||
},
|
||||
goToOpportunities: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
@ -367,10 +453,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
shouldBeRegistered: () => true,
|
||||
useAction: useGoToOpportunitiesNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'O'],
|
||||
},
|
||||
goToSettings: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
@ -385,10 +472,11 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
shouldBeRegistered: () => true,
|
||||
useAction: useGoToSettingsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'S'],
|
||||
},
|
||||
goToTasks: {
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
@ -403,6 +491,7 @@ export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
shouldBeRegistered: () => true,
|
||||
useAction: useGoToTasksNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'T'],
|
||||
},
|
||||
@ -1,24 +1,7 @@
|
||||
import { useDeleteMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction';
|
||||
import { useDestroyMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useDestroyMultipleRecordsAction';
|
||||
import { useExportMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction';
|
||||
import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys';
|
||||
import { useCreateNewTableRecordNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useCreateNewTableRecordNoSelectionRecordAction';
|
||||
import { useGoToCompaniesNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToCompaniesNoSelectionRecordAction';
|
||||
import { useGoToOpportunitiesNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToOpportunitiesNoSelectionRecordAction';
|
||||
import { useGoToPeopleNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToPeopleNoSelectionRecordAction';
|
||||
import { useGoToSettingsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToSettingsNoSelectionRecordAction';
|
||||
import { useGoToTasksNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToTasksNoSelectionRecordAction';
|
||||
import { useHideDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useHideDeletedRecordsNoSelectionRecordAction';
|
||||
import { useImportRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useImportRecordsNoSelectionRecordAction';
|
||||
import { useSeeDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeDeletedRecordsNoSelectionRecordAction';
|
||||
import { useSeeRunsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeRunsNoSelectionRecordAction';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKey';
|
||||
import { useAddToFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction';
|
||||
import { useDeleteSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction';
|
||||
import { useDestroySingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDestroySingleRecordAction';
|
||||
import { useNavigateToNextRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction';
|
||||
import { useNavigateToPreviousRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction';
|
||||
import { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { NoSelectionWorkflowRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/workflow-actions/types/NoSelectionWorkflowRecordActionsKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { useActivateWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateWorkflowSingleRecordAction';
|
||||
import { useDeactivateWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDeactivateWorkflowSingleRecordAction';
|
||||
@ -28,452 +11,268 @@ import { useSeeRunsWorkflowSingleRecordAction } from '@/action-menu/actions/reco
|
||||
import { useSeeVersionsWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeVersionsWorkflowSingleRecordAction';
|
||||
import { useTestWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useTestWorkflowSingleRecordAction';
|
||||
import { WorkflowSingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/workflow-actions/types/WorkflowSingleRecordActionsKeys';
|
||||
import { ActionHook } from '@/action-menu/actions/types/ActionHook';
|
||||
import { inheritActionsFromDefaultConfig } from '@/action-menu/actions/record-actions/utils/inheritActionsFromDefaultConfig';
|
||||
import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import {
|
||||
ActionMenuEntry,
|
||||
ActionMenuEntryScope,
|
||||
ActionMenuEntryType,
|
||||
} from '@/action-menu/types/ActionMenuEntry';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconBuildingSkyscraper,
|
||||
IconCheckbox,
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconDatabaseExport,
|
||||
IconEyeOff,
|
||||
IconFileImport,
|
||||
IconHeart,
|
||||
IconHeartOff,
|
||||
IconHistoryToggle,
|
||||
IconNoteOff,
|
||||
IconPlayerPause,
|
||||
IconPlayerPlay,
|
||||
IconPlus,
|
||||
IconPower,
|
||||
IconRotate2,
|
||||
IconSettings,
|
||||
IconTargetArrow,
|
||||
IconTrash,
|
||||
IconTrashX,
|
||||
IconUser,
|
||||
IconVersions,
|
||||
} from 'twenty-ui';
|
||||
|
||||
export const WORKFLOW_ACTIONS_CONFIG: Record<
|
||||
string,
|
||||
ActionMenuEntry & {
|
||||
useAction: ActionHook;
|
||||
}
|
||||
> = {
|
||||
createNewRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.CREATE_NEW_RECORD,
|
||||
label: msg`Create new record`,
|
||||
shortLabel: msg`New record`,
|
||||
position: 0,
|
||||
isPinned: true,
|
||||
Icon: IconPlus,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useCreateNewTableRecordNoSelectionRecordAction,
|
||||
export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
config: {
|
||||
[WorkflowSingleRecordActionKeys.ACTIVATE]: {
|
||||
key: WorkflowSingleRecordActionKeys.ACTIVATE,
|
||||
label: msg`Activate Workflow`,
|
||||
shortLabel: msg`Activate`,
|
||||
isPinned: true,
|
||||
position: 1,
|
||||
Icon: IconPower,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion?.currentVersion?.trigger) &&
|
||||
isDefined(workflowWithCurrentVersion.currentVersion?.steps) &&
|
||||
workflowWithCurrentVersion.currentVersion.steps.length > 0 &&
|
||||
(workflowWithCurrentVersion.currentVersion.status === 'DRAFT' ||
|
||||
!workflowWithCurrentVersion.versions?.some(
|
||||
(version) => version.status === 'ACTIVE',
|
||||
)),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useActivateWorkflowSingleRecordAction,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.DEACTIVATE]: {
|
||||
key: WorkflowSingleRecordActionKeys.DEACTIVATE,
|
||||
label: msg`Deactivate Workflow`,
|
||||
shortLabel: msg`Deactivate`,
|
||||
isPinned: true,
|
||||
position: 2,
|
||||
Icon: IconPlayerPause,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
workflowWithCurrentVersion.currentVersion.status === 'ACTIVE',
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useDeactivateWorkflowSingleRecordAction,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.DISCARD_DRAFT]: {
|
||||
key: WorkflowSingleRecordActionKeys.DISCARD_DRAFT,
|
||||
label: msg`Discard Draft`,
|
||||
shortLabel: msg`Discard Draft`,
|
||||
isPinned: true,
|
||||
position: 3,
|
||||
Icon: IconNoteOff,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
workflowWithCurrentVersion.versions.length > 1 &&
|
||||
workflowWithCurrentVersion.currentVersion.status === 'DRAFT',
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useDiscardDraftWorkflowSingleRecordAction,
|
||||
},
|
||||
[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: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
(workflowWithCurrentVersion?.statuses?.includes('ACTIVE') || false) &&
|
||||
(workflowWithCurrentVersion?.statuses?.includes('DRAFT') || false),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeActiveVersionWorkflowSingleRecordAction,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.SEE_RUNS]: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_RUNS,
|
||||
label: msg`See runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
isPinned: true,
|
||||
position: 5,
|
||||
Icon: IconHistoryToggle,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeRunsWorkflowSingleRecordAction,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.SEE_VERSIONS]: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_VERSIONS,
|
||||
label: msg`See versions history`,
|
||||
shortLabel: msg`See versions`,
|
||||
isPinned: false,
|
||||
position: 6,
|
||||
Icon: IconVersions,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeVersionsWorkflowSingleRecordAction,
|
||||
},
|
||||
[WorkflowSingleRecordActionKeys.TEST]: {
|
||||
key: WorkflowSingleRecordActionKeys.TEST,
|
||||
label: msg`Test Workflow`,
|
||||
shortLabel: msg`Test`,
|
||||
isPinned: true,
|
||||
position: 7,
|
||||
Icon: IconPlayerPlay,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion?.currentVersion?.trigger) &&
|
||||
((workflowWithCurrentVersion.currentVersion.trigger.type === 'MANUAL' &&
|
||||
!isDefined(
|
||||
workflowWithCurrentVersion.currentVersion.trigger.settings
|
||||
.objectType,
|
||||
)) ||
|
||||
workflowWithCurrentVersion.currentVersion.trigger.type === 'WEBHOOK'),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useTestWorkflowSingleRecordAction,
|
||||
},
|
||||
[NoSelectionWorkflowRecordActionKeys.GO_TO_RUNS]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionWorkflowRecordActionKeys.GO_TO_RUNS,
|
||||
label: msg`Go to runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
position: 22,
|
||||
Icon: IconHistoryToggle,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeRunsNoSelectionRecordAction,
|
||||
},
|
||||
},
|
||||
activateWorkflowSingleRecord: {
|
||||
key: WorkflowSingleRecordActionKeys.ACTIVATE,
|
||||
label: msg`Activate Workflow`,
|
||||
shortLabel: msg`Activate`,
|
||||
isPinned: true,
|
||||
position: 1,
|
||||
Icon: IconPower,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useActivateWorkflowSingleRecordAction,
|
||||
actionKeys: [
|
||||
NoSelectionRecordActionKeys.CREATE_NEW_RECORD,
|
||||
SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
SingleRecordActionKeys.DELETE,
|
||||
SingleRecordActionKeys.DESTROY,
|
||||
SingleRecordActionKeys.EXPORT,
|
||||
MultipleRecordsActionKeys.DELETE,
|
||||
MultipleRecordsActionKeys.DESTROY,
|
||||
MultipleRecordsActionKeys.EXPORT,
|
||||
NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
],
|
||||
propertiesToOverwrite: {
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_RECORD]: {
|
||||
position: 0,
|
||||
label: msg`Create new workflow`,
|
||||
},
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
position: 8,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
position: 9,
|
||||
},
|
||||
[SingleRecordActionKeys.DELETE]: {
|
||||
position: 10,
|
||||
label: msg`Delete workflow`,
|
||||
},
|
||||
[MultipleRecordsActionKeys.DELETE]: {
|
||||
position: 11,
|
||||
label: msg`Delete workflows`,
|
||||
},
|
||||
[SingleRecordActionKeys.DESTROY]: {
|
||||
position: 12,
|
||||
label: msg`Permanently destroy workflow`,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT]: {
|
||||
position: 13,
|
||||
label: msg`Export workflow`,
|
||||
},
|
||||
[MultipleRecordsActionKeys.EXPORT]: {
|
||||
position: 14,
|
||||
label: msg`Export workflows`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.EXPORT_VIEW]: {
|
||||
position: 15,
|
||||
label: msg`Export view`,
|
||||
},
|
||||
[MultipleRecordsActionKeys.DESTROY]: {
|
||||
position: 16,
|
||||
label: msg`Permanently destroy workflows`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
position: 17,
|
||||
label: msg`Navigate to previous workflow`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
position: 18,
|
||||
label: msg`Navigate to next workflow`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.SEE_DELETED_RECORDS]: {
|
||||
position: 19,
|
||||
label: msg`See deleted workflows`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: {
|
||||
position: 20,
|
||||
label: msg`Hide deleted workflows`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.IMPORT_RECORDS]: {
|
||||
position: 21,
|
||||
label: msg`Import workflows`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_PEOPLE]: {
|
||||
position: 23,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 24,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
position: 25,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
position: 26,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
position: 27,
|
||||
},
|
||||
},
|
||||
deactivateWorkflowSingleRecord: {
|
||||
key: WorkflowSingleRecordActionKeys.DEACTIVATE,
|
||||
label: msg`Deactivate Workflow`,
|
||||
shortLabel: msg`Deactivate`,
|
||||
isPinned: true,
|
||||
position: 2,
|
||||
Icon: IconPlayerPause,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useDeactivateWorkflowSingleRecordAction,
|
||||
},
|
||||
discardWorkflowDraftSingleRecord: {
|
||||
key: WorkflowSingleRecordActionKeys.DISCARD_DRAFT,
|
||||
label: msg`Discard Draft`,
|
||||
shortLabel: msg`Discard Draft`,
|
||||
isPinned: true,
|
||||
position: 3,
|
||||
Icon: IconNoteOff,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useDiscardDraftWorkflowSingleRecordAction,
|
||||
},
|
||||
seeWorkflowActiveVersionSingleRecord: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_ACTIVE_VERSION,
|
||||
label: msg`See active version`,
|
||||
shortLabel: msg`See active version`,
|
||||
isPinned: false,
|
||||
position: 4,
|
||||
Icon: IconVersions,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeActiveVersionWorkflowSingleRecordAction,
|
||||
},
|
||||
seeWorkflowRunsSingleRecord: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_RUNS,
|
||||
label: msg`See runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
isPinned: true,
|
||||
position: 5,
|
||||
Icon: IconHistoryToggle,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeRunsWorkflowSingleRecordAction,
|
||||
},
|
||||
seeWorkflowVersionsHistorySingleRecord: {
|
||||
key: WorkflowSingleRecordActionKeys.SEE_VERSIONS,
|
||||
label: msg`See versions history`,
|
||||
shortLabel: msg`See versions`,
|
||||
isPinned: false,
|
||||
position: 6,
|
||||
Icon: IconVersions,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeVersionsWorkflowSingleRecordAction,
|
||||
},
|
||||
testWorkflowSingleRecord: {
|
||||
key: WorkflowSingleRecordActionKeys.TEST,
|
||||
label: msg`Test Workflow`,
|
||||
shortLabel: msg`Test`,
|
||||
isPinned: true,
|
||||
position: 7,
|
||||
Icon: IconPlayerPlay,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useTestWorkflowSingleRecordAction,
|
||||
},
|
||||
navigateToPreviousRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
label: msg`Navigate to previous workflow`,
|
||||
position: 8,
|
||||
Icon: IconChevronUp,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useNavigateToPreviousRecordSingleRecordAction,
|
||||
},
|
||||
navigateToNextRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
label: msg`Navigate to next workflow`,
|
||||
position: 9,
|
||||
Icon: IconChevronDown,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useNavigateToNextRecordSingleRecordAction,
|
||||
},
|
||||
addToFavoritesSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
label: msg`Add to favorites`,
|
||||
shortLabel: msg`Add to favorites`,
|
||||
position: 10,
|
||||
isPinned: false,
|
||||
Icon: IconHeart,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useAddToFavoritesSingleRecordAction,
|
||||
},
|
||||
removeFromFavoritesSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
label: msg`Remove from favorites`,
|
||||
shortLabel: msg`Remove from favorites`,
|
||||
isPinned: false,
|
||||
position: 11,
|
||||
Icon: IconHeartOff,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useRemoveFromFavoritesSingleRecordAction,
|
||||
},
|
||||
deleteSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.DELETE,
|
||||
label: msg`Delete workflow`,
|
||||
shortLabel: msg`Delete`,
|
||||
position: 12,
|
||||
Icon: IconTrash,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useDeleteSingleRecordAction,
|
||||
},
|
||||
deleteMultipleRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.DELETE,
|
||||
label: msg`Delete workflows`,
|
||||
shortLabel: msg`Delete`,
|
||||
position: 13,
|
||||
Icon: IconTrash,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useDeleteMultipleRecordsAction,
|
||||
},
|
||||
destroySingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.DESTROY,
|
||||
label: msg`Permanently destroy record`,
|
||||
shortLabel: msg`Destroy`,
|
||||
position: 14,
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useDestroySingleRecordAction,
|
||||
},
|
||||
exportSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT,
|
||||
label: msg`Export workflow`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 15,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
exportMultipleRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.EXPORT,
|
||||
label: msg`Export workflows`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 16,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
exportView: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.EXPORT_VIEW,
|
||||
label: msg`Export view`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 17,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
destroyMultipleRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.DESTROY,
|
||||
label: msg`Permanently destroy workflows`,
|
||||
shortLabel: msg`Destroy`,
|
||||
position: 18,
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useDestroyMultipleRecordsAction,
|
||||
},
|
||||
seeDeletedRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
label: msg`See deleted workflows`,
|
||||
shortLabel: msg`Deleted workflows`,
|
||||
position: 19,
|
||||
Icon: IconRotate2,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
hideDeletedRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
label: msg`Hide deleted workflows`,
|
||||
shortLabel: msg`Hide deleted`,
|
||||
position: 20,
|
||||
Icon: IconEyeOff,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useHideDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
importRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.IMPORT_RECORDS,
|
||||
label: msg`Import workflows`,
|
||||
shortLabel: msg`Import`,
|
||||
position: 21,
|
||||
Icon: IconFileImport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useImportRecordsNoSelectionRecordAction,
|
||||
},
|
||||
seeAllRuns: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_RUNS,
|
||||
label: msg`Go to runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
position: 22,
|
||||
Icon: IconHistoryToggle,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeRunsNoSelectionRecordAction,
|
||||
},
|
||||
goToPeople: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
label: msg`Go to People`,
|
||||
shortLabel: msg`People`,
|
||||
position: 23,
|
||||
Icon: IconUser,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToPeopleNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'P'],
|
||||
},
|
||||
goToCompanies: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
label: msg`Go to Companies`,
|
||||
shortLabel: msg`Companies`,
|
||||
position: 24,
|
||||
Icon: IconBuildingSkyscraper,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToCompaniesNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'C'],
|
||||
},
|
||||
goToOpportunities: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
label: msg`Go to Opportunities`,
|
||||
shortLabel: msg`Opportunities`,
|
||||
position: 25,
|
||||
Icon: IconTargetArrow,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToOpportunitiesNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'O'],
|
||||
},
|
||||
goToSettings: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
label: msg`Go to Settings`,
|
||||
shortLabel: msg`Settings`,
|
||||
position: 26,
|
||||
Icon: IconSettings,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToSettingsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'S'],
|
||||
},
|
||||
goToTasks: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
label: msg`Go to Tasks`,
|
||||
shortLabel: msg`Tasks`,
|
||||
position: 27,
|
||||
Icon: IconCheckbox,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToTasksNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'T'],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@ -1,305 +1,134 @@
|
||||
import { useExportMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction';
|
||||
import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys';
|
||||
import { useGoToCompaniesNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToCompaniesNoSelectionRecordAction';
|
||||
import { useGoToOpportunitiesNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToOpportunitiesNoSelectionRecordAction';
|
||||
import { useGoToPeopleNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToPeopleNoSelectionRecordAction';
|
||||
import { useGoToSettingsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToSettingsNoSelectionRecordAction';
|
||||
import { useGoToTasksNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToTasksNoSelectionRecordAction';
|
||||
import { useHideDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useHideDeletedRecordsNoSelectionRecordAction';
|
||||
import { useSeeDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeDeletedRecordsNoSelectionRecordAction';
|
||||
import { useSeeWorkflowsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeWorkflowsNoSelectionRecordAction';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKey';
|
||||
import { useAddToFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction';
|
||||
import { useNavigateToNextRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction';
|
||||
import { useNavigateToPreviousRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction';
|
||||
import { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { useSeeVersionWorkflowRunSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-run-actions/hooks/useSeeVersionWorkflowRunSingleRecordAction';
|
||||
import { useSeeWorkflowWorkflowRunSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-run-actions/hooks/useSeeWorkflowWorkflowRunSingleRecordAction';
|
||||
import { WorkflowRunSingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/workflow-run-actions/types/WorkflowRunSingleRecordActionsKeys';
|
||||
import { ActionHook } from '@/action-menu/actions/types/ActionHook';
|
||||
import { inheritActionsFromDefaultConfig } from '@/action-menu/actions/record-actions/utils/inheritActionsFromDefaultConfig';
|
||||
import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import {
|
||||
ActionMenuEntry,
|
||||
ActionMenuEntryScope,
|
||||
ActionMenuEntryType,
|
||||
} from '@/action-menu/types/ActionMenuEntry';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import {
|
||||
IconBuildingSkyscraper,
|
||||
IconCheckbox,
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconDatabaseExport,
|
||||
IconEyeOff,
|
||||
IconHeart,
|
||||
IconHeartOff,
|
||||
IconRotate2,
|
||||
IconSettings,
|
||||
IconSettingsAutomation,
|
||||
IconTargetArrow,
|
||||
IconUser,
|
||||
IconVersions,
|
||||
} from 'twenty-ui';
|
||||
import { IconSettingsAutomation, IconVersions } from 'twenty-ui';
|
||||
|
||||
export const WORKFLOW_RUNS_ACTIONS_CONFIG: Record<
|
||||
string,
|
||||
ActionMenuEntry & {
|
||||
useAction: ActionHook;
|
||||
}
|
||||
> = {
|
||||
seeWorkflowSingleRecord: {
|
||||
key: WorkflowRunSingleRecordActionKeys.SEE_WORKFLOW,
|
||||
label: msg`See workflow`,
|
||||
shortLabel: msg`See workflow`,
|
||||
position: 0,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconSettingsAutomation,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeWorkflowWorkflowRunSingleRecordAction,
|
||||
export const WORKFLOW_RUNS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
config: {
|
||||
[WorkflowRunSingleRecordActionKeys.SEE_WORKFLOW]: {
|
||||
key: WorkflowRunSingleRecordActionKeys.SEE_WORKFLOW,
|
||||
label: msg`See workflow`,
|
||||
shortLabel: msg`See workflow`,
|
||||
position: 0,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconSettingsAutomation,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeWorkflowWorkflowRunSingleRecordAction,
|
||||
},
|
||||
[WorkflowRunSingleRecordActionKeys.SEE_VERSION]: {
|
||||
key: WorkflowRunSingleRecordActionKeys.SEE_VERSION,
|
||||
label: msg`See version`,
|
||||
shortLabel: msg`See version`,
|
||||
position: 1,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconVersions,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeVersionWorkflowRunSingleRecordAction,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_WORKFLOWS]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_WORKFLOWS,
|
||||
label: msg`Go to workflows`,
|
||||
shortLabel: msg`See workflows`,
|
||||
position: 11,
|
||||
Icon: IconSettingsAutomation,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeWorkflowsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'W'],
|
||||
},
|
||||
},
|
||||
seeVersionSingleRecord: {
|
||||
key: WorkflowRunSingleRecordActionKeys.SEE_VERSION,
|
||||
label: msg`See version`,
|
||||
shortLabel: msg`See version`,
|
||||
position: 1,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconVersions,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeVersionWorkflowRunSingleRecordAction,
|
||||
actionKeys: [
|
||||
SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
SingleRecordActionKeys.EXPORT,
|
||||
MultipleRecordsActionKeys.EXPORT,
|
||||
NoSelectionRecordActionKeys.EXPORT_VIEW,
|
||||
NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
],
|
||||
propertiesToOverwrite: {
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
isPinned: false,
|
||||
position: 2,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
isPinned: false,
|
||||
position: 3,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT]: {
|
||||
position: 4,
|
||||
label: msg`Export run`,
|
||||
},
|
||||
[MultipleRecordsActionKeys.EXPORT]: {
|
||||
position: 5,
|
||||
label: msg`Export runs`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.EXPORT_VIEW]: {
|
||||
position: 6,
|
||||
label: msg`Export view`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.SEE_DELETED_RECORDS]: {
|
||||
position: 7,
|
||||
label: msg`See deleted runs`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: {
|
||||
position: 8,
|
||||
label: msg`Hide deleted runs`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
position: 9,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
position: 10,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_PEOPLE]: {
|
||||
position: 12,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 13,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
position: 14,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
position: 15,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
position: 16,
|
||||
},
|
||||
},
|
||||
addToFavoritesSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
label: msg`Add to favorites`,
|
||||
shortLabel: msg`Add to favorites`,
|
||||
position: 2,
|
||||
isPinned: false,
|
||||
Icon: IconHeart,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useAddToFavoritesSingleRecordAction,
|
||||
},
|
||||
removeFromFavoritesSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
label: msg`Remove from favorites`,
|
||||
shortLabel: msg`Remove from favorites`,
|
||||
isPinned: false,
|
||||
position: 3,
|
||||
Icon: IconHeartOff,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useRemoveFromFavoritesSingleRecordAction,
|
||||
},
|
||||
navigateToPreviousRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
label: msg`Navigate to previous run`,
|
||||
position: 4,
|
||||
isPinned: true,
|
||||
Icon: IconChevronUp,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useNavigateToPreviousRecordSingleRecordAction,
|
||||
},
|
||||
navigateToNextRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
label: msg`Navigate to next run`,
|
||||
position: 5,
|
||||
isPinned: true,
|
||||
Icon: IconChevronDown,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useNavigateToNextRecordSingleRecordAction,
|
||||
},
|
||||
exportSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT,
|
||||
label: msg`Export run`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 6,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
exportMultipleRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.EXPORT,
|
||||
label: msg`Export runs`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 7,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
exportView: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.EXPORT_VIEW,
|
||||
label: msg`Export view`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 8,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
seeDeletedRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
label: msg`See deleted runs`,
|
||||
shortLabel: msg`Deleted runs`,
|
||||
position: 9,
|
||||
Icon: IconRotate2,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
hideDeletedRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
label: msg`Hide deleted runs`,
|
||||
shortLabel: msg`Hide deleted`,
|
||||
position: 10,
|
||||
Icon: IconEyeOff,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useHideDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
seeAllWorkflows: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_WORKFLOWS,
|
||||
label: msg`Go to workflows`,
|
||||
shortLabel: msg`See workflows`,
|
||||
position: 11,
|
||||
Icon: IconSettingsAutomation,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeWorkflowsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'W'],
|
||||
},
|
||||
goToPeople: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
label: msg`Go to People`,
|
||||
shortLabel: msg`People`,
|
||||
position: 12,
|
||||
Icon: IconUser,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToPeopleNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'P'],
|
||||
},
|
||||
goToCompanies: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
label: msg`Go to Companies`,
|
||||
shortLabel: msg`Companies`,
|
||||
position: 13,
|
||||
Icon: IconBuildingSkyscraper,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToCompaniesNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'C'],
|
||||
},
|
||||
goToOpportunities: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
label: msg`Go to Opportunities`,
|
||||
shortLabel: msg`Opportunities`,
|
||||
position: 14,
|
||||
Icon: IconTargetArrow,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToOpportunitiesNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'O'],
|
||||
},
|
||||
goToSettings: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
label: msg`Go to Settings`,
|
||||
shortLabel: msg`Settings`,
|
||||
position: 15,
|
||||
Icon: IconSettings,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToSettingsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'S'],
|
||||
},
|
||||
goToTasks: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
label: msg`Go to Tasks`,
|
||||
shortLabel: msg`Tasks`,
|
||||
position: 16,
|
||||
Icon: IconCheckbox,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToTasksNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'T'],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@ -1,350 +1,194 @@
|
||||
import { useExportMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction';
|
||||
import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys';
|
||||
import { useGoToCompaniesNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToCompaniesNoSelectionRecordAction';
|
||||
import { useGoToOpportunitiesNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToOpportunitiesNoSelectionRecordAction';
|
||||
import { useGoToPeopleNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToPeopleNoSelectionRecordAction';
|
||||
import { useGoToSettingsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToSettingsNoSelectionRecordAction';
|
||||
import { useGoToTasksNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useGoToTasksNoSelectionRecordAction';
|
||||
import { useHideDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useHideDeletedRecordsNoSelectionRecordAction';
|
||||
import { useSeeDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeDeletedRecordsNoSelectionRecordAction';
|
||||
import { useSeeRunsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeRunsNoSelectionRecordAction';
|
||||
import { useSeeWorkflowsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useSeeWorkflowsNoSelectionRecordAction';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKey';
|
||||
import { useAddToFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction';
|
||||
import { useNavigateToNextRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction';
|
||||
import { useNavigateToPreviousRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction';
|
||||
import { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { NoSelectionWorkflowRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/workflow-actions/types/NoSelectionWorkflowRecordActionsKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { useSeeRunsWorkflowVersionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeRunsWorkflowVersionSingleRecordAction';
|
||||
import { useSeeVersionsWorkflowVersionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeVersionsWorkflowVersionSingleRecordAction';
|
||||
import { useSeeWorkflowWorkflowVersionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeWorkflowWorkflowVersionSingleRecordAction';
|
||||
import { useUseAsDraftWorkflowVersionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useUseAsDraftWorkflowVersionSingleRecordAction';
|
||||
import { WorkflowVersionSingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/types/WorkflowVersionSingleRecordActionsKeys';
|
||||
import { ActionHook } from '@/action-menu/actions/types/ActionHook';
|
||||
import { inheritActionsFromDefaultConfig } from '@/action-menu/actions/record-actions/utils/inheritActionsFromDefaultConfig';
|
||||
import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import {
|
||||
ActionMenuEntry,
|
||||
ActionMenuEntryScope,
|
||||
ActionMenuEntryType,
|
||||
} from '@/action-menu/types/ActionMenuEntry';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconBuildingSkyscraper,
|
||||
IconCheckbox,
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconDatabaseExport,
|
||||
IconEyeOff,
|
||||
IconHeart,
|
||||
IconHeartOff,
|
||||
IconHistoryToggle,
|
||||
IconPencil,
|
||||
IconRotate2,
|
||||
IconSettings,
|
||||
IconSettingsAutomation,
|
||||
IconTargetArrow,
|
||||
IconUser,
|
||||
IconVersions,
|
||||
} from 'twenty-ui';
|
||||
|
||||
export const WORKFLOW_VERSIONS_ACTIONS_CONFIG: Record<
|
||||
string,
|
||||
ActionMenuEntry & {
|
||||
useAction: ActionHook;
|
||||
}
|
||||
> = {
|
||||
useAsDraftWorkflowVersionSingleRecord: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.USE_AS_DRAFT,
|
||||
label: msg`Use as draft`,
|
||||
shortLabel: msg`Use as draft`,
|
||||
position: 1,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconPencil,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
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`,
|
||||
position: 1,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconPencil,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord) && selectedRecord.status !== 'DRAFT',
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useUseAsDraftWorkflowVersionSingleRecordAction,
|
||||
},
|
||||
[WorkflowVersionSingleRecordActionKeys.SEE_WORKFLOW]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_WORKFLOW,
|
||||
label: msg`See workflow`,
|
||||
shortLabel: msg`See workflow`,
|
||||
position: 2,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconSettingsAutomation,
|
||||
shouldBeRegistered: ({ selectedRecord }) =>
|
||||
isDefined(selectedRecord?.workflow?.id),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeWorkflowWorkflowVersionSingleRecordAction,
|
||||
},
|
||||
[WorkflowVersionSingleRecordActionKeys.SEE_RUNS]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_RUNS,
|
||||
label: msg`See runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
position: 3,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconHistoryToggle,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeRunsWorkflowVersionSingleRecordAction,
|
||||
},
|
||||
[WorkflowVersionSingleRecordActionKeys.SEE_VERSIONS]: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_VERSIONS,
|
||||
label: msg`See versions history`,
|
||||
shortLabel: msg`See versions`,
|
||||
position: 4,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconVersions,
|
||||
shouldBeRegistered: ({ workflowWithCurrentVersion }) =>
|
||||
isDefined(workflowWithCurrentVersion),
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeVersionsWorkflowVersionSingleRecordAction,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_WORKFLOWS]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_WORKFLOWS,
|
||||
label: msg`Go to workflows`,
|
||||
shortLabel: msg`See workflows`,
|
||||
position: 14,
|
||||
Icon: IconSettingsAutomation,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeWorkflowsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'W'],
|
||||
},
|
||||
[NoSelectionWorkflowRecordActionKeys.GO_TO_RUNS]: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionWorkflowRecordActionKeys.GO_TO_RUNS,
|
||||
label: msg`Go to runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
position: 15,
|
||||
Icon: IconHistoryToggle,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
shouldBeRegistered: () => true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeRunsNoSelectionRecordAction,
|
||||
},
|
||||
},
|
||||
actionKeys: [
|
||||
SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
SingleRecordActionKeys.EXPORT,
|
||||
MultipleRecordsActionKeys.EXPORT,
|
||||
NoSelectionRecordActionKeys.EXPORT_VIEW,
|
||||
NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
],
|
||||
useAction: useUseAsDraftWorkflowVersionSingleRecordAction,
|
||||
propertiesToOverwrite: {
|
||||
[SingleRecordActionKeys.ADD_TO_FAVORITES]: {
|
||||
position: 5,
|
||||
isPinned: false,
|
||||
},
|
||||
[SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: {
|
||||
position: 6,
|
||||
isPinned: false,
|
||||
},
|
||||
[SingleRecordActionKeys.EXPORT]: {
|
||||
position: 7,
|
||||
label: msg`Export version`,
|
||||
},
|
||||
[MultipleRecordsActionKeys.EXPORT]: {
|
||||
position: 8,
|
||||
label: msg`Export versions`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.EXPORT_VIEW]: {
|
||||
position: 9,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.SEE_DELETED_RECORDS]: {
|
||||
position: 10,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: {
|
||||
position: 11,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: {
|
||||
position: 12,
|
||||
label: msg`Navigate to previous version`,
|
||||
},
|
||||
[SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: {
|
||||
position: 13,
|
||||
label: msg`Navigate to next version`,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_PEOPLE]: {
|
||||
position: 16,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_COMPANIES]: {
|
||||
position: 17,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: {
|
||||
position: 18,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_SETTINGS]: {
|
||||
position: 19,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.GO_TO_TASKS]: {
|
||||
position: 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
seeWorkflowSingleRecord: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_WORKFLOW,
|
||||
label: msg`See workflow`,
|
||||
shortLabel: msg`See workflow`,
|
||||
position: 2,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconSettingsAutomation,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeWorkflowWorkflowVersionSingleRecordAction,
|
||||
},
|
||||
seeWorkflowRunsSingleRecord: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_RUNS,
|
||||
label: msg`See runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
position: 3,
|
||||
isPinned: true,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconHistoryToggle,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeRunsWorkflowVersionSingleRecordAction,
|
||||
},
|
||||
seeWorkflowVersionsHistorySingleRecord: {
|
||||
key: WorkflowVersionSingleRecordActionKeys.SEE_VERSIONS,
|
||||
label: msg`See versions history`,
|
||||
shortLabel: msg`See versions`,
|
||||
position: 4,
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
Icon: IconVersions,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useSeeVersionsWorkflowVersionSingleRecordAction,
|
||||
},
|
||||
navigateToPreviousRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
label: msg`Navigate to previous version`,
|
||||
position: 5,
|
||||
Icon: IconChevronUp,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useNavigateToPreviousRecordSingleRecordAction,
|
||||
},
|
||||
navigateToNextRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
label: msg`Navigate to next version`,
|
||||
position: 6,
|
||||
Icon: IconChevronDown,
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
useAction: useNavigateToNextRecordSingleRecordAction,
|
||||
},
|
||||
addToFavoritesSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
label: msg`Add to favorites`,
|
||||
shortLabel: msg`Add to favorites`,
|
||||
position: 7,
|
||||
isPinned: false,
|
||||
Icon: IconHeart,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useAddToFavoritesSingleRecordAction,
|
||||
},
|
||||
removeFromFavoritesSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
label: msg`Remove from favorites`,
|
||||
shortLabel: msg`Remove from favorites`,
|
||||
isPinned: false,
|
||||
position: 8,
|
||||
Icon: IconHeartOff,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useRemoveFromFavoritesSingleRecordAction,
|
||||
},
|
||||
exportSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT,
|
||||
label: msg`Export version`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 9,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
exportMultipleRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.EXPORT,
|
||||
label: msg`Export versions`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 10,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
exportView: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.EXPORT_VIEW,
|
||||
label: msg`Export view`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 11,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
seeDeletedRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
label: msg`See deleted versions`,
|
||||
shortLabel: msg`Deleted versions`,
|
||||
position: 12,
|
||||
Icon: IconRotate2,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
hideDeletedRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
label: msg`Hide deleted versions`,
|
||||
shortLabel: msg`Hide deleted`,
|
||||
position: 13,
|
||||
Icon: IconEyeOff,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useHideDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
seeAllWorkflows: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_WORKFLOWS,
|
||||
label: msg`Go to workflows`,
|
||||
shortLabel: msg`See workflows`,
|
||||
position: 14,
|
||||
Icon: IconSettingsAutomation,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeWorkflowsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'W'],
|
||||
},
|
||||
seeAllRuns: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_RUNS,
|
||||
label: msg`Go to runs`,
|
||||
shortLabel: msg`See runs`,
|
||||
position: 15,
|
||||
Icon: IconHistoryToggle,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeRunsNoSelectionRecordAction,
|
||||
},
|
||||
goToPeople: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
label: msg`Go to People`,
|
||||
shortLabel: msg`People`,
|
||||
position: 16,
|
||||
Icon: IconUser,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToPeopleNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'P'],
|
||||
},
|
||||
goToCompanies: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
label: msg`Go to Companies`,
|
||||
shortLabel: msg`Companies`,
|
||||
position: 17,
|
||||
Icon: IconBuildingSkyscraper,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToCompaniesNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'C'],
|
||||
},
|
||||
goToOpportunities: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
label: msg`Go to Opportunities`,
|
||||
shortLabel: msg`Opportunities`,
|
||||
position: 18,
|
||||
Icon: IconTargetArrow,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToOpportunitiesNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'O'],
|
||||
},
|
||||
goToSettings: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
label: msg`Go to Settings`,
|
||||
shortLabel: msg`Settings`,
|
||||
position: 19,
|
||||
Icon: IconSettings,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToSettingsNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'S'],
|
||||
},
|
||||
goToTasks: {
|
||||
type: ActionMenuEntryType.Navigation,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
label: msg`Go to Tasks`,
|
||||
shortLabel: msg`Tasks`,
|
||||
position: 20,
|
||||
Icon: IconCheckbox,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
useAction: useGoToTasksNoSelectionRecordAction,
|
||||
hotKeys: ['G', 'T'],
|
||||
},
|
||||
};
|
||||
);
|
||||
|
||||
@ -75,8 +75,6 @@ const getWrapper = (
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const defaultWrapper = getWrapper();
|
||||
|
||||
describe('useDestroyMultipleRecordsAction', () => {
|
||||
it('should call destroyManyRecords on click if records are filtered by deletedAt', async () => {
|
||||
const { result } = renderHook(
|
||||
@ -121,24 +119,4 @@ describe('useDestroyMultipleRecordsAction', () => {
|
||||
expect(destroyManyRecordsMock).toHaveBeenCalledWith(expectedParams);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not call destroyManyRecords on click if records are not filtered by deletedAt', async () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useDestroyMultipleRecordsAction({
|
||||
objectMetadataItem: personMockObjectMetadataItem,
|
||||
}),
|
||||
{
|
||||
wrapper: defaultWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.ConfirmationModal?.props?.isOpen).toBeFalsy();
|
||||
|
||||
act(() => {
|
||||
result.current.onClick();
|
||||
});
|
||||
|
||||
expect(result.current.ConfirmationModal?.props?.isOpen).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,23 +2,18 @@ import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/Ac
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
|
||||
import { BACKEND_BATCH_REQUEST_MAX_COUNT } from '@/object-record/constants/BackendBatchRequestMaxCount';
|
||||
import { DEFAULT_QUERY_PAGE_SIZE } from '@/object-record/constants/DefaultQueryPageSize';
|
||||
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
|
||||
import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords';
|
||||
import { useCheckIsSoftDeleteFilter } from '@/object-record/record-filter/hooks/useCheckIsSoftDeleteFilter';
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useDeleteMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
({ objectMetadataItem }) => {
|
||||
@ -33,8 +28,6 @@ export const useDeleteMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
throw new Error('Current view ID is not defined');
|
||||
}
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem.namePlural,
|
||||
@ -46,10 +39,6 @@ export const useDeleteMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
);
|
||||
|
||||
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
@ -67,12 +56,6 @@ export const useDeleteMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
filterValueDependencies,
|
||||
);
|
||||
|
||||
const { checkIsSoftDeleteFilter } = useCheckIsSoftDeleteFilter();
|
||||
|
||||
const isDeletedFilterActive = contextStoreFilters.some(
|
||||
checkIsSoftDeleteFilter,
|
||||
);
|
||||
|
||||
const { fetchAllRecords: fetchAllRecordIds } = useLazyFetchAllRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
filter: graphqlFilter,
|
||||
@ -91,21 +74,7 @@ export const useDeleteMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
});
|
||||
}, [deleteManyRecords, fetchAllRecordIds, resetTableRowSelection]);
|
||||
|
||||
const isRemoteObject = objectMetadataItem.isRemote;
|
||||
|
||||
const shouldBeRegistered =
|
||||
!hasObjectReadOnlyPermission &&
|
||||
!isRemoteObject &&
|
||||
!isDeletedFilterActive &&
|
||||
isDefined(contextStoreNumberOfSelectedRecords) &&
|
||||
contextStoreNumberOfSelectedRecords < BACKEND_BATCH_REQUEST_MAX_COUNT &&
|
||||
contextStoreNumberOfSelectedRecords > 0;
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsDeleteRecordsModalOpen(true);
|
||||
};
|
||||
|
||||
@ -121,7 +90,6 @@ export const useDeleteMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
);
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
ConfirmationModal: confirmationModal,
|
||||
};
|
||||
|
||||
@ -2,23 +2,18 @@ import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/Ac
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
|
||||
import { BACKEND_BATCH_REQUEST_MAX_COUNT } from '@/object-record/constants/BackendBatchRequestMaxCount';
|
||||
import { DEFAULT_QUERY_PAGE_SIZE } from '@/object-record/constants/DefaultQueryPageSize';
|
||||
import { RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter';
|
||||
import { useDestroyManyRecords } from '@/object-record/hooks/useDestroyManyRecords';
|
||||
import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords';
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useDestroyMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
({ objectMetadataItem }) => {
|
||||
@ -40,16 +35,10 @@ export const useDestroyMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
),
|
||||
});
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const { destroyManyRecords } = useDestroyManyRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
);
|
||||
|
||||
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
@ -73,16 +62,6 @@ export const useDestroyMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
...deletedAtFilter,
|
||||
};
|
||||
|
||||
const deletedAtFieldMetadata = objectMetadataItem.fields.find(
|
||||
(field) => field.name === 'deletedAt',
|
||||
);
|
||||
|
||||
const isDeletedFilterActive = contextStoreFilters.some(
|
||||
(filter) =>
|
||||
filter.fieldMetadataId === deletedAtFieldMetadata?.id &&
|
||||
filter.operand === RecordFilterOperand.IsNotEmpty,
|
||||
);
|
||||
|
||||
const { fetchAllRecords: fetchAllRecordIds } = useLazyFetchAllRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
filter: graphqlFilter,
|
||||
@ -99,21 +78,7 @@ export const useDestroyMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
await destroyManyRecords({ recordIdsToDestroy });
|
||||
}, [destroyManyRecords, fetchAllRecordIds, resetTableRowSelection]);
|
||||
|
||||
const isRemoteObject = objectMetadataItem.isRemote;
|
||||
|
||||
const shouldBeRegistered =
|
||||
!hasObjectReadOnlyPermission &&
|
||||
!isRemoteObject &&
|
||||
isDeletedFilterActive &&
|
||||
isDefined(contextStoreNumberOfSelectedRecords) &&
|
||||
contextStoreNumberOfSelectedRecords < BACKEND_BATCH_REQUEST_MAX_COUNT &&
|
||||
contextStoreNumberOfSelectedRecords > 0;
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsDestroyRecordsModalOpen(true);
|
||||
};
|
||||
|
||||
@ -131,7 +96,6 @@ export const useDestroyMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
);
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
ConfirmationModal: confirmationModal,
|
||||
};
|
||||
|
||||
@ -33,7 +33,6 @@ export const useExportMultipleRecordsAction = ({
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered: true,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -3,22 +3,17 @@ import { useCallback, useState } from 'react';
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
|
||||
import { BACKEND_BATCH_REQUEST_MAX_COUNT } from '@/object-record/constants/BackendBatchRequestMaxCount';
|
||||
import { DEFAULT_QUERY_PAGE_SIZE } from '@/object-record/constants/DefaultQueryPageSize';
|
||||
import { RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter';
|
||||
import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords';
|
||||
import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords';
|
||||
import { useCheckIsSoftDeleteFilter } from '@/object-record/record-filter/hooks/useCheckIsSoftDeleteFilter';
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useRestoreMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
({ objectMetadataItem }) => {
|
||||
@ -33,8 +28,6 @@ export const useRestoreMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
throw new Error('Current view ID is not defined');
|
||||
}
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem.namePlural,
|
||||
@ -46,10 +39,6 @@ export const useRestoreMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
);
|
||||
|
||||
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
@ -74,12 +63,6 @@ export const useRestoreMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
...deletedAtFilter,
|
||||
};
|
||||
|
||||
const { checkIsSoftDeleteFilter } = useCheckIsSoftDeleteFilter();
|
||||
|
||||
const isDeletedFilterActive = contextStoreFilters.some(
|
||||
checkIsSoftDeleteFilter,
|
||||
);
|
||||
|
||||
const { fetchAllRecords: fetchAllRecordIds } = useLazyFetchAllRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
filter: graphqlFilter,
|
||||
@ -98,21 +81,7 @@ export const useRestoreMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
});
|
||||
}, [restoreManyRecords, fetchAllRecordIds, resetTableRowSelection]);
|
||||
|
||||
const isRemoteObject = objectMetadataItem.isRemote;
|
||||
|
||||
const shouldBeRegistered =
|
||||
!hasObjectReadOnlyPermission &&
|
||||
!isRemoteObject &&
|
||||
isDeletedFilterActive &&
|
||||
isDefined(contextStoreNumberOfSelectedRecords) &&
|
||||
contextStoreNumberOfSelectedRecords < BACKEND_BATCH_REQUEST_MAX_COUNT &&
|
||||
contextStoreNumberOfSelectedRecords > 0;
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsRestoreRecordsModalOpen(true);
|
||||
};
|
||||
|
||||
@ -128,7 +97,6 @@ export const useRestoreMultipleRecordsAction: ActionHookWithObjectMetadataItem =
|
||||
);
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
ConfirmationModal: confirmationModal,
|
||||
};
|
||||
|
||||
@ -1,27 +1,13 @@
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { useCreateNewIndexRecord } from '@/object-record/record-table/hooks/useCreateNewIndexRecord';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
export const useCreateNewTableRecordNoSelectionRecordAction: ActionHookWithObjectMetadataItem =
|
||||
({ objectMetadataItem }) => {
|
||||
const currentViewId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
);
|
||||
|
||||
if (!currentViewId) {
|
||||
throw new Error('Current view ID is not defined');
|
||||
}
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const { createNewIndexRecord } = useCreateNewIndexRecord({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
return {
|
||||
shouldBeRegistered: !hasObjectReadOnlyPermission,
|
||||
onClick: createNewIndexRecord,
|
||||
};
|
||||
};
|
||||
|
||||
@ -7,8 +7,6 @@ export const useGoToCompaniesNoSelectionRecordAction: ActionHookWithoutObjectMet
|
||||
() => {
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = true;
|
||||
|
||||
const onClick = () => {
|
||||
navigateApp(AppPath.RecordIndexPage, {
|
||||
objectNamePlural: CoreObjectNamePlural.Company,
|
||||
@ -16,7 +14,6 @@ export const useGoToCompaniesNoSelectionRecordAction: ActionHookWithoutObjectMet
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -7,8 +7,6 @@ export const useGoToOpportunitiesNoSelectionRecordAction: ActionHookWithoutObjec
|
||||
() => {
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = true;
|
||||
|
||||
const onClick = () => {
|
||||
navigateApp(AppPath.RecordIndexPage, {
|
||||
objectNamePlural: CoreObjectNamePlural.Opportunity,
|
||||
@ -16,7 +14,6 @@ export const useGoToOpportunitiesNoSelectionRecordAction: ActionHookWithoutObjec
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -7,8 +7,6 @@ export const useGoToPeopleNoSelectionRecordAction: ActionHookWithoutObjectMetada
|
||||
() => {
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = true;
|
||||
|
||||
const onClick = () => {
|
||||
navigateApp(AppPath.RecordIndexPage, {
|
||||
objectNamePlural: CoreObjectNamePlural.Person,
|
||||
@ -16,7 +14,6 @@ export const useGoToPeopleNoSelectionRecordAction: ActionHookWithoutObjectMetada
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -6,14 +6,11 @@ export const useGoToSettingsNoSelectionRecordAction: ActionHookWithoutObjectMeta
|
||||
() => {
|
||||
const navigateSettings = useNavigateSettings();
|
||||
|
||||
const shouldBeRegistered = true;
|
||||
|
||||
const onClick = () => {
|
||||
navigateSettings(SettingsPath.ProfilePage);
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -7,8 +7,6 @@ export const useGoToTasksNoSelectionRecordAction: ActionHookWithoutObjectMetadat
|
||||
() => {
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = true;
|
||||
|
||||
const onClick = () => {
|
||||
navigateApp(AppPath.RecordIndexPage, {
|
||||
objectNamePlural: CoreObjectNamePlural.Task,
|
||||
@ -16,7 +14,6 @@ export const useGoToTasksNoSelectionRecordAction: ActionHookWithoutObjectMetadat
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -52,7 +52,6 @@ export const useHideDeletedRecordsNoSelectionRecordAction: ActionHookWithObjectM
|
||||
}, [deletedFilter, removeRecordFilter, toggleSoftDeleteFilterState]);
|
||||
|
||||
return {
|
||||
shouldBeRegistered: isDefined(deletedFilter),
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -9,9 +9,6 @@ export const useImportRecordsNoSelectionRecordAction: ActionHookWithObjectMetada
|
||||
);
|
||||
|
||||
return {
|
||||
shouldBeRegistered: true,
|
||||
onClick: () => {
|
||||
openObjectRecordsSpreadsheetImportDialog();
|
||||
},
|
||||
onClick: openObjectRecordsSpreadsheetImportDialog,
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,8 +2,6 @@ import { useCallback } from 'react';
|
||||
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { useCheckIsSoftDeleteFilter } from '@/object-record/record-filter/hooks/useCheckIsSoftDeleteFilter';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { useHandleToggleTrashColumnFilter } from '@/object-record/record-index/hooks/useHandleToggleTrashColumnFilter';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
@ -29,24 +27,12 @@ export const useSeeDeletedRecordsNoSelectionRecordAction: ActionHookWithObjectMe
|
||||
viewBarId: recordIndexId,
|
||||
});
|
||||
|
||||
const { checkIsSoftDeleteFilter } = useCheckIsSoftDeleteFilter();
|
||||
|
||||
const currentRecordFilters = useRecoilComponentValueV2(
|
||||
currentRecordFiltersComponentState,
|
||||
recordIndexId,
|
||||
);
|
||||
|
||||
const isDeletedFilterActive = currentRecordFilters.some(
|
||||
checkIsSoftDeleteFilter,
|
||||
);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
handleToggleTrashColumnFilter();
|
||||
toggleSoftDeleteFilterState(true);
|
||||
}, [handleToggleTrashColumnFilter, toggleSoftDeleteFilterState]);
|
||||
|
||||
return {
|
||||
shouldBeRegistered: !isDeletedFilterActive,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -7,8 +7,6 @@ export const useSeeRunsNoSelectionRecordAction: ActionHookWithoutObjectMetadataI
|
||||
() => {
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = true;
|
||||
|
||||
const onClick = () => {
|
||||
navigateApp(AppPath.RecordIndexPage, {
|
||||
objectNamePlural: CoreObjectNamePlural.WorkflowRun,
|
||||
@ -16,7 +14,6 @@ export const useSeeRunsNoSelectionRecordAction: ActionHookWithoutObjectMetadataI
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,20 +1,12 @@
|
||||
import { ActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
export const useSeeWorkflowsNoSelectionRecordAction: ActionHookWithoutObjectMetadataItem =
|
||||
() => {
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const isWorkflowsEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IsWorkflowEnabled,
|
||||
);
|
||||
|
||||
const shouldBeRegistered = isWorkflowsEnabled;
|
||||
|
||||
const onClick = () => {
|
||||
navigateApp(AppPath.RecordIndexPage, {
|
||||
objectNamePlural: CoreObjectNamePlural.Workflow,
|
||||
@ -22,7 +14,6 @@ export const useSeeWorkflowsNoSelectionRecordAction: ActionHookWithoutObjectMeta
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -4,7 +4,6 @@ export enum NoSelectionRecordActionKeys {
|
||||
SEE_DELETED_RECORDS = 'see-deleted-records',
|
||||
HIDE_DELETED_RECORDS = 'hide-deleted-records',
|
||||
IMPORT_RECORDS = 'import-records',
|
||||
GO_TO_RUNS = 'go-to-runs',
|
||||
GO_TO_WORKFLOWS = 'go-to-workflows',
|
||||
GO_TO_PEOPLE = 'go-to-people',
|
||||
GO_TO_COMPANIES = 'go-to-companies',
|
||||
@ -0,0 +1,3 @@
|
||||
export enum NoSelectionWorkflowRecordActionKeys {
|
||||
GO_TO_RUNS = 'go-to-runs',
|
||||
}
|
||||
@ -70,45 +70,12 @@ const wrapperConfigWithSelectedRecordNotAsFavorite: GetJestMetadataAndApolloMock
|
||||
},
|
||||
};
|
||||
|
||||
const wrapperWithSelectedRecordAsFavorite =
|
||||
getJestMetadataAndApolloMocksAndActionMenuWrapper(
|
||||
wrapperConfigWithSelectedRecordAsFavorite,
|
||||
);
|
||||
|
||||
const wrapperWithSelectedRecordNotAsFavorite =
|
||||
getJestMetadataAndApolloMocksAndActionMenuWrapper(
|
||||
wrapperConfigWithSelectedRecordNotAsFavorite,
|
||||
);
|
||||
|
||||
describe('useAddToFavoritesSingleRecordAction', () => {
|
||||
it('should be registered when the record is not a favorite', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useAddToFavoritesSingleRecordAction({
|
||||
objectMetadataItem: personMockObjectMetadataItem,
|
||||
}),
|
||||
{
|
||||
wrapper: wrapperWithSelectedRecordNotAsFavorite,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(true);
|
||||
});
|
||||
|
||||
it('should not be registered when the record is a favorite', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useAddToFavoritesSingleRecordAction({
|
||||
objectMetadataItem: personMockObjectMetadataItem,
|
||||
}),
|
||||
{
|
||||
wrapper: wrapperWithSelectedRecordAsFavorite,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should call createFavorite on click', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
|
||||
@ -61,60 +61,15 @@ const wrapperConfigWithSelectedRecordAsFavorite: GetJestMetadataAndApolloMocksAn
|
||||
},
|
||||
};
|
||||
|
||||
const wrapperConfigWithSelectedRecordNotAsFavorite: GetJestMetadataAndApolloMocksAndActionMenuWrapperProps =
|
||||
{
|
||||
...wrapperConfigWithSelectedRecordAsFavorite,
|
||||
contextStoreTargetedRecordsRule: {
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [peopleMock[1].id],
|
||||
},
|
||||
};
|
||||
|
||||
const wrapperWithSelectedRecordAsFavorite =
|
||||
getJestMetadataAndApolloMocksAndActionMenuWrapper(
|
||||
wrapperConfigWithSelectedRecordAsFavorite,
|
||||
);
|
||||
|
||||
const wrapperWithSelectedRecordNotAsFavorite =
|
||||
getJestMetadataAndApolloMocksAndActionMenuWrapper(
|
||||
wrapperConfigWithSelectedRecordNotAsFavorite,
|
||||
);
|
||||
|
||||
describe('useRemoveFromFavoritesSingleRecordAction', () => {
|
||||
it('should be registered when the record is a favorite', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useRemoveFromFavoritesSingleRecordAction({
|
||||
objectMetadataItem: personMockObjectMetadataItem,
|
||||
}),
|
||||
{
|
||||
wrapper: wrapperWithSelectedRecordAsFavorite,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(true);
|
||||
});
|
||||
|
||||
it('should not be registered when the record is not a favorite', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useRemoveFromFavoritesSingleRecordAction({
|
||||
objectMetadataItem: personMockObjectMetadataItem,
|
||||
}),
|
||||
{
|
||||
wrapper: wrapperWithSelectedRecordNotAsFavorite,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should call deleteFavorite on click', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useRemoveFromFavoritesSingleRecordAction({
|
||||
objectMetadataItem: personMockObjectMetadataItem,
|
||||
}),
|
||||
() => useRemoveFromFavoritesSingleRecordAction(),
|
||||
{
|
||||
wrapper: wrapperWithSelectedRecordAsFavorite,
|
||||
},
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite';
|
||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { isNull } from '@sniptt/guards';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@ -11,27 +9,12 @@ export const useAddToFavoritesSingleRecordAction: ActionHookWithObjectMetadataIt
|
||||
({ objectMetadataItem }) => {
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const { sortedFavorites: favorites } = useFavorites();
|
||||
|
||||
const { createFavorite } = useCreateFavorite();
|
||||
|
||||
const selectedRecord = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
|
||||
const foundFavorite = favorites?.find(
|
||||
(favorite) => favorite.recordId === recordId,
|
||||
);
|
||||
|
||||
const isFavorite = !!foundFavorite;
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(objectMetadataItem) &&
|
||||
isDefined(selectedRecord) &&
|
||||
!objectMetadataItem.isRemote &&
|
||||
!isFavorite &&
|
||||
isNull(selectedRecord.deletedAt);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
if (!isDefined(selectedRecord)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -39,7 +22,6 @@ export const useAddToFavoritesSingleRecordAction: ActionHookWithObjectMetadataIt
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -3,14 +3,10 @@ import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/Ac
|
||||
import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite';
|
||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isNull } from '@sniptt/guards';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useDeleteSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
@ -21,8 +17,6 @@ export const useDeleteSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
const [isDeleteRecordsModalOpen, setIsDeleteRecordsModalOpen] =
|
||||
useState(false);
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: objectMetadataItem.namePlural,
|
||||
});
|
||||
@ -31,8 +25,6 @@ export const useDeleteSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const selectedRecord = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
|
||||
const { sortedFavorites: favorites } = useFavorites();
|
||||
const { deleteFavorite } = useDeleteFavorite();
|
||||
|
||||
@ -56,23 +48,11 @@ export const useDeleteSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
recordId,
|
||||
]);
|
||||
|
||||
const isRemoteObject = objectMetadataItem.isRemote;
|
||||
|
||||
const shouldBeRegistered =
|
||||
!isRemoteObject &&
|
||||
isNull(selectedRecord?.deletedAt) &&
|
||||
!hasObjectReadOnlyPermission;
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsDeleteRecordsModalOpen(true);
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
ConfirmationModal: (
|
||||
<ConfirmationModal
|
||||
|
||||
@ -1,15 +1,11 @@
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { useDestroyOneRecord } from '@/object-record/hooks/useDestroyOneRecord';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useDestroySingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
objectMetadataItem,
|
||||
@ -19,8 +15,6 @@ export const useDestroySingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
const [isDestroyRecordsModalOpen, setIsDestroyRecordsModalOpen] =
|
||||
useState(false);
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
@ -31,8 +25,6 @@ export const useDestroySingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const selectedRecord = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
|
||||
const handleDeleteClick = useCallback(async () => {
|
||||
resetTableRowSelection();
|
||||
|
||||
@ -48,23 +40,11 @@ export const useDestroySingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
objectMetadataItem.namePlural,
|
||||
]);
|
||||
|
||||
const isRemoteObject = objectMetadataItem.isRemote;
|
||||
|
||||
const shouldBeRegistered =
|
||||
!hasObjectReadOnlyPermission &&
|
||||
!isRemoteObject &&
|
||||
isDefined(selectedRecord?.deletedAt);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsDestroyRecordsModalOpen(true);
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
ConfirmationModal: (
|
||||
<ConfirmationModal
|
||||
|
||||
@ -1,33 +1,19 @@
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { BlockNoteEditor } from '@blocknote/core';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useExportNoteAction: ActionHookWithObjectMetadataItem = ({
|
||||
objectMetadataItem,
|
||||
}) => {
|
||||
export const useExportNoteAction: ActionHookWithoutObjectMetadataItem = () => {
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const selectedRecord = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
|
||||
const filename = `${(selectedRecord?.title || 'Untitled Note').replace(/[<>:"/\\|?*]/g, '-')}`;
|
||||
|
||||
const isNoteOrTask =
|
||||
objectMetadataItem?.nameSingular === CoreObjectNameSingular.Note ||
|
||||
objectMetadataItem?.nameSingular === CoreObjectNameSingular.Task;
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(objectMetadataItem) &&
|
||||
isDefined(selectedRecord) &&
|
||||
isNoteOrTask &&
|
||||
isNonEmptyString(selectedRecord.bodyV2?.blocknote);
|
||||
|
||||
const onClick = async () => {
|
||||
if (!shouldBeRegistered || !selectedRecord.bodyV2.blocknote) {
|
||||
if (!isDefined(selectedRecord)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -65,7 +51,6 @@ export const useExportNoteAction: ActionHookWithObjectMetadataItem = ({
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,22 +1,17 @@
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export const useNavigateToNextRecordSingleRecordAction: ActionHookWithObjectMetadataItem =
|
||||
({ objectMetadataItem }) => {
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const { isInRightDrawer } = useContext(ActionMenuContext);
|
||||
|
||||
const { navigateToNextRecord } = useRecordShowPagePagination(
|
||||
objectMetadataItem.nameSingular,
|
||||
recordId,
|
||||
);
|
||||
|
||||
return {
|
||||
shouldBeRegistered: !isInRightDrawer,
|
||||
onClick: navigateToNextRecord,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,22 +1,17 @@
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export const useNavigateToPreviousRecordSingleRecordAction: ActionHookWithObjectMetadataItem =
|
||||
({ objectMetadataItem }) => {
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const { isInRightDrawer } = useContext(ActionMenuContext);
|
||||
|
||||
const { navigateToPreviousRecord } = useRecordShowPagePagination(
|
||||
objectMetadataItem.nameSingular,
|
||||
recordId,
|
||||
);
|
||||
|
||||
return {
|
||||
shouldBeRegistered: !isInRightDrawer,
|
||||
onClick: navigateToPreviousRecord,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { ActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite';
|
||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useRemoveFromFavoritesSingleRecordAction: ActionHookWithObjectMetadataItem =
|
||||
({ objectMetadataItem }) => {
|
||||
export const useRemoveFromFavoritesSingleRecordAction: ActionHookWithoutObjectMetadataItem =
|
||||
() => {
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const { sortedFavorites: favorites } = useFavorites();
|
||||
@ -16,15 +16,8 @@ export const useRemoveFromFavoritesSingleRecordAction: ActionHookWithObjectMetad
|
||||
(favorite) => favorite.recordId === recordId,
|
||||
);
|
||||
|
||||
const isFavorite = !!foundFavorite;
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(objectMetadataItem) &&
|
||||
!objectMetadataItem.isRemote &&
|
||||
isFavorite;
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
if (!isDefined(foundFavorite)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -32,7 +25,6 @@ export const useRemoveFromFavoritesSingleRecordAction: ActionHookWithObjectMetad
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,17 +1,9 @@
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useRestoreSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
objectMetadataItem,
|
||||
@ -21,8 +13,6 @@ export const useRestoreSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
const [isRestoreRecordModalOpen, setIsRestoreRecordModalOpen] =
|
||||
useState(false);
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: objectMetadataItem.namePlural,
|
||||
});
|
||||
@ -31,8 +21,6 @@ export const useRestoreSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const selectedRecord = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
|
||||
const handleRestoreClick = useCallback(async () => {
|
||||
resetTableRowSelection();
|
||||
|
||||
@ -41,27 +29,7 @@ export const useRestoreSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
});
|
||||
}, [restoreManyRecords, resetTableRowSelection, recordId]);
|
||||
|
||||
const isRemoteObject = objectMetadataItem.isRemote;
|
||||
|
||||
const isSoftDeleteFilterActive = useRecoilComponentValueV2(
|
||||
isSoftDeleteFilterActiveComponentState,
|
||||
);
|
||||
|
||||
const isShowPage =
|
||||
useRecoilComponentValueV2(contextStoreCurrentViewTypeComponentState) ===
|
||||
ContextStoreViewType.ShowPage;
|
||||
|
||||
const shouldBeRegistered =
|
||||
!isRemoteObject &&
|
||||
isDefined(selectedRecord?.deletedAt) &&
|
||||
!hasObjectReadOnlyPermission &&
|
||||
(isShowPage || isSoftDeleteFilterActive);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsRestoreRecordModalOpen(true);
|
||||
};
|
||||
|
||||
@ -70,7 +38,6 @@ export const useRestoreSingleRecordAction: ActionHookWithObjectMetadataItem = ({
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
ConfirmationModal: (
|
||||
<ConfirmationModal
|
||||
|
||||
@ -51,51 +51,6 @@ const draftWorkflowMock = {
|
||||
],
|
||||
};
|
||||
|
||||
const activeWorkflowMock = {
|
||||
...baseWorkflowMock,
|
||||
currentVersion: {
|
||||
...baseWorkflowMock.currentVersion,
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
versions: [
|
||||
{
|
||||
__typename: 'WorkflowVersion',
|
||||
id: 'currentVersionId',
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const noStepsWorkflowMock = {
|
||||
...baseWorkflowMock,
|
||||
currentVersion: {
|
||||
...baseWorkflowMock.currentVersion,
|
||||
steps: [],
|
||||
},
|
||||
versions: [
|
||||
{
|
||||
__typename: 'WorkflowVersion',
|
||||
id: 'currentVersionId',
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const noTriggerWorkflowMock = {
|
||||
...baseWorkflowMock,
|
||||
currentVersion: {
|
||||
...baseWorkflowMock.currentVersion,
|
||||
trigger: undefined,
|
||||
},
|
||||
versions: [
|
||||
{
|
||||
__typename: 'WorkflowVersion',
|
||||
id: 'currentVersionId',
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
jest.mock('@/workflow/hooks/useWorkflowWithCurrentVersion', () => ({
|
||||
useWorkflowWithCurrentVersion: jest.fn(),
|
||||
}));
|
||||
@ -138,66 +93,6 @@ describe('useActivateWorkflowSingleRecordAction', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be registered when workflow has trigger and steps and is not active', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockReturnValue(
|
||||
draftWorkflowMock,
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => useActivateWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: createWrapper(draftWorkflowMock),
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(true);
|
||||
});
|
||||
|
||||
it('should not be registered when workflow is already active', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockReturnValue(
|
||||
activeWorkflowMock,
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => useActivateWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: createWrapper(activeWorkflowMock),
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should not be registered when workflow has no steps', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockReturnValue(
|
||||
noStepsWorkflowMock,
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => useActivateWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: createWrapper(noStepsWorkflowMock),
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should not be registered when workflow has no trigger', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockReturnValue(
|
||||
noTriggerWorkflowMock,
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => useActivateWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: createWrapper(noTriggerWorkflowMock),
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should call activateWorkflowVersion on click', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockReturnValue(
|
||||
draftWorkflowMock,
|
||||
@ -219,23 +114,4 @@ describe('useActivateWorkflowSingleRecordAction', () => {
|
||||
workflowVersionId: draftWorkflowMock.currentVersion.id,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not call activateWorkflowVersion when not registered', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockReturnValue(
|
||||
activeWorkflowMock,
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => useActivateWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: createWrapper(activeWorkflowMock),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.onClick();
|
||||
});
|
||||
|
||||
expect(activateWorkflowVersionMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@ -37,24 +37,6 @@ const activeWorkflowMock = {
|
||||
},
|
||||
};
|
||||
|
||||
const deactivatedWorkflowMock = {
|
||||
__typename: 'Workflow',
|
||||
id: 'workflowId',
|
||||
lastPublishedVersionId: 'lastPublishedVersionId',
|
||||
currentVersion: {
|
||||
__typename: 'WorkflowVersion',
|
||||
id: 'currentVersionId',
|
||||
trigger: 'trigger',
|
||||
status: 'DEACTIVATED',
|
||||
steps: [
|
||||
{
|
||||
__typename: 'WorkflowStep',
|
||||
id: 'stepId1',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
jest.mock('@/workflow/hooks/useWorkflowWithCurrentVersion', () => ({
|
||||
useWorkflowWithCurrentVersion: jest.fn(),
|
||||
}));
|
||||
@ -90,61 +72,11 @@ const activeWorkflowWrapper = getJestMetadataAndApolloMocksAndActionMenuWrapper(
|
||||
},
|
||||
);
|
||||
|
||||
const deactivatedWorkflowWrapper =
|
||||
getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: '1',
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
workflowMockObjectMetadataItem.nameSingular,
|
||||
contextStoreTargetedRecordsRule: {
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [deactivatedWorkflowMock.id],
|
||||
},
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(
|
||||
recordStoreFamilyState(deactivatedWorkflowMock.id),
|
||||
deactivatedWorkflowMock,
|
||||
);
|
||||
snapshot.set(currentWorkspaceState, {
|
||||
...mockCurrentWorkspace,
|
||||
featureFlags: [mockedWorkflowEnabledFeatureFlag],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
describe('useDeactivateWorkflowSingleRecordAction', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should not be registered when the workflow is deactivated', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockImplementation(
|
||||
() => deactivatedWorkflowMock,
|
||||
);
|
||||
const { result } = renderHook(
|
||||
() => useDeactivateWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: deactivatedWorkflowWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should be registered when the workflow is active', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockImplementation(
|
||||
() => activeWorkflowMock,
|
||||
);
|
||||
const { result } = renderHook(
|
||||
() => useDeactivateWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: activeWorkflowWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(true);
|
||||
});
|
||||
|
||||
it('should call deactivateWorkflowVersion on click', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockImplementation(
|
||||
() => activeWorkflowMock,
|
||||
|
||||
@ -20,50 +20,6 @@ const mockedWorkflowEnabledFeatureFlag = {
|
||||
workspaceId: '1',
|
||||
};
|
||||
|
||||
const noDraftWorkflowMock = {
|
||||
__typename: 'Workflow',
|
||||
id: 'workflowId',
|
||||
lastPublishedVersionId: 'lastPublishedVersionId',
|
||||
currentVersion: {
|
||||
__typename: 'WorkflowVersion',
|
||||
id: 'currentVersionId',
|
||||
trigger: 'trigger',
|
||||
status: 'ACTIVE',
|
||||
steps: [
|
||||
{
|
||||
__typename: 'WorkflowStep',
|
||||
id: 'stepId1',
|
||||
},
|
||||
],
|
||||
},
|
||||
versions: [
|
||||
{
|
||||
__typename: 'WorkflowVersion',
|
||||
id: 'currentVersionId',
|
||||
trigger: 'trigger',
|
||||
status: 'ACTIVE',
|
||||
steps: [
|
||||
{
|
||||
__typename: 'WorkflowStep',
|
||||
id: 'stepId1',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
__typename: 'WorkflowVersion',
|
||||
id: 'versionId2',
|
||||
trigger: 'trigger',
|
||||
status: 'ACTIVE',
|
||||
steps: [
|
||||
{
|
||||
__typename: 'WorkflowStep',
|
||||
id: 'stepId2',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const draftWorkflowMock = {
|
||||
__typename: 'Workflow',
|
||||
id: 'workflowId',
|
||||
@ -108,11 +64,6 @@ const draftWorkflowMock = {
|
||||
],
|
||||
};
|
||||
|
||||
const draftWorkflowMockWithOneVersion = {
|
||||
...draftWorkflowMock,
|
||||
versions: [draftWorkflowMock.currentVersion],
|
||||
};
|
||||
|
||||
jest.mock('@/workflow/hooks/useWorkflowWithCurrentVersion', () => ({
|
||||
useWorkflowWithCurrentVersion: jest.fn(),
|
||||
}));
|
||||
@ -125,28 +76,6 @@ jest.mock('@/workflow/hooks/useDeleteOneWorkflowVersion', () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
const noDraftWorkflowWrapper =
|
||||
getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: '1',
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
workflowMockObjectMetadataItem.nameSingular,
|
||||
contextStoreTargetedRecordsRule: {
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [noDraftWorkflowMock.id],
|
||||
},
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(
|
||||
recordStoreFamilyState(noDraftWorkflowMock.id),
|
||||
noDraftWorkflowMock,
|
||||
);
|
||||
snapshot.set(currentWorkspaceState, {
|
||||
...mockCurrentWorkspace,
|
||||
featureFlags: [mockedWorkflowEnabledFeatureFlag],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const draftWorkflowWrapper = getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: '1',
|
||||
@ -168,76 +97,11 @@ const draftWorkflowWrapper = getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
},
|
||||
});
|
||||
|
||||
const draftWorkflowWithOneVersionWrapper =
|
||||
getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: '1',
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
workflowMockObjectMetadataItem.nameSingular,
|
||||
contextStoreTargetedRecordsRule: {
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [draftWorkflowMockWithOneVersion.id],
|
||||
},
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(
|
||||
recordStoreFamilyState(draftWorkflowMockWithOneVersion.id),
|
||||
draftWorkflowMockWithOneVersion,
|
||||
);
|
||||
snapshot.set(currentWorkspaceState, {
|
||||
...mockCurrentWorkspace,
|
||||
featureFlags: [mockedWorkflowEnabledFeatureFlag],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
describe('useDiscardDraftWorkflowSingleRecordAction', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should not be registered when there is no draft', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockImplementation(
|
||||
() => noDraftWorkflowMock,
|
||||
);
|
||||
const { result } = renderHook(
|
||||
() => useDiscardDraftWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: noDraftWorkflowWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should not be registered when there is only one version', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockImplementation(
|
||||
() => draftWorkflowMockWithOneVersion,
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => useDiscardDraftWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: draftWorkflowWithOneVersionWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should be registered when the workflow is draft', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockImplementation(
|
||||
() => draftWorkflowMock,
|
||||
);
|
||||
const { result } = renderHook(
|
||||
() => useDiscardDraftWorkflowSingleRecordAction(),
|
||||
{
|
||||
wrapper: draftWorkflowWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.shouldBeRegistered).toBe(true);
|
||||
});
|
||||
|
||||
it('should call deleteOneWorkflowVersion on click', () => {
|
||||
(useWorkflowWithCurrentVersion as jest.Mock).mockImplementation(
|
||||
() => draftWorkflowMock,
|
||||
|
||||
@ -12,17 +12,8 @@ export const useActivateWorkflowSingleRecordAction: ActionHookWithoutObjectMetad
|
||||
|
||||
const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(recordId);
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(workflowWithCurrentVersion?.currentVersion?.trigger) &&
|
||||
isDefined(workflowWithCurrentVersion.currentVersion?.steps) &&
|
||||
workflowWithCurrentVersion.currentVersion.steps.length > 0 &&
|
||||
(workflowWithCurrentVersion.currentVersion.status === 'DRAFT' ||
|
||||
!workflowWithCurrentVersion.versions?.some(
|
||||
(version) => version.status === 'ACTIVE',
|
||||
));
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
if (!isDefined(workflowWithCurrentVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -33,7 +24,6 @@ export const useActivateWorkflowSingleRecordAction: ActionHookWithoutObjectMetad
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -12,12 +12,8 @@ export const useDeactivateWorkflowSingleRecordAction: ActionHookWithoutObjectMet
|
||||
|
||||
const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(recordId);
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
workflowWithCurrentVersion.currentVersion.status === 'ACTIVE';
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
if (!isDefined(workflowWithCurrentVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -27,7 +23,6 @@ export const useDeactivateWorkflowSingleRecordAction: ActionHookWithoutObjectMet
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -12,13 +12,8 @@ export const useDiscardDraftWorkflowSingleRecordAction: ActionHookWithoutObjectM
|
||||
|
||||
const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(recordId);
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(workflowWithCurrentVersion) &&
|
||||
workflowWithCurrentVersion.versions.length > 1 &&
|
||||
workflowWithCurrentVersion.currentVersion.status === 'DRAFT';
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
if (!isDefined(workflowWithCurrentVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -28,7 +23,6 @@ export const useDiscardDraftWorkflowSingleRecordAction: ActionHookWithoutObjectM
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -3,26 +3,19 @@ import { ActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { useActiveWorkflowVersion } from '@/workflow/hooks/useActiveWorkflowVersion';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
export const useSeeActiveVersionWorkflowSingleRecordAction: ActionHookWithoutObjectMetadataItem =
|
||||
() => {
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const workflow = useWorkflowWithCurrentVersion(recordId);
|
||||
|
||||
const isDraft = workflow?.statuses?.includes('DRAFT') || false;
|
||||
|
||||
const workflowActiveVersion = useActiveWorkflowVersion(recordId);
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = isDefined(workflowActiveVersion) && isDraft;
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
if (!isDefined(workflowActiveVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -33,7 +26,6 @@ export const useSeeActiveVersionWorkflowSingleRecordAction: ActionHookWithoutObj
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -4,8 +4,8 @@ import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlur
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
export const useSeeRunsWorkflowSingleRecordAction: ActionHookWithoutObjectMetadataItem =
|
||||
() => {
|
||||
@ -15,10 +15,8 @@ export const useSeeRunsWorkflowSingleRecordAction: ActionHookWithoutObjectMetada
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = isDefined(workflowWithCurrentVersion);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
if (!isDefined(workflowWithCurrentVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -40,7 +38,6 @@ export const useSeeRunsWorkflowSingleRecordAction: ActionHookWithoutObjectMetada
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -4,8 +4,8 @@ import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlur
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
export const useSeeVersionsWorkflowSingleRecordAction: ActionHookWithoutObjectMetadataItem =
|
||||
() => {
|
||||
@ -15,10 +15,10 @@ export const useSeeVersionsWorkflowSingleRecordAction: ActionHookWithoutObjectMe
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = isDefined(workflowWithCurrentVersion);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) return;
|
||||
if (!isDefined(workflowWithCurrentVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigateApp(
|
||||
AppPath.RecordIndexPage,
|
||||
@ -38,7 +38,6 @@ export const useSeeVersionsWorkflowSingleRecordAction: ActionHookWithoutObjectMe
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -12,16 +12,8 @@ export const useTestWorkflowSingleRecordAction: ActionHookWithoutObjectMetadataI
|
||||
|
||||
const { runWorkflowVersion } = useRunWorkflowVersion();
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(workflowWithCurrentVersion?.currentVersion?.trigger) &&
|
||||
((workflowWithCurrentVersion.currentVersion.trigger.type === 'MANUAL' &&
|
||||
!isDefined(
|
||||
workflowWithCurrentVersion.currentVersion.trigger.settings.objectType,
|
||||
)) ||
|
||||
workflowWithCurrentVersion.currentVersion.trigger.type === 'WEBHOOK');
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) {
|
||||
if (!isDefined(workflowWithCurrentVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -31,7 +23,6 @@ export const useTestWorkflowSingleRecordAction: ActionHookWithoutObjectMetadataI
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -15,10 +15,13 @@ export const useSeeVersionWorkflowRunSingleRecordAction: ActionHookWithoutObject
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = isDefined(workflowRun?.workflowVersion?.id);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered || !workflowRun?.workflowVersion?.id) return;
|
||||
if (
|
||||
!isDefined(workflowRun) ||
|
||||
!isDefined(workflowRun?.workflowVersion?.id)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigateApp(AppPath.RecordShowPage, {
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
@ -27,7 +30,6 @@ export const useSeeVersionWorkflowRunSingleRecordAction: ActionHookWithoutObject
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -15,10 +15,10 @@ export const useSeeWorkflowWorkflowRunSingleRecordAction: ActionHookWithoutObjec
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = isDefined(workflowRun?.workflow?.id);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered || !workflowRun?.workflow?.id) return;
|
||||
if (!isDefined(workflowRun) || !isDefined(workflowRun?.workflow?.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigateApp(AppPath.RecordShowPage, {
|
||||
objectNameSingular: CoreObjectNameSingular.Workflow,
|
||||
@ -27,7 +27,6 @@ export const useSeeWorkflowWorkflowRunSingleRecordAction: ActionHookWithoutObjec
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -6,8 +6,8 @@ import { AppPath } from '@/types/AppPath';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
export const useSeeRunsWorkflowVersionSingleRecordAction: ActionHookWithoutObjectMetadataItem =
|
||||
() => {
|
||||
@ -21,10 +21,10 @@ export const useSeeRunsWorkflowVersionSingleRecordAction: ActionHookWithoutObjec
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = isDefined(workflowWithCurrentVersion);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) return;
|
||||
if (!isDefined(workflowWithCurrentVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigateApp(
|
||||
AppPath.RecordIndexPage,
|
||||
@ -49,7 +49,6 @@ export const useSeeRunsWorkflowVersionSingleRecordAction: ActionHookWithoutObjec
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -6,8 +6,8 @@ import { AppPath } from '@/types/AppPath';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
export const useSeeVersionsWorkflowVersionSingleRecordAction: ActionHookWithoutObjectMetadataItem =
|
||||
() => {
|
||||
@ -21,10 +21,10 @@ export const useSeeVersionsWorkflowVersionSingleRecordAction: ActionHookWithoutO
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = isDefined(workflowWithCurrentVersion);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered) return;
|
||||
if (!isDefined(workflowWithCurrentVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigateApp(
|
||||
AppPath.RecordIndexPage,
|
||||
@ -44,7 +44,6 @@ export const useSeeVersionsWorkflowVersionSingleRecordAction: ActionHookWithoutO
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -15,10 +15,13 @@ export const useSeeWorkflowWorkflowVersionSingleRecordAction: ActionHookWithoutO
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const shouldBeRegistered = isDefined(workflowVersion?.workflow?.id);
|
||||
|
||||
const onClick = () => {
|
||||
if (!shouldBeRegistered || !workflowVersion?.workflow?.id) return;
|
||||
if (
|
||||
!isDefined(workflowVersion) ||
|
||||
!isDefined(workflowVersion?.workflow?.id)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigateApp(AppPath.RecordShowPage, {
|
||||
objectNameSingular: CoreObjectNameSingular.Workflow,
|
||||
@ -27,7 +30,6 @@ export const useSeeWorkflowWorkflowVersionSingleRecordAction: ActionHookWithoutO
|
||||
};
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
};
|
||||
};
|
||||
|
||||
@ -8,8 +8,8 @@ import { useWorkflowVersion } from '@/workflow/hooks/useWorkflowVersion';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { openOverrideWorkflowDraftConfirmationModalState } from '@/workflow/states/openOverrideWorkflowDraftConfirmationModalState';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
export const useUseAsDraftWorkflowVersionSingleRecordAction: ActionHookWithoutObjectMetadataItem =
|
||||
() => {
|
||||
@ -33,13 +33,10 @@ export const useUseAsDraftWorkflowVersionSingleRecordAction: ActionHookWithoutOb
|
||||
const hasAlreadyDraftVersion =
|
||||
workflow?.versions.some((version) => version.status === 'DRAFT') || false;
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(workflowVersion) &&
|
||||
isDefined(workflow) &&
|
||||
workflowVersion.status !== 'DRAFT';
|
||||
|
||||
const onClick = async () => {
|
||||
if (!shouldBeRegistered) return;
|
||||
if (!isDefined(workflowVersion) || !isDefined(workflow)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasAlreadyDraftVersion) {
|
||||
setOpenOverrideWorkflowDraftConfirmationModal(true);
|
||||
@ -55,7 +52,7 @@ export const useUseAsDraftWorkflowVersionSingleRecordAction: ActionHookWithoutOb
|
||||
}
|
||||
};
|
||||
|
||||
const ConfirmationModal = shouldBeRegistered ? (
|
||||
const ConfirmationModal = isDefined(workflowVersion) ? (
|
||||
<OverrideWorkflowDraftConfirmationModal
|
||||
workflowId={workflowVersion.workflow.id}
|
||||
workflowVersionIdToCopy={workflowVersion.id}
|
||||
@ -63,7 +60,6 @@ export const useUseAsDraftWorkflowVersionSingleRecordAction: ActionHookWithoutOb
|
||||
) : undefined;
|
||||
|
||||
return {
|
||||
shouldBeRegistered,
|
||||
onClick,
|
||||
ConfirmationModal,
|
||||
};
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
import { DEFAULT_RECORD_ACTIONS_CONFIG } from '@/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig';
|
||||
import { DefaultRecordActionConfigKeys } from '@/action-menu/actions/types/DefaultRecordActionConfigKeys';
|
||||
import { RecordConfigAction } from '@/action-menu/actions/types/RecordConfigAction';
|
||||
|
||||
export const inheritActionsFromDefaultConfig = ({
|
||||
config,
|
||||
actionKeys,
|
||||
propertiesToOverwrite,
|
||||
}: {
|
||||
config: Record<string, RecordConfigAction>;
|
||||
actionKeys: DefaultRecordActionConfigKeys[];
|
||||
propertiesToOverwrite: Partial<
|
||||
Record<DefaultRecordActionConfigKeys, Partial<RecordConfigAction>>
|
||||
>;
|
||||
}): Record<string, RecordConfigAction> => {
|
||||
const actionsFromDefaultConfig = actionKeys.reduce(
|
||||
(acc, key) => ({
|
||||
...acc,
|
||||
[key]: {
|
||||
...DEFAULT_RECORD_ACTIONS_CONFIG[key],
|
||||
...propertiesToOverwrite[key],
|
||||
},
|
||||
}),
|
||||
{} as Record<string, RecordConfigAction>,
|
||||
);
|
||||
|
||||
return {
|
||||
...actionsFromDefaultConfig,
|
||||
...config,
|
||||
};
|
||||
};
|
||||
@ -1,20 +1,19 @@
|
||||
import { ActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { RecordAgnosticConfigAction } from '@/action-menu/actions/types/RecordAgnosticConfigAction';
|
||||
import { wrapActionInCallbacks } from '@/action-menu/actions/utils/wrapActionInCallbacks';
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
|
||||
import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry';
|
||||
import { useContext, useEffect } from 'react';
|
||||
|
||||
type RegisterAgnosticRecordActionEffectProps = {
|
||||
action: ActionMenuEntry & {
|
||||
useAction: ActionHookWithoutObjectMetadataItem;
|
||||
};
|
||||
action: RecordAgnosticConfigAction;
|
||||
};
|
||||
|
||||
export const RegisterAgnosticRecordActionEffect = ({
|
||||
action,
|
||||
}: RegisterAgnosticRecordActionEffectProps) => {
|
||||
const { shouldBeRegistered, onClick, ConfirmationModal } = action.useAction();
|
||||
const { onClick, ConfirmationModal } = action.useAction();
|
||||
|
||||
const shouldBeRegistered = action.shouldBeRegistered({});
|
||||
|
||||
const { onActionStartedCallback, onActionExecutedCallback } =
|
||||
useContext(ActionMenuContext);
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { useSearchRecordsRecordAgnosticAction } from '@/action-menu/actions/record-agnostic-actions/hooks/useSearchRecordsRecordAgnosticAction';
|
||||
import { RecordAgnosticActionsKey } from '@/action-menu/actions/record-agnostic-actions/types/RecordAgnosticActionsKey';
|
||||
import { ActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { RecordAgnosticActionsKeys } from '@/action-menu/actions/record-agnostic-actions/types/RecordAgnosticActionsKeys';
|
||||
import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import { RecordAgnosticConfigAction } from '@/action-menu/actions/types/RecordAgnosticConfigAction';
|
||||
import {
|
||||
ActionMenuEntry,
|
||||
ActionMenuEntryScope,
|
||||
ActionMenuEntryType,
|
||||
} from '@/action-menu/types/ActionMenuEntry';
|
||||
@ -12,14 +11,12 @@ import { IconSearch } from 'twenty-ui';
|
||||
|
||||
export const RECORD_AGNOSTIC_ACTIONS_CONFIG: Record<
|
||||
string,
|
||||
ActionMenuEntry & {
|
||||
useAction: ActionHookWithoutObjectMetadataItem;
|
||||
}
|
||||
RecordAgnosticConfigAction
|
||||
> = {
|
||||
searchRecords: {
|
||||
[RecordAgnosticActionsKeys.SEARCH_RECORDS]: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: RecordAgnosticActionsKey.SEARCH_RECORDS,
|
||||
key: RecordAgnosticActionsKeys.SEARCH_RECORDS,
|
||||
label: msg`Search records`,
|
||||
shortLabel: msg`Search`,
|
||||
position: 0,
|
||||
@ -28,11 +25,12 @@ export const RECORD_AGNOSTIC_ACTIONS_CONFIG: Record<
|
||||
availableOn: [ActionViewType.GLOBAL],
|
||||
useAction: useSearchRecordsRecordAgnosticAction,
|
||||
hotKeys: ['/'],
|
||||
shouldBeRegistered: () => true,
|
||||
},
|
||||
searchRecordsFallback: {
|
||||
[RecordAgnosticActionsKeys.SEARCH_RECORDS_FALLBACK]: {
|
||||
type: ActionMenuEntryType.Fallback,
|
||||
scope: ActionMenuEntryScope.Global,
|
||||
key: RecordAgnosticActionsKey.SEARCH_RECORDS_FALLBACK,
|
||||
key: RecordAgnosticActionsKeys.SEARCH_RECORDS_FALLBACK,
|
||||
label: msg`Search records`,
|
||||
shortLabel: msg`Search`,
|
||||
position: 1,
|
||||
@ -41,5 +39,6 @@ export const RECORD_AGNOSTIC_ACTIONS_CONFIG: Record<
|
||||
availableOn: [ActionViewType.GLOBAL],
|
||||
useAction: useSearchRecordsRecordAgnosticAction,
|
||||
hotKeys: ['/'],
|
||||
shouldBeRegistered: () => true,
|
||||
},
|
||||
};
|
||||
|
||||
@ -15,6 +15,5 @@ export const useSearchRecordsRecordAgnosticAction = () => {
|
||||
|
||||
return {
|
||||
onClick,
|
||||
shouldBeRegistered: true,
|
||||
};
|
||||
};
|
||||
|
||||
@ -6,9 +6,9 @@ import { useActiveWorkflowVersionsWithManualTrigger } from '@/workflow/hooks/use
|
||||
import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { IconSettingsAutomation } from 'twenty-ui';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useRunWorkflowActions = () => {
|
||||
const isWorkflowEnabled = useIsFeatureEnabled(
|
||||
@ -39,9 +39,9 @@ export const useRunWorkflowActions = () => {
|
||||
label: msg`${name}`,
|
||||
position: index,
|
||||
Icon: IconSettingsAutomation,
|
||||
shouldBeRegistered: () => true,
|
||||
useAction: () => {
|
||||
return {
|
||||
shouldBeRegistered: true,
|
||||
onClick: async () => {
|
||||
await runWorkflowVersion({
|
||||
workflowVersionId: activeWorkflowVersion.id,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export enum RecordAgnosticActionsKey {
|
||||
export enum RecordAgnosticActionsKeys {
|
||||
SEARCH_RECORDS = 'search-records',
|
||||
SEARCH_RECORDS_FALLBACK = 'search-records-fallback',
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
import { ConfirmationModalProps } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
|
||||
export type ActionHookResult = {
|
||||
shouldBeRegistered: boolean;
|
||||
onClick: () => Promise<void> | void;
|
||||
ConfirmationModal?: React.ReactElement<ConfirmationModalProps>;
|
||||
};
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
|
||||
export type DefaultRecordActionConfigKeys =
|
||||
| NoSelectionRecordActionKeys
|
||||
| SingleRecordActionKeys
|
||||
| MultipleRecordsActionKeys;
|
||||
@ -0,0 +1,9 @@
|
||||
import { ActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/ActionHook';
|
||||
import { RecordConfigAction } from '@/action-menu/actions/types/RecordConfigAction';
|
||||
|
||||
export type RecordAgnosticConfigAction = Omit<
|
||||
RecordConfigAction,
|
||||
'useAction'
|
||||
> & {
|
||||
useAction: ActionHookWithoutObjectMetadataItem;
|
||||
};
|
||||
@ -0,0 +1,25 @@
|
||||
import { ActionHook } from '@/action-menu/actions/types/ActionHook';
|
||||
import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import { ShouldBeRegisteredFunctionParams } from '@/action-menu/actions/types/ShouldBeRegisteredFunctionParams';
|
||||
import {
|
||||
ActionMenuEntryScope,
|
||||
ActionMenuEntryType,
|
||||
} from '@/action-menu/types/ActionMenuEntry';
|
||||
import { MessageDescriptor } from '@lingui/core';
|
||||
import { IconComponent, MenuItemAccent } from 'twenty-ui';
|
||||
|
||||
export type RecordConfigAction = {
|
||||
type: ActionMenuEntryType;
|
||||
scope: ActionMenuEntryScope;
|
||||
key: string;
|
||||
label: MessageDescriptor;
|
||||
shortLabel?: MessageDescriptor;
|
||||
position: number;
|
||||
Icon: IconComponent;
|
||||
isPinned?: boolean;
|
||||
accent?: MenuItemAccent;
|
||||
availableOn?: ActionViewType[];
|
||||
shouldBeRegistered: (params: ShouldBeRegisteredFunctionParams) => boolean;
|
||||
useAction: ActionHook;
|
||||
hotKeys?: string[];
|
||||
};
|
||||
@ -0,0 +1,20 @@
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
|
||||
|
||||
export type ShouldBeRegisteredFunctionParams = {
|
||||
objectMetadataItem?: ObjectMetadataItem;
|
||||
hasObjectReadOnlyPermission?: boolean;
|
||||
isWorkflowsEnabled?: boolean;
|
||||
recordFilters?: RecordFilter[];
|
||||
isShowPage?: boolean;
|
||||
isSoftDeleteFilterActive?: boolean;
|
||||
isInRightDrawer?: boolean;
|
||||
isFavorite?: boolean;
|
||||
isRemote?: boolean;
|
||||
isNoteOrTask?: boolean;
|
||||
selectedRecord?: ObjectRecord;
|
||||
numberOfSelectedRecords?: number;
|
||||
workflowWithCurrentVersion?: WorkflowWithCurrentVersion;
|
||||
};
|
||||
@ -1,4 +1,4 @@
|
||||
import { DEFAULT_ACTIONS_CONFIG } from '@/action-menu/actions/record-actions/constants/DefaultActionsConfig';
|
||||
import { DEFAULT_RECORD_ACTIONS_CONFIG } from '@/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig';
|
||||
import { WORKFLOW_ACTIONS_CONFIG } from '@/action-menu/actions/record-actions/constants/WorkflowActionsConfig';
|
||||
import { WORKFLOW_RUNS_ACTIONS_CONFIG } from '@/action-menu/actions/record-actions/constants/WorkflowRunsActionsConfig';
|
||||
import { WORKFLOW_VERSIONS_ACTIONS_CONFIG } from '@/action-menu/actions/record-actions/constants/WorkflowVersionsActionsConfig';
|
||||
@ -14,6 +14,6 @@ export const getActionConfig = (objectMetadataItem: ObjectMetadataItem) => {
|
||||
case CoreObjectNameSingular.WorkflowRun:
|
||||
return WORKFLOW_RUNS_ACTIONS_CONFIG;
|
||||
default:
|
||||
return DEFAULT_ACTIONS_CONFIG;
|
||||
return DEFAULT_RECORD_ACTIONS_CONFIG;
|
||||
}
|
||||
};
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState';
|
||||
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
export const useShouldActionBeRegisteredParams = ({
|
||||
objectMetadataItem,
|
||||
}: {
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
}) => {
|
||||
const { sortedFavorites: favorites } = useFavorites();
|
||||
|
||||
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
|
||||
const recordId =
|
||||
contextStoreTargetedRecordsRule.mode === 'selection'
|
||||
? contextStoreTargetedRecordsRule.selectedRecordIds[0]
|
||||
: undefined;
|
||||
|
||||
const foundFavorite = favorites?.find(
|
||||
(favorite) => favorite.recordId === recordId,
|
||||
);
|
||||
|
||||
const isFavorite = !!foundFavorite;
|
||||
|
||||
const selectedRecord =
|
||||
useRecoilValue(recordStoreFamilyState(recordId ?? '')) || undefined;
|
||||
|
||||
const isRemoteObject = objectMetadataItem.isRemote;
|
||||
|
||||
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||
|
||||
const isNoteOrTask =
|
||||
objectMetadataItem?.nameSingular === CoreObjectNameSingular.Note ||
|
||||
objectMetadataItem?.nameSingular === CoreObjectNameSingular.Task;
|
||||
|
||||
const { isInRightDrawer } = useContext(ActionMenuContext);
|
||||
|
||||
const isSoftDeleteFilterActive = useRecoilComponentValueV2(
|
||||
isSoftDeleteFilterActiveComponentState,
|
||||
);
|
||||
|
||||
const isShowPage =
|
||||
useRecoilComponentValueV2(contextStoreCurrentViewTypeComponentState) ===
|
||||
ContextStoreViewType.ShowPage;
|
||||
|
||||
const isWorkflowsEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IsWorkflowEnabled,
|
||||
);
|
||||
|
||||
const numberOfSelectedRecords = useRecoilComponentValueV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
);
|
||||
|
||||
const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(
|
||||
recordId,
|
||||
objectMetadataItem.nameSingular !== CoreObjectNameSingular.Workflow,
|
||||
);
|
||||
|
||||
return {
|
||||
isFavorite,
|
||||
isRemoteObject,
|
||||
hasObjectReadOnlyPermission,
|
||||
isNoteOrTask,
|
||||
isInRightDrawer,
|
||||
isSoftDeleteFilterActive,
|
||||
isShowPage,
|
||||
selectedRecord,
|
||||
isWorkflowsEnabled,
|
||||
numberOfSelectedRecords,
|
||||
workflowWithCurrentVersion,
|
||||
};
|
||||
};
|
||||
@ -1,8 +1,8 @@
|
||||
import { RecordActionMenuEntriesSetter } from '@/action-menu/actions/record-actions/components/RecordActionMenuEntriesSetter';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKey';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { RecordAgnosticActionMenuEntriesSetter } from '@/action-menu/actions/record-agnostic-actions/components/RecordAgnosticActionMenuEntriesSetter';
|
||||
import { RunWorkflowRecordAgnosticActionMenuEntriesSetter } from '@/action-menu/actions/record-agnostic-actions/components/RunWorkflowRecordAgnosticActionMenuEntriesSetter';
|
||||
import { RecordAgnosticActionsKey } from '@/action-menu/actions/record-agnostic-actions/types/RecordAgnosticActionsKey';
|
||||
import { RecordAgnosticActionsKeys } from '@/action-menu/actions/record-agnostic-actions/types/RecordAgnosticActionsKeys';
|
||||
import { ActionMenuConfirmationModals } from '@/action-menu/components/ActionMenuConfirmationModals';
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
|
||||
@ -144,16 +144,16 @@ export const CommandMenuContainer = ({
|
||||
isInRightDrawer: true,
|
||||
onActionExecutedCallback: ({ key }) => {
|
||||
if (
|
||||
key !== RecordAgnosticActionsKey.SEARCH_RECORDS &&
|
||||
key !== RecordAgnosticActionsKeys.SEARCH_RECORDS &&
|
||||
key !==
|
||||
RecordAgnosticActionsKey.SEARCH_RECORDS_FALLBACK &&
|
||||
RecordAgnosticActionsKeys.SEARCH_RECORDS_FALLBACK &&
|
||||
key !== NoSelectionRecordActionKeys.CREATE_NEW_RECORD
|
||||
) {
|
||||
toggleCommandMenu();
|
||||
}
|
||||
|
||||
if (
|
||||
key !== RecordAgnosticActionsKey.SEARCH_RECORDS_FALLBACK
|
||||
key !== RecordAgnosticActionsKeys.SEARCH_RECORDS_FALLBACK
|
||||
) {
|
||||
setCommandMenuSearch('');
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useWorkflowWithCurrentVersion = (
|
||||
workflowId: string | undefined,
|
||||
skip = false,
|
||||
): WorkflowWithCurrentVersion | undefined => {
|
||||
const { record: workflow } = useFindOneRecord<Workflow>({
|
||||
objectNameSingular: CoreObjectNameSingular.Workflow,
|
||||
@ -20,7 +21,7 @@ export const useWorkflowWithCurrentVersion = (
|
||||
lastPublishedVersionId: true,
|
||||
versions: true,
|
||||
},
|
||||
skip: !isDefined(workflowId),
|
||||
skip: !isDefined(workflowId) || skip,
|
||||
});
|
||||
|
||||
return useMemo(() => {
|
||||
|
||||
Reference in New Issue
Block a user