Refactor command menu items deprecated code (#19508)
- Removes the intermediate `CommandMenuItemConfig` / `CommandConfigContext` / `CommandMenuItemDisplay` abstraction layers, replacing them with a single `CommandMenuItemRenderer` that renders directly from the command menu items from the backend - Eliminates the server-items/ subdirectory by moving its contents (hooks/, contexts/, states/, display/, edit/) up into the parent command-menu-item/ module, removing an unnecessary nesting level.
This commit is contained in:
+39
@@ -0,0 +1,39 @@
|
||||
import { getVisibleCommandMenuItemCountForContainerWidth } from '@/command-menu-item/display/utils/getVisibleCommandMenuItemCountForContainerWidth';
|
||||
|
||||
describe('getVisibleCommandMenuItemCountForContainerWidth', () => {
|
||||
it('should return all items when container width is zero', () => {
|
||||
const visibleCommandMenuItemCount =
|
||||
getVisibleCommandMenuItemCountForContainerWidth({
|
||||
commandMenuItemKeysInDisplayOrder: ['a', 'b', 'c'],
|
||||
commandMenuItemWidthsByKey: { a: 20, b: 20, c: 20 },
|
||||
commandMenuItemsContainerWidth: 0,
|
||||
commandMenuItemsGapWidth: 8,
|
||||
});
|
||||
|
||||
expect(visibleCommandMenuItemCount).toBe(3);
|
||||
});
|
||||
|
||||
it('should return all items when at least one width is missing', () => {
|
||||
const visibleCommandMenuItemCount =
|
||||
getVisibleCommandMenuItemCountForContainerWidth({
|
||||
commandMenuItemKeysInDisplayOrder: ['a', 'b'],
|
||||
commandMenuItemWidthsByKey: { a: 20 },
|
||||
commandMenuItemsContainerWidth: 40,
|
||||
commandMenuItemsGapWidth: 8,
|
||||
});
|
||||
|
||||
expect(visibleCommandMenuItemCount).toBe(2);
|
||||
});
|
||||
|
||||
it('should stop before exceeding the container width with gaps', () => {
|
||||
const visibleCommandMenuItemCount =
|
||||
getVisibleCommandMenuItemCountForContainerWidth({
|
||||
commandMenuItemKeysInDisplayOrder: ['a', 'b', 'c'],
|
||||
commandMenuItemWidthsByKey: { a: 40, b: 40, c: 40 },
|
||||
commandMenuItemsContainerWidth: 100,
|
||||
commandMenuItemsGapWidth: 8,
|
||||
});
|
||||
|
||||
expect(visibleCommandMenuItemCount).toBe(2);
|
||||
});
|
||||
});
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
type GetVisibleCommandMenuItemCountForContainerWidthParams = {
|
||||
commandMenuItemKeysInDisplayOrder: string[];
|
||||
commandMenuItemWidthsByKey: Record<string, number>;
|
||||
commandMenuItemsContainerWidth: number;
|
||||
commandMenuItemsGapWidth: number;
|
||||
};
|
||||
|
||||
export const getVisibleCommandMenuItemCountForContainerWidth = ({
|
||||
commandMenuItemKeysInDisplayOrder,
|
||||
commandMenuItemWidthsByKey,
|
||||
commandMenuItemsContainerWidth,
|
||||
commandMenuItemsGapWidth,
|
||||
}: GetVisibleCommandMenuItemCountForContainerWidthParams): number => {
|
||||
if (commandMenuItemsContainerWidth <= 0) {
|
||||
return commandMenuItemKeysInDisplayOrder.length;
|
||||
}
|
||||
|
||||
let usedWidth = 0;
|
||||
let visibleCommandMenuItemCount = 0;
|
||||
|
||||
for (const commandMenuItemKey of commandMenuItemKeysInDisplayOrder) {
|
||||
const commandMenuItemWidth = commandMenuItemWidthsByKey[commandMenuItemKey];
|
||||
|
||||
if (typeof commandMenuItemWidth !== 'number') {
|
||||
return commandMenuItemKeysInDisplayOrder.length;
|
||||
}
|
||||
|
||||
const nextWidth =
|
||||
visibleCommandMenuItemCount === 0
|
||||
? commandMenuItemWidth
|
||||
: usedWidth + commandMenuItemsGapWidth + commandMenuItemWidth;
|
||||
|
||||
if (nextWidth > commandMenuItemsContainerWidth) {
|
||||
break;
|
||||
}
|
||||
|
||||
usedWidth = nextWidth;
|
||||
visibleCommandMenuItemCount += 1;
|
||||
}
|
||||
|
||||
return visibleCommandMenuItemCount;
|
||||
};
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import { type CommandMenuContextApi, type Nullable } from 'twenty-shared/types';
|
||||
import { interpolateCommandMenuItemTemplate } from 'twenty-shared/utils';
|
||||
import { type CommandMenuItemFieldsFragment } from '~/generated-metadata/graphql';
|
||||
|
||||
type InterpolatedCommandMenuItemFields = {
|
||||
iconKey: Nullable<string>;
|
||||
label: string;
|
||||
shortLabel: Nullable<string>;
|
||||
};
|
||||
|
||||
export const interpolateCommandMenuItemFields = (
|
||||
item: CommandMenuItemFieldsFragment,
|
||||
commandMenuContextApi: CommandMenuContextApi,
|
||||
): InterpolatedCommandMenuItemFields => {
|
||||
const iconKey = interpolateCommandMenuItemTemplate({
|
||||
label: item.icon,
|
||||
context: commandMenuContextApi,
|
||||
});
|
||||
|
||||
const label =
|
||||
interpolateCommandMenuItemTemplate({
|
||||
label: item.label,
|
||||
context: commandMenuContextApi,
|
||||
}) ?? item.label;
|
||||
|
||||
const shortLabel = interpolateCommandMenuItemTemplate({
|
||||
label: item.shortLabel,
|
||||
context: commandMenuContextApi,
|
||||
});
|
||||
|
||||
return { iconKey, label, shortLabel };
|
||||
};
|
||||
Reference in New Issue
Block a user