[COMMAND MENU ITEMS] Create union type for command menu item payload (#19432)
Replace generic JSON scalar with a typed GraphQL union CommandMenuItemPayload (PathNavigationPayload | ObjectMetadataNavigationPayload) for the CommandMenuItem.payload field
This commit is contained in:
+6
-8
@@ -1,7 +1,7 @@
|
||||
import { HeadlessEngineCommandWrapperEffect } from '@/command-menu-item/engine-command/components/HeadlessEngineCommandWrapperEffect';
|
||||
import { useHeadlessCommandContextApi } from '@/command-menu-item/engine-command/hooks/useHeadlessCommandContextApi';
|
||||
import { isObjectMetadataNavigationPayload } from '@/command-menu-item/engine-command/utils/isObjectMetadataNavigationPayload';
|
||||
import { isPathNavigationPayload } from '@/command-menu-item/engine-command/utils/isPathNavigationPayload';
|
||||
import { isObjectMetadataCommandMenuItemPayload } from '@/command-menu-item/engine-command/utils/isObjectMetadataCommandMenuItemPayload';
|
||||
import { isPathCommandMenuItemPayload } from '@/command-menu-item/engine-command/utils/isPathCommandMenuItemPayload';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { AppPath } from 'twenty-shared/types';
|
||||
@@ -17,11 +17,9 @@ export const NavigationEngineCommand = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const navigationPayload = payload;
|
||||
|
||||
if (isObjectMetadataNavigationPayload(navigationPayload)) {
|
||||
if (isObjectMetadataCommandMenuItemPayload(payload)) {
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.id === navigationPayload.objectMetadataItemId,
|
||||
(item) => item.id === payload.objectMetadataItemId,
|
||||
);
|
||||
|
||||
if (!isDefined(objectMetadataItem)) {
|
||||
@@ -38,9 +36,9 @@ export const NavigationEngineCommand = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPathNavigationPayload(navigationPayload)) {
|
||||
if (isPathCommandMenuItemPayload(payload)) {
|
||||
// eslint-disable-next-line twenty/no-navigate-prefer-link
|
||||
navigate(navigationPayload.path);
|
||||
navigate(payload.path);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
type CommandMenuItemAvailabilityType,
|
||||
type EngineComponentKey,
|
||||
type CommandMenuItemPayload,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
type MountCommandParams = {
|
||||
@@ -18,7 +19,7 @@ type MountCommandParams = {
|
||||
workflowVersionId?: string;
|
||||
availabilityType?: CommandMenuItemAvailabilityType;
|
||||
availabilityObjectMetadataId?: string | null;
|
||||
payload?: Record<string, unknown> | null;
|
||||
payload?: CommandMenuItemPayload | null;
|
||||
};
|
||||
|
||||
export const useMountCommand = () => {
|
||||
|
||||
+5
-2
@@ -5,7 +5,10 @@ import {
|
||||
type Nullable,
|
||||
type RecordGqlOperationFilter,
|
||||
} from 'twenty-shared/types';
|
||||
import { type EngineComponentKey } from '~/generated-metadata/graphql';
|
||||
import {
|
||||
type EngineComponentKey,
|
||||
type CommandMenuItemPayload,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export type HeadlessEngineCommandContextApi = {
|
||||
engineComponentKey: EngineComponentKey;
|
||||
@@ -16,7 +19,7 @@ export type HeadlessEngineCommandContextApi = {
|
||||
targetedRecordsRule: ContextStoreTargetedRecordsRule;
|
||||
selectedRecords: ObjectRecord[];
|
||||
graphqlFilter: Nullable<RecordGqlOperationFilter>;
|
||||
payload: Nullable<Record<string, unknown>>;
|
||||
payload: Nullable<CommandMenuItemPayload>;
|
||||
};
|
||||
|
||||
export type HeadlessFrontComponentCommandContextApi =
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { isObjectMetadataCommandMenuItemPayload } from '@/command-menu-item/engine-command/utils/isObjectMetadataCommandMenuItemPayload';
|
||||
import { type CommandMenuItemPayload } from '~/generated-metadata/graphql';
|
||||
|
||||
describe('isObjectMetadataCommandMenuItemPayload', () => {
|
||||
it('should return true for an ObjectMetadataCommandMenuItemPayload', () => {
|
||||
const payload: CommandMenuItemPayload = {
|
||||
__typename: 'ObjectMetadataCommandMenuItemPayload',
|
||||
objectMetadataItemId: 'some-uuid',
|
||||
};
|
||||
|
||||
expect(isObjectMetadataCommandMenuItemPayload(payload)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for a PathCommandMenuItemPayload', () => {
|
||||
const payload: CommandMenuItemPayload = {
|
||||
__typename: 'PathCommandMenuItemPayload',
|
||||
path: '/settings',
|
||||
};
|
||||
|
||||
expect(isObjectMetadataCommandMenuItemPayload(payload)).toBe(false);
|
||||
});
|
||||
});
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { isPathCommandMenuItemPayload } from '@/command-menu-item/engine-command/utils/isPathCommandMenuItemPayload';
|
||||
import { type CommandMenuItemPayload } from '~/generated-metadata/graphql';
|
||||
|
||||
describe('isPathCommandMenuItemPayload', () => {
|
||||
it('should return true for a PathCommandMenuItemPayload', () => {
|
||||
const payload: CommandMenuItemPayload = {
|
||||
__typename: 'PathCommandMenuItemPayload',
|
||||
path: '/settings',
|
||||
};
|
||||
|
||||
expect(isPathCommandMenuItemPayload(payload)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for an ObjectMetadataCommandMenuItemPayload', () => {
|
||||
const payload: CommandMenuItemPayload = {
|
||||
__typename: 'ObjectMetadataCommandMenuItemPayload',
|
||||
objectMetadataItemId: 'some-uuid',
|
||||
};
|
||||
|
||||
expect(isPathCommandMenuItemPayload(payload)).toBe(false);
|
||||
});
|
||||
});
|
||||
+5
-2
@@ -14,7 +14,10 @@ import { type EnrichedObjectMetadataItem } from '@/object-metadata/types/Enriche
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type EngineComponentKey } from '~/generated-metadata/graphql';
|
||||
import {
|
||||
type EngineComponentKey,
|
||||
type CommandMenuItemPayload,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export const buildHeadlessCommandContextApi = ({
|
||||
store,
|
||||
@@ -25,7 +28,7 @@ export const buildHeadlessCommandContextApi = ({
|
||||
store: Store;
|
||||
contextStoreInstanceId: string;
|
||||
engineComponentKey: EngineComponentKey;
|
||||
payload?: Record<string, unknown> | null;
|
||||
payload?: CommandMenuItemPayload | null;
|
||||
}): HeadlessEngineCommandContextApi => {
|
||||
const objectMetadataItemId = store.get(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import {
|
||||
type CommandMenuItemPayload,
|
||||
type ObjectMetadataCommandMenuItemPayload,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export const isObjectMetadataCommandMenuItemPayload = (
|
||||
payload: CommandMenuItemPayload,
|
||||
): payload is ObjectMetadataCommandMenuItemPayload =>
|
||||
payload.__typename === 'ObjectMetadataCommandMenuItemPayload';
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
export const isObjectMetadataNavigationPayload = (
|
||||
payload: Record<string, unknown>,
|
||||
): payload is { objectMetadataItemId: string } =>
|
||||
'objectMetadataItemId' in payload &&
|
||||
typeof payload.objectMetadataItemId === 'string';
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import {
|
||||
type CommandMenuItemPayload,
|
||||
type PathCommandMenuItemPayload,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export const isPathCommandMenuItemPayload = (
|
||||
payload: CommandMenuItemPayload,
|
||||
): payload is PathCommandMenuItemPayload =>
|
||||
payload.__typename === 'PathCommandMenuItemPayload';
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
export const isPathNavigationPayload = (
|
||||
payload: Record<string, unknown>,
|
||||
): payload is { path: string } =>
|
||||
'path' in payload && typeof payload.path === 'string';
|
||||
Reference in New Issue
Block a user