545 replace objects icons and names with records avatars and labelidentifiers in command menu context chips (#10787)
Closes https://github.com/twentyhq/core-team-issues/issues/545 This PR: - Introduces `commandMenuNavigationMorphItemsState` which stores the information about the `recordId` and the `objectMetadataItemId` for each page - Creates `CommandMenuContextChipEffect`, which queries the records from the previous pages in case a record has been updated during the navigation, to keep up to date information and stores it inside `commandMenuNavigationRecordsState` - `useCommandMenuContextChips` returns the context chips information - Style updates (icons background and color) - Updates `useCommandMenu` to set and reset these new states https://github.com/user-attachments/assets/8886848a-721d-4709-9330-8e84ebc0d51e
This commit is contained in:
@ -1,63 +0,0 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useLimitPerMetadataItem } from '@/object-metadata/hooks/useLimitPerMetadataItem';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SingleRecordPickerComponentInstanceContext } from '@/object-record/record-picker/single-record-picker/states/contexts/SingleRecordPickerComponentInstanceContext';
|
||||
|
||||
const instanceId = 'instanceId';
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<SingleRecordPickerComponentInstanceContext.Provider value={{ instanceId }}>
|
||||
<RecoilRoot>{children}</RecoilRoot>
|
||||
</SingleRecordPickerComponentInstanceContext.Provider>
|
||||
);
|
||||
|
||||
describe('useLimitPerMetadataItem', () => {
|
||||
const objectData: ObjectMetadataItem[] = [
|
||||
{
|
||||
createdAt: 'createdAt',
|
||||
id: 'id',
|
||||
isActive: true,
|
||||
isCustom: true,
|
||||
isSystem: true,
|
||||
isRemote: false,
|
||||
isSearchable: true,
|
||||
labelPlural: 'labelPlural',
|
||||
labelSingular: 'labelSingular',
|
||||
namePlural: 'namePlural',
|
||||
nameSingular: 'nameSingular',
|
||||
labelIdentifierFieldMetadataId: '20202020-72ba-4e11-a36d-e17b544541e1',
|
||||
updatedAt: 'updatedAt',
|
||||
isLabelSyncedWithName: false,
|
||||
fields: [],
|
||||
indexMetadatas: [],
|
||||
},
|
||||
];
|
||||
|
||||
it('should return object with nameSingular and default limit', async () => {
|
||||
const { result } = renderHook(
|
||||
() => useLimitPerMetadataItem({ objectMetadataItems: objectData }),
|
||||
{
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.limitPerMetadataItem).toStrictEqual({
|
||||
limitNameSingular: 60,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an object with nameSingular and specified limit', async () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useLimitPerMetadataItem({ objectMetadataItems: objectData, limit: 30 }),
|
||||
{
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.limitPerMetadataItem).toStrictEqual({
|
||||
limitNameSingular: 30,
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,36 +1,16 @@
|
||||
import { getIconColorForObjectType } from '@/object-metadata/utils/getIconColorForObjectType';
|
||||
import { getIconForObjectType } from '@/object-metadata/utils/getIconForObjectType';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { IconCheckbox, IconComponent, IconNotes } from 'twenty-ui';
|
||||
|
||||
export const useGetStandardObjectIcon = (objectNameSingular: string) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const getIconForObjectType = (
|
||||
objectType: string,
|
||||
): IconComponent | undefined => {
|
||||
switch (objectType) {
|
||||
case 'note':
|
||||
return IconNotes;
|
||||
case 'task':
|
||||
return IconCheckbox;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const getIconColorForObjectType = (objectType: string): string => {
|
||||
switch (objectType) {
|
||||
case 'note':
|
||||
return theme.color.yellow;
|
||||
case 'task':
|
||||
return theme.color.blue;
|
||||
default:
|
||||
return 'currentColor';
|
||||
}
|
||||
};
|
||||
|
||||
const { Icon, IconColor } = {
|
||||
Icon: getIconForObjectType(objectNameSingular),
|
||||
IconColor: getIconColorForObjectType(objectNameSingular),
|
||||
IconColor: getIconColorForObjectType({
|
||||
objectType: objectNameSingular,
|
||||
theme,
|
||||
}),
|
||||
};
|
||||
|
||||
return { Icon, IconColor };
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { DEFAULT_SEARCH_REQUEST_LIMIT } from '@/object-record/constants/DefaultSearchRequestLimit';
|
||||
import { capitalize, isDefined } from 'twenty-shared';
|
||||
|
||||
export const useLimitPerMetadataItem = ({
|
||||
objectMetadataItems,
|
||||
limit = DEFAULT_SEARCH_REQUEST_LIMIT,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataItem[];
|
||||
limit?: number;
|
||||
}) => {
|
||||
const limitPerMetadataItem = Object.fromEntries(
|
||||
objectMetadataItems
|
||||
.map(({ nameSingular }) => {
|
||||
return [`limit${capitalize(nameSingular)}`, limit];
|
||||
})
|
||||
.filter(isDefined),
|
||||
);
|
||||
|
||||
return {
|
||||
limitPerMetadataItem,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,18 @@
|
||||
import { Theme } from '@emotion/react';
|
||||
|
||||
export const getIconColorForObjectType = ({
|
||||
objectType,
|
||||
theme,
|
||||
}: {
|
||||
objectType: string;
|
||||
theme: Theme;
|
||||
}): string => {
|
||||
switch (objectType) {
|
||||
case 'note':
|
||||
return theme.color.yellow;
|
||||
case 'task':
|
||||
return theme.color.blue;
|
||||
default:
|
||||
return 'currentColor';
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
import { IconCheckbox, IconComponent, IconNotes } from 'twenty-ui';
|
||||
|
||||
export const getIconForObjectType = (
|
||||
objectType: string,
|
||||
): IconComponent | undefined => {
|
||||
switch (objectType) {
|
||||
case 'note':
|
||||
return IconNotes;
|
||||
case 'task':
|
||||
return IconCheckbox;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user