[feat]:Added the ability to create a view from Command Menu (#13335)
Fixes - #13307 **Description** This PR adds the feature to create view from the command menu **Key Changes** - Added the command in the DEAFULT_RECORD_ACTION_CONFIG - Created a component which is used in the action when the command is clicked **Files Changed** - packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx - packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/components/SeeDeletedRecordsNoSelectionRecordAction.tsx - packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys.ts - packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx **Demo Video** https://github.com/user-attachments/assets/8e3dc3dd-7f85-4da5-8c4a-6721abb29aff --------- Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
This commit is contained in:
@ -5,6 +5,7 @@ import { ExportMultipleRecordsAction } from '@/action-menu/actions/record-action
|
||||
import { RestoreMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/components/RestoreMultipleRecordsAction';
|
||||
import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys';
|
||||
import { CreateNewTableRecordNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/components/CreateNewTableRecordNoSelectionRecordAction';
|
||||
import { CreateNewViewNoSelectionRecord } from '@/action-menu/actions/record-actions/no-selection/components/CreateNewViewNoSelectionRecord';
|
||||
import { HideDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/components/HideDeletedRecordsNoSelectionRecordAction';
|
||||
import { ImportRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/components/ImportRecordsNoSelectionRecordAction';
|
||||
import { SeeDeletedRecordsNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/components/SeeDeletedRecordsNoSelectionRecordAction';
|
||||
@ -41,6 +42,7 @@ import {
|
||||
IconFileImport,
|
||||
IconHeart,
|
||||
IconHeartOff,
|
||||
IconLayout,
|
||||
IconPlus,
|
||||
IconRefresh,
|
||||
IconRotate2,
|
||||
@ -276,13 +278,28 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <SeeDeletedRecordsNoSelectionRecordAction />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.CREATE_NEW_VIEW]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.CREATE_NEW_VIEW,
|
||||
label: msg`Create View`,
|
||||
shortLabel: msg`Create View`,
|
||||
position: 11,
|
||||
Icon: IconLayout,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
shouldBeRegistered: ({ isSoftDeleteFilterActive }) =>
|
||||
!isSoftDeleteFilterActive,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
component: <CreateNewViewNoSelectionRecord />,
|
||||
},
|
||||
[NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: {
|
||||
type: ActionType.Standard,
|
||||
scope: ActionScope.Object,
|
||||
key: NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
|
||||
label: msg`Hide deleted records`,
|
||||
shortLabel: msg`Hide deleted`,
|
||||
position: 11,
|
||||
position: 12,
|
||||
Icon: IconEyeOff,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
@ -297,7 +314,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: SingleRecordActionKeys.DESTROY,
|
||||
label: msg`Permanently destroy record`,
|
||||
shortLabel: msg`Destroy`,
|
||||
position: 12,
|
||||
position: 13,
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
@ -316,7 +333,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
|
||||
label: msg`Navigate to previous record`,
|
||||
position: 13,
|
||||
position: 14,
|
||||
isPinned: true,
|
||||
Icon: IconChevronUp,
|
||||
shouldBeRegistered: ({ isInRightDrawer }) => !isInRightDrawer,
|
||||
@ -328,7 +345,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
scope: ActionScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
|
||||
label: msg`Navigate to next record`,
|
||||
position: 14,
|
||||
position: 15,
|
||||
isPinned: true,
|
||||
Icon: IconChevronDown,
|
||||
shouldBeRegistered: ({ isInRightDrawer }) => !isInRightDrawer,
|
||||
@ -341,7 +358,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: MultipleRecordsActionKeys.DESTROY,
|
||||
label: msg`Permanently destroy records`,
|
||||
shortLabel: msg`Destroy`,
|
||||
position: 15,
|
||||
position: 16,
|
||||
Icon: IconTrashX,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
@ -366,7 +383,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: SingleRecordActionKeys.RESTORE,
|
||||
label: msg`Restore record`,
|
||||
shortLabel: msg`Restore`,
|
||||
position: 16,
|
||||
position: 17,
|
||||
Icon: IconRefresh,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
@ -394,7 +411,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: MultipleRecordsActionKeys.RESTORE,
|
||||
label: msg`Restore records`,
|
||||
shortLabel: msg`Restore`,
|
||||
position: 17,
|
||||
position: 18,
|
||||
Icon: IconRefresh,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
@ -419,7 +436,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_WORKFLOWS,
|
||||
label: msg`Go to workflows`,
|
||||
shortLabel: msg`See workflows`,
|
||||
position: 18,
|
||||
position: 19,
|
||||
Icon: IconSettingsAutomation,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
@ -451,7 +468,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
label: msg`Go to People`,
|
||||
shortLabel: msg`People`,
|
||||
position: 19,
|
||||
position: 20,
|
||||
Icon: IconUser,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@ -482,7 +499,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_COMPANIES,
|
||||
label: msg`Go to Companies`,
|
||||
shortLabel: msg`Companies`,
|
||||
position: 20,
|
||||
position: 21,
|
||||
Icon: IconBuildingSkyscraper,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@ -513,7 +530,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
|
||||
label: msg`Go to Opportunities`,
|
||||
shortLabel: msg`Opportunities`,
|
||||
position: 21,
|
||||
position: 22,
|
||||
Icon: IconTargetArrow,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@ -546,7 +563,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_SETTINGS,
|
||||
label: msg`Go to Settings`,
|
||||
shortLabel: msg`Settings`,
|
||||
position: 22,
|
||||
position: 23,
|
||||
Icon: IconSettings,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@ -572,7 +589,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_TASKS,
|
||||
label: msg`Go to Tasks`,
|
||||
shortLabel: msg`Tasks`,
|
||||
position: 23,
|
||||
position: 24,
|
||||
Icon: IconCheckbox,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
@ -603,7 +620,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
|
||||
key: NoSelectionRecordActionKeys.GO_TO_NOTES,
|
||||
label: msg`Go to Notes`,
|
||||
shortLabel: msg`Notes`,
|
||||
position: 24,
|
||||
position: 25,
|
||||
Icon: IconCheckbox,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
import { Action } from '@/action-menu/actions/components/Action';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode';
|
||||
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
|
||||
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
|
||||
|
||||
export const CreateNewViewNoSelectionRecord = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
const { openDropdown } = useOpenDropdown();
|
||||
|
||||
const currentViewId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
);
|
||||
|
||||
if (!currentViewId) {
|
||||
throw new Error('Current view ID is not defined');
|
||||
}
|
||||
|
||||
const recordIndexId = getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem.namePlural,
|
||||
currentViewId,
|
||||
);
|
||||
|
||||
const setViewPickerReferenceViewId = useSetRecoilComponentStateV2(
|
||||
viewPickerReferenceViewIdComponentState,
|
||||
recordIndexId,
|
||||
);
|
||||
|
||||
const { setViewPickerMode } = useViewPickerMode(recordIndexId);
|
||||
|
||||
const handleAddViewButtonClick = () => {
|
||||
setViewPickerReferenceViewId(currentViewId);
|
||||
setViewPickerMode('create-empty');
|
||||
openDropdown({
|
||||
dropdownComponentInstanceIdFromProps: VIEW_PICKER_DROPDOWN_ID,
|
||||
});
|
||||
};
|
||||
|
||||
return <Action onClick={handleAddViewButtonClick} />;
|
||||
};
|
||||
@ -11,4 +11,5 @@ export enum NoSelectionRecordActionKeys {
|
||||
GO_TO_SETTINGS = 'go-to-settings',
|
||||
GO_TO_TASKS = 'go-to-tasks',
|
||||
GO_TO_NOTES = 'go-to-notes',
|
||||
CREATE_NEW_VIEW = 'create-view',
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user