Fix Side Panel v2 bugs (#10865)
Fixing: - Export as PDF on empty note - Command O (sub commands) not using the right contextStore - BelongsToOne Field input triggering an error on open if no existing relation record is pre-selected
This commit is contained in:
@ -2,7 +2,7 @@ import { RegisterRecordActionEffect } from '@/action-menu/actions/record-actions
|
||||
import { WorkflowRunRecordActionMenuEntrySetterEffect } from '@/action-menu/actions/record-actions/workflow-run-record-actions/components/WorkflowRunRecordActionMenuEntrySetter';
|
||||
import { getActionConfig } from '@/action-menu/actions/utils/getActionConfig';
|
||||
import { getActionViewType } from '@/action-menu/actions/utils/getActionViewType';
|
||||
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
@ -14,18 +14,31 @@ import { isDefined } from 'twenty-shared';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const RecordActionMenuEntriesSetter = () => {
|
||||
const contextStoreCurrentObjectMetadataItemId = useRecoilComponentValueV2(
|
||||
const localContextStoreCurrentObjectMetadataItemId =
|
||||
useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
);
|
||||
|
||||
const mainContextStoreCurrentObjectMetadataItemId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
const localContextStoreObjectMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.id === contextStoreCurrentObjectMetadataItemId,
|
||||
objectMetadataItem.id === localContextStoreCurrentObjectMetadataItemId,
|
||||
);
|
||||
|
||||
const mainContextStoreObjectMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.id === mainContextStoreCurrentObjectMetadataItemId,
|
||||
);
|
||||
|
||||
const objectMetadataItem =
|
||||
localContextStoreObjectMetadataItem ?? mainContextStoreObjectMetadataItem;
|
||||
|
||||
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
|
||||
@ -39,7 +39,7 @@ import {
|
||||
IconTrashX,
|
||||
} from 'twenty-ui';
|
||||
|
||||
export const DEFAULT_ACTIONS_CONFIG_V2: Record<
|
||||
export const DEFAULT_ACTIONS_CONFIG: Record<
|
||||
string,
|
||||
ActionMenuEntry & {
|
||||
useAction: ActionHook;
|
||||
@ -1,188 +0,0 @@
|
||||
import { useDeleteMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction';
|
||||
import { useExportMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction';
|
||||
import { useRestoreMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useRestoreMultipleRecordsAction';
|
||||
import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys';
|
||||
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 { 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 { 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 {
|
||||
ActionMenuEntry,
|
||||
ActionMenuEntryScope,
|
||||
ActionMenuEntryType,
|
||||
} from '@/action-menu/types/ActionMenuEntry';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import {
|
||||
IconDatabaseExport,
|
||||
IconFileImport,
|
||||
IconHeart,
|
||||
IconHeartOff,
|
||||
IconRefresh,
|
||||
IconRotate2,
|
||||
IconTrash,
|
||||
} from 'twenty-ui';
|
||||
|
||||
export const DEFAULT_ACTIONS_CONFIG_V1: Record<
|
||||
string,
|
||||
ActionMenuEntry & {
|
||||
useAction: ActionHook;
|
||||
}
|
||||
> = {
|
||||
addToFavoritesSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
label: msg`Add to favorites`,
|
||||
position: 0,
|
||||
Icon: IconHeart,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useAddToFavoritesSingleRecordAction,
|
||||
},
|
||||
removeFromFavoritesSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
|
||||
label: msg`Remove from favorites`,
|
||||
position: 1,
|
||||
Icon: IconHeartOff,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useRemoveFromFavoritesSingleRecordAction,
|
||||
},
|
||||
deleteSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.DELETE,
|
||||
label: msg`Delete`,
|
||||
position: 2,
|
||||
Icon: IconTrash,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useDeleteSingleRecordAction,
|
||||
},
|
||||
deleteMultipleRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.DELETE,
|
||||
label: msg`Delete records`,
|
||||
shortLabel: msg`Delete`,
|
||||
position: 3,
|
||||
Icon: IconTrash,
|
||||
accent: 'danger',
|
||||
isPinned: true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useDeleteMultipleRecordsAction,
|
||||
},
|
||||
exportSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.EXPORT,
|
||||
label: msg`Export record`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 4,
|
||||
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 records`,
|
||||
shortLabel: msg`Export`,
|
||||
position: 5,
|
||||
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: 6,
|
||||
Icon: IconDatabaseExport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useExportMultipleRecordsAction,
|
||||
},
|
||||
restoreSingleRecord: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: SingleRecordActionKeys.RESTORE,
|
||||
label: msg`Restore record`,
|
||||
shortLabel: msg`Restore`,
|
||||
position: 7,
|
||||
Icon: IconRefresh,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
availableOn: [
|
||||
ActionViewType.SHOW_PAGE,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
],
|
||||
useAction: useRestoreSingleRecordAction,
|
||||
},
|
||||
restoreMultipleRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.RecordSelection,
|
||||
key: MultipleRecordsActionKeys.RESTORE,
|
||||
label: msg`Restore records`,
|
||||
shortLabel: msg`Restore`,
|
||||
position: 8,
|
||||
Icon: IconRefresh,
|
||||
accent: 'default',
|
||||
isPinned: true,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
|
||||
useAction: useRestoreMultipleRecordsAction,
|
||||
},
|
||||
seeDeletedRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
|
||||
label: msg`See deleted records`,
|
||||
shortLabel: msg`Deleted records`,
|
||||
position: 9,
|
||||
Icon: IconRotate2,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useSeeDeletedRecordsNoSelectionRecordAction,
|
||||
},
|
||||
importRecords: {
|
||||
type: ActionMenuEntryType.Standard,
|
||||
scope: ActionMenuEntryScope.Object,
|
||||
key: NoSelectionRecordActionKeys.IMPORT_RECORDS,
|
||||
label: msg`Import records`,
|
||||
shortLabel: msg`Import`,
|
||||
position: 10,
|
||||
Icon: IconFileImport,
|
||||
accent: 'default',
|
||||
isPinned: false,
|
||||
availableOn: [ActionViewType.INDEX_PAGE_NO_SELECTION],
|
||||
useAction: useImportRecordsNoSelectionRecordAction,
|
||||
},
|
||||
};
|
||||
@ -3,6 +3,7 @@ import { ActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/Ac
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
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';
|
||||
|
||||
@ -20,10 +21,13 @@ export const useExportNoteAction: ActionHookWithObjectMetadataItem = ({
|
||||
objectMetadataItem?.nameSingular === CoreObjectNameSingular.Task;
|
||||
|
||||
const shouldBeRegistered =
|
||||
isDefined(objectMetadataItem) && isDefined(selectedRecord) && isNoteOrTask;
|
||||
isDefined(objectMetadataItem) &&
|
||||
isDefined(selectedRecord) &&
|
||||
isNoteOrTask &&
|
||||
isNonEmptyString(selectedRecord.bodyV2?.blocknote);
|
||||
|
||||
const onClick = async () => {
|
||||
if (!shouldBeRegistered || !selectedRecord?.body) {
|
||||
if (!shouldBeRegistered || !selectedRecord.bodyV2.blocknote) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { DEFAULT_ACTIONS_CONFIG_V2 } from '@/action-menu/actions/record-actions/constants/DefaultActionsConfigV2';
|
||||
import { DEFAULT_ACTIONS_CONFIG } from '@/action-menu/actions/record-actions/constants/DefaultActionsConfig';
|
||||
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_V2;
|
||||
return DEFAULT_ACTIONS_CONFIG;
|
||||
}
|
||||
};
|
||||
|
||||
@ -140,7 +140,7 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer>
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
<UndecoratedLink
|
||||
to={newSelectFieldSettingsUrl}
|
||||
onClick={() => {
|
||||
|
||||
@ -197,7 +197,9 @@ export const RecordDetailRelationSection = ({
|
||||
const handleOpenRelationPickerDropdown = () => {
|
||||
if (isToOneObject) {
|
||||
setSingleRecordPickerSearchFilter('');
|
||||
setSingleRecordPickerSelectedId(relationRecords[0].id);
|
||||
if (relationRecords.length > 0) {
|
||||
setSingleRecordPickerSelectedId(relationRecords[0].id);
|
||||
}
|
||||
}
|
||||
|
||||
if (isToManyObjects) {
|
||||
|
||||
@ -65,6 +65,8 @@ export const Default: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
await sleep(100);
|
||||
await canvas.findByText('Code your function');
|
||||
await canvas.findByText('Code your function', undefined, {
|
||||
timeout: 3000,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user