Improve and fix source selection in charts (#15033)
- Improvements: Hide advanced objects in a subMenu and order objects alphabetically <img width="420" height="944" alt="CleanShot 2025-10-10 at 17 32 59@2x" src="https://github.com/user-attachments/assets/52d70a97-b037-4ac1-9237-ef3262cac099" /> <img width="426" height="1140" alt="CleanShot 2025-10-10 at 17 33 24@2x" src="https://github.com/user-attachments/assets/932501be-3c5a-45d9-b2fd-938c7f6b2ef9" /> - Fix: reset all fields when changing object
This commit is contained in:
+78
-10
@@ -3,6 +3,8 @@ import { useUpdateCurrentWidgetConfig } from '@/command-menu/pages/page-layout/h
|
||||
import { useWidgetInEditMode } from '@/command-menu/pages/page-layout/hooks/useWidgetInEditMode';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
|
||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
|
||||
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
@@ -14,14 +16,19 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { IconChevronLeft, IconSettings, useIcons } from 'twenty-ui/display';
|
||||
import { MenuItem, MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
|
||||
|
||||
const ADVANCED_OBJECTS_MENU_ITEM_ID = 'advanced-objects';
|
||||
|
||||
export const ChartDataSourceDropdownContent = () => {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [isAdvancedObjectsMenuOpened, setIsAdvancedObjectsMenuOpened] =
|
||||
useState(false);
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
const { objectPermissionsByObjectMetadataId } = useObjectPermissions();
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
|
||||
@@ -45,13 +52,23 @@ export const ChartDataSourceDropdownContent = () => {
|
||||
objectPermissionsByObjectMetadataId[objectMetadataItem.id];
|
||||
|
||||
return (
|
||||
isDefined(objectPermissions) && objectPermissions.canReadObjectRecords
|
||||
isDefined(objectPermissions) &&
|
||||
objectPermissions.canReadObjectRecords &&
|
||||
objectMetadataItem.isActive
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
const regularObjects = objectsWithReadAccess
|
||||
.filter((item) => !item.isSystem)
|
||||
.sort((a, b) => a.labelPlural.localeCompare(b.labelPlural));
|
||||
|
||||
const systemObjects = objectsWithReadAccess
|
||||
.filter((item) => item.isSystem)
|
||||
.sort((a, b) => a.labelPlural.localeCompare(b.labelPlural));
|
||||
|
||||
const availableObjectMetadataItems = filterBySearchQuery({
|
||||
items: objectsWithReadAccess,
|
||||
items: isAdvancedObjectsMenuOpened ? systemObjects : regularObjects,
|
||||
searchQuery,
|
||||
getSearchableValues: (item) => [item.labelPlural, item.namePlural],
|
||||
});
|
||||
@@ -64,14 +81,47 @@ export const ChartDataSourceDropdownContent = () => {
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const handleSelectSource = (objectMetadataId: string) => {
|
||||
updateCurrentWidgetConfig({
|
||||
objectMetadataId,
|
||||
});
|
||||
if (currentSource !== objectMetadataId) {
|
||||
updateCurrentWidgetConfig({
|
||||
objectMetadataId,
|
||||
configToUpdate: {
|
||||
aggregateFieldMetadataId: null,
|
||||
groupByFieldMetadataIdX: null,
|
||||
groupByFieldMetadataIdY: null,
|
||||
groupBySubFieldNameX: null,
|
||||
groupBySubFieldNameY: null,
|
||||
groupByFieldMetadataId: null,
|
||||
groupBySubFieldName: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
const handleAdvancedObjectsClick = () => {
|
||||
setIsAdvancedObjectsMenuOpened(true);
|
||||
setSearchQuery('');
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setIsAdvancedObjectsMenuOpened(false);
|
||||
setSearchQuery('');
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{isAdvancedObjectsMenuOpened && (
|
||||
<DropdownMenuHeader
|
||||
StartComponent={
|
||||
<DropdownMenuHeaderLeftComponent
|
||||
onClick={handleBack}
|
||||
Icon={IconChevronLeft}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Trans>Advanced objects</Trans>
|
||||
</DropdownMenuHeader>
|
||||
)}
|
||||
<DropdownMenuSearchInput
|
||||
autoFocus
|
||||
type="text"
|
||||
@@ -84,9 +134,14 @@ export const ChartDataSourceDropdownContent = () => {
|
||||
<SelectableList
|
||||
selectableListInstanceId={dropdownId}
|
||||
focusId={dropdownId}
|
||||
selectableItemIdArray={availableObjectMetadataItems.map(
|
||||
(objectMetadataItem) => objectMetadataItem.id,
|
||||
)}
|
||||
selectableItemIdArray={[
|
||||
...availableObjectMetadataItems.map(
|
||||
(objectMetadataItem) => objectMetadataItem.id,
|
||||
),
|
||||
...(!isAdvancedObjectsMenuOpened
|
||||
? [ADVANCED_OBJECTS_MENU_ITEM_ID]
|
||||
: []),
|
||||
]}
|
||||
>
|
||||
{availableObjectMetadataItems.map((objectMetadataItem) => (
|
||||
<SelectableListItem
|
||||
@@ -107,6 +162,19 @@ export const ChartDataSourceDropdownContent = () => {
|
||||
/>
|
||||
</SelectableListItem>
|
||||
))}
|
||||
{!isAdvancedObjectsMenuOpened && (
|
||||
<SelectableListItem
|
||||
itemId={ADVANCED_OBJECTS_MENU_ITEM_ID}
|
||||
onEnter={handleAdvancedObjectsClick}
|
||||
>
|
||||
<MenuItem
|
||||
text={t`Advanced objects`}
|
||||
LeftIcon={IconSettings}
|
||||
onClick={handleAdvancedObjectsClick}
|
||||
hasSubMenu
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
</SelectableList>
|
||||
</DropdownMenuItemsContainer>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user