Add calendar date field submenu with grouped field options (#23445)
## Summary - Add a submenu for selecting calendar date fields as it was not clear enough that you could pick 2 date fields. - Group date and datetime fields with non-selectable headers ### Before <img width="240" height="252" alt="Screenshot 2026-07-29 at 11 32 54" src="https://github.com/user-attachments/assets/169bd965-676f-4ef9-8ba6-9ecac80547c6" /> ### After <img width="260" height="246" alt="Screenshot 2026-07-29 at 11 31 58" src="https://github.com/user-attachments/assets/a4471bb0-5c1f-4f5e-bddb-165a5c9da4c7" />
This commit is contained in:
+95
@@ -0,0 +1,95 @@
|
||||
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
||||
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
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 { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconCalendar, IconChevronLeft } from 'twenty-ui/icon';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
|
||||
export const ObjectOptionsDropdownCalendarDateFieldsContent = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const { objectMetadataItem, resetContent, onContentChange } =
|
||||
useObjectOptionsDropdown();
|
||||
|
||||
const { currentView } = useGetCurrentViewOnly();
|
||||
|
||||
const selectedItemId = useAtomComponentStateValue(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
if (!isDefined(currentView)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const calendarFieldMetadata = objectMetadataItem.fields.find(
|
||||
(field) => field.id === currentView.calendarFieldMetadataId,
|
||||
);
|
||||
|
||||
const calendarEndFieldMetadata = objectMetadataItem.fields.find(
|
||||
(field) => field.id === currentView.calendarEndFieldMetadataId,
|
||||
);
|
||||
|
||||
const selectableItemIdArray = ['CalendarDateField', 'CalendarEndDateField'];
|
||||
|
||||
return (
|
||||
<DropdownContent widthInPixels={GenericDropdownContentWidth.Large}>
|
||||
<DropdownMenuHeader
|
||||
StartComponent={
|
||||
<DropdownMenuHeaderLeftComponent
|
||||
onClick={() => resetContent()}
|
||||
Icon={IconChevronLeft}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{t`Date fields`}
|
||||
</DropdownMenuHeader>
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
<SelectableList
|
||||
selectableListInstanceId={OBJECT_OPTIONS_DROPDOWN_ID}
|
||||
focusId={OBJECT_OPTIONS_DROPDOWN_ID}
|
||||
selectableItemIdArray={selectableItemIdArray}
|
||||
>
|
||||
<SelectableListItem
|
||||
itemId="CalendarDateField"
|
||||
onEnter={() => onContentChange('calendarFields')}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'CalendarDateField'}
|
||||
onClick={() => onContentChange('calendarFields')}
|
||||
LeftIcon={IconCalendar}
|
||||
text={t`Date field`}
|
||||
contextualText={calendarFieldMetadata?.label}
|
||||
contextualTextPosition="right"
|
||||
hasSubMenu
|
||||
/>
|
||||
</SelectableListItem>
|
||||
<SelectableListItem
|
||||
itemId="CalendarEndDateField"
|
||||
onEnter={() => onContentChange('calendarEndFields')}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'CalendarEndDateField'}
|
||||
onClick={() => onContentChange('calendarEndFields')}
|
||||
LeftIcon={IconCalendar}
|
||||
text={t`End date field`}
|
||||
contextualText={calendarEndFieldMetadata?.label ?? t`None`}
|
||||
contextualTextPosition="right"
|
||||
hasSubMenu
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</SelectableList>
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
);
|
||||
};
|
||||
+25
-13
@@ -2,11 +2,13 @@ import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSe
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||
import { recordIndexCalendarEndFieldMetadataIdComponentState } from '@/object-record/record-index/states/recordIndexCalendarEndFieldMetadataIdComponentState';
|
||||
import { groupCalendarFieldMetadataItemsByType } from '@/object-record/record-calendar/utils/groupCalendarFieldMetadataItemsByType';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
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 { DropdownMenuSectionLabel } from '@/ui/layout/dropdown/components/DropdownMenuSectionLabel';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
|
||||
@@ -14,7 +16,7 @@ import { useGetAvailableFieldsForCalendar } from '@/views/view-picker/hooks/useG
|
||||
import { getAvailableCalendarEndFieldMetadataItems } from '@/views/view-picker/utils/getAvailableCalendarEndFieldMetadataItems';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { Fragment, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconChevronLeft, useIcons } from 'twenty-ui/icon';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
@@ -28,7 +30,7 @@ export const ObjectOptionsDropdownCalendarEndFieldsContent = () => {
|
||||
FeatureFlagKey.IS_CALENDAR_WEEK_VIEW_ENABLED,
|
||||
);
|
||||
|
||||
const { resetContent, closeDropdown } = useObjectOptionsDropdown();
|
||||
const { onContentChange, closeDropdown } = useObjectOptionsDropdown();
|
||||
|
||||
const { currentView } = useGetCurrentViewOnly();
|
||||
const { updateCurrentView } = useUpdateCurrentView();
|
||||
@@ -49,6 +51,10 @@ export const ObjectOptionsDropdownCalendarEndFieldsContent = () => {
|
||||
field.label.toLowerCase().includes(searchInput.toLowerCase()),
|
||||
);
|
||||
|
||||
const calendarEndFieldGroups = groupCalendarFieldMetadataItemsByType(
|
||||
filteredCalendarEndFields,
|
||||
);
|
||||
|
||||
const handleCalendarEndFieldChange = async (
|
||||
fieldMetadataItem: FieldMetadataItem | null,
|
||||
) => {
|
||||
@@ -72,7 +78,7 @@ export const ObjectOptionsDropdownCalendarEndFieldsContent = () => {
|
||||
<DropdownMenuHeader
|
||||
StartComponent={
|
||||
<DropdownMenuHeaderLeftComponent
|
||||
onClick={() => resetContent()}
|
||||
onClick={() => onContentChange('calendarDateFields')}
|
||||
Icon={IconChevronLeft}
|
||||
/>
|
||||
}
|
||||
@@ -92,16 +98,22 @@ export const ObjectOptionsDropdownCalendarEndFieldsContent = () => {
|
||||
onClick={() => handleCalendarEndFieldChange(null)}
|
||||
text={t`None`}
|
||||
/>
|
||||
{filteredCalendarEndFields.map((fieldMetadataItem) => (
|
||||
<MenuItemSelect
|
||||
key={fieldMetadataItem.id}
|
||||
selected={
|
||||
fieldMetadataItem.id === currentView?.calendarEndFieldMetadataId
|
||||
}
|
||||
onClick={() => handleCalendarEndFieldChange(fieldMetadataItem)}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
text={fieldMetadataItem.label}
|
||||
/>
|
||||
{calendarEndFieldGroups.map((group) => (
|
||||
<Fragment key={group.label}>
|
||||
<DropdownMenuSectionLabel label={group.label} />
|
||||
{group.fields.map((fieldMetadataItem) => (
|
||||
<MenuItemSelect
|
||||
key={fieldMetadataItem.id}
|
||||
selected={
|
||||
fieldMetadataItem.id ===
|
||||
currentView?.calendarEndFieldMetadataId
|
||||
}
|
||||
onClick={() => handleCalendarEndFieldChange(fieldMetadataItem)}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
text={fieldMetadataItem.label}
|
||||
/>
|
||||
))}
|
||||
</Fragment>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
|
||||
+42
-12
@@ -3,27 +3,34 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataIte
|
||||
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||
import { recordIndexCalendarEndFieldMetadataIdComponentState } from '@/object-record/record-index/states/recordIndexCalendarEndFieldMetadataIdComponentState';
|
||||
import { recordIndexCalendarFieldMetadataIdComponentState } from '@/object-record/record-index/states/recordIndexCalendarFieldMetadataIdComponentState';
|
||||
import { groupCalendarFieldMetadataItemsByType } from '@/object-record/record-calendar/utils/groupCalendarFieldMetadataItemsByType';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
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 { DropdownMenuSectionLabel } from '@/ui/layout/dropdown/components/DropdownMenuSectionLabel';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
|
||||
import { useGetAvailableFieldsForCalendar } from '@/views/view-picker/hooks/useGetAvailableFieldsForCalendar';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { Fragment, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconChevronLeft, IconSettings, useIcons } from 'twenty-ui/icon';
|
||||
import { MenuItem, MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
export const ObjectOptionsDropdownCalendarFieldsContent = () => {
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const [searchInput, setSearchInput] = useState('');
|
||||
const isCalendarWeekViewEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_CALENDAR_WEEK_VIEW_ENABLED,
|
||||
);
|
||||
|
||||
const { objectMetadataItem, resetContent, closeDropdown } =
|
||||
const { objectMetadataItem, resetContent, onContentChange, closeDropdown } =
|
||||
useObjectOptionsDropdown();
|
||||
|
||||
const { currentView } = useGetCurrentViewOnly();
|
||||
@@ -50,10 +57,28 @@ export const ObjectOptionsDropdownCalendarFieldsContent = () => {
|
||||
)
|
||||
: undefined;
|
||||
|
||||
const filteredCalendarFields = availableFieldsForCalendar.filter((field) =>
|
||||
const availableCalendarFields = isDefined(calendarEndFieldMetadata)
|
||||
? availableFieldsForCalendar.filter(
|
||||
(field) => field.type === calendarEndFieldMetadata.type,
|
||||
)
|
||||
: availableFieldsForCalendar;
|
||||
|
||||
const filteredCalendarFields = availableCalendarFields.filter((field) =>
|
||||
field.label.toLowerCase().includes(searchInput.toLowerCase()),
|
||||
);
|
||||
|
||||
const calendarFieldGroups = groupCalendarFieldMetadataItemsByType(
|
||||
filteredCalendarFields,
|
||||
);
|
||||
|
||||
const handleBack = () => {
|
||||
if (isCalendarWeekViewEnabled) {
|
||||
onContentChange('calendarDateFields');
|
||||
return;
|
||||
}
|
||||
resetContent();
|
||||
};
|
||||
|
||||
const handleCalendarFieldChange = async (
|
||||
fieldMetadataItem: FieldMetadataItem,
|
||||
) => {
|
||||
@@ -82,7 +107,7 @@ export const ObjectOptionsDropdownCalendarFieldsContent = () => {
|
||||
<DropdownMenuHeader
|
||||
StartComponent={
|
||||
<DropdownMenuHeaderLeftComponent
|
||||
onClick={() => resetContent()}
|
||||
onClick={handleBack}
|
||||
Icon={IconChevronLeft}
|
||||
/>
|
||||
}
|
||||
@@ -97,14 +122,19 @@ export const ObjectOptionsDropdownCalendarFieldsContent = () => {
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer>
|
||||
{filteredCalendarFields.map((fieldMetadataItem) => (
|
||||
<MenuItemSelect
|
||||
key={fieldMetadataItem.id}
|
||||
selected={fieldMetadataItem.id === calendarFieldMetadata?.id}
|
||||
onClick={() => handleCalendarFieldChange(fieldMetadataItem)}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
text={fieldMetadataItem.label}
|
||||
/>
|
||||
{calendarFieldGroups.map((group) => (
|
||||
<Fragment key={group.label}>
|
||||
<DropdownMenuSectionLabel label={group.label} />
|
||||
{group.fields.map((fieldMetadataItem) => (
|
||||
<MenuItemSelect
|
||||
key={fieldMetadataItem.id}
|
||||
selected={fieldMetadataItem.id === calendarFieldMetadata?.id}
|
||||
onClick={() => handleCalendarFieldChange(fieldMetadataItem)}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
text={fieldMetadataItem.label}
|
||||
/>
|
||||
))}
|
||||
</Fragment>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
+7
@@ -1,4 +1,5 @@
|
||||
import { ObjectOptionsDropdownAddRecordGroupContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownAddRecordGroupContent';
|
||||
import { ObjectOptionsDropdownCalendarDateFieldsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarDateFieldsContent';
|
||||
import { ObjectOptionsDropdownCalendarFieldsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarFieldsContent';
|
||||
import { ObjectOptionsDropdownCalendarEndFieldsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarEndFieldsContent';
|
||||
import { ObjectOptionsDropdownCalendarViewContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent';
|
||||
@@ -43,6 +44,12 @@ export const ObjectOptionsDropdownContent = () => {
|
||||
return <ObjectOptionsDropdownAddRecordGroupContent />;
|
||||
case 'calendarView':
|
||||
return <ObjectOptionsDropdownCalendarViewContent />;
|
||||
case 'calendarDateFields':
|
||||
return isCalendarWeekViewEnabled ? (
|
||||
<ObjectOptionsDropdownCalendarDateFieldsContent />
|
||||
) : (
|
||||
<ObjectOptionsDropdownMenuContent />
|
||||
);
|
||||
case 'calendarFields':
|
||||
return <ObjectOptionsDropdownCalendarFieldsContent />;
|
||||
case 'calendarEndFields':
|
||||
|
||||
+33
-37
@@ -74,12 +74,6 @@ export const ObjectOptionsDropdownCustomView = ({
|
||||
)
|
||||
: undefined;
|
||||
|
||||
const calendarEndFieldMetadata = currentView?.calendarEndFieldMetadataId
|
||||
? objectMetadataItem.fields.find(
|
||||
(field) => field.id === currentView.calendarEndFieldMetadataId,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
const viewsOnCurrentObject = useAtomFamilySelectorValue(
|
||||
viewsFromObjectMetadataItemFamilySelector,
|
||||
{ objectMetadataItemId: objectMetadataItem.id },
|
||||
@@ -129,8 +123,9 @@ export const ObjectOptionsDropdownCustomView = ({
|
||||
'Fields',
|
||||
...(customViewData?.type === ViewType.CALENDAR
|
||||
? [
|
||||
'CalendarDateField',
|
||||
...(isCalendarWeekViewEnabled ? ['CalendarEndDateField'] : []),
|
||||
isCalendarWeekViewEnabled
|
||||
? 'CalendarDateFields'
|
||||
: 'CalendarDateField',
|
||||
'CalendarView',
|
||||
]
|
||||
: []),
|
||||
@@ -196,42 +191,43 @@ export const ObjectOptionsDropdownCustomView = ({
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
{customViewData?.type === ViewType.CALENDAR && (
|
||||
<>
|
||||
<div id="calendar-date-field-picker-menu-item">
|
||||
<SelectableListItem
|
||||
itemId="CalendarDateField"
|
||||
onEnter={() => onContentChange('calendarFields')}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'CalendarDateField'}
|
||||
onClick={() => onContentChange('calendarFields')}
|
||||
LeftIcon={IconCalendar}
|
||||
text={t`Date field`}
|
||||
contextualText={
|
||||
isDefaultView
|
||||
? t`Not available on Default View`
|
||||
: calendarFieldMetadata?.label
|
||||
}
|
||||
contextualTextPosition="right"
|
||||
hasSubMenu
|
||||
disabled={isDefaultView}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</div>
|
||||
{isCalendarWeekViewEnabled && (
|
||||
<div id="calendar-end-date-field-picker-menu-item">
|
||||
{isCalendarWeekViewEnabled ? (
|
||||
<div id="calendar-date-fields-picker-menu-item">
|
||||
<SelectableListItem
|
||||
itemId="CalendarEndDateField"
|
||||
onEnter={() => onContentChange('calendarEndFields')}
|
||||
itemId="CalendarDateFields"
|
||||
onEnter={() => onContentChange('calendarDateFields')}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'CalendarEndDateField'}
|
||||
onClick={() => onContentChange('calendarEndFields')}
|
||||
focused={selectedItemId === 'CalendarDateFields'}
|
||||
onClick={() => onContentChange('calendarDateFields')}
|
||||
LeftIcon={IconCalendar}
|
||||
text={t`End date field`}
|
||||
text={t`Date fields`}
|
||||
contextualText={
|
||||
isDefaultView
|
||||
? t`Not available on Default View`
|
||||
: (calendarEndFieldMetadata?.label ?? t`None`)
|
||||
: calendarFieldMetadata?.label
|
||||
}
|
||||
contextualTextPosition="right"
|
||||
hasSubMenu
|
||||
disabled={isDefaultView}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</div>
|
||||
) : (
|
||||
<div id="calendar-date-field-picker-menu-item">
|
||||
<SelectableListItem
|
||||
itemId="CalendarDateField"
|
||||
onEnter={() => onContentChange('calendarFields')}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'CalendarDateField'}
|
||||
onClick={() => onContentChange('calendarFields')}
|
||||
LeftIcon={IconCalendar}
|
||||
text={t`Date field`}
|
||||
contextualText={
|
||||
isDefaultView
|
||||
? t`Not available on Default View`
|
||||
: calendarFieldMetadata?.label
|
||||
}
|
||||
contextualTextPosition="right"
|
||||
hasSubMenu
|
||||
|
||||
+25
-31
@@ -87,12 +87,6 @@ export const ObjectOptionsDropdownLayoutContent = () => {
|
||||
)
|
||||
: undefined;
|
||||
|
||||
const calendarEndFieldMetadata = currentView?.calendarEndFieldMetadataId
|
||||
? objectMetadataItem.fields.find(
|
||||
(field) => field.id === currentView.calendarEndFieldMetadataId,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
const { setAndPersistViewType } = useSetViewTypeFromLayoutOptionsMenu();
|
||||
const { availableFieldsForGrouping, navigateToSelectSettings } =
|
||||
useGetAvailableFieldsToGroupRecordsBy();
|
||||
@@ -140,8 +134,9 @@ export const ObjectOptionsDropdownLayoutContent = () => {
|
||||
...(currentView?.type === ViewType.CALENDAR
|
||||
? [
|
||||
'CalendarView',
|
||||
'CalendarDateField',
|
||||
...(isCalendarWeekViewEnabled ? ['CalendarEndDateField'] : []),
|
||||
isCalendarWeekViewEnabled
|
||||
? 'CalendarDateFields'
|
||||
: 'CalendarDateField',
|
||||
]
|
||||
: []),
|
||||
...(currentView?.type !== ViewType.TABLE ? ['Compact view'] : []),
|
||||
@@ -237,33 +232,32 @@ export const ObjectOptionsDropdownLayoutContent = () => {
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
{currentView?.type === ViewType.CALENDAR && (
|
||||
<>
|
||||
<SelectableListItem
|
||||
itemId="CalendarDateField"
|
||||
onEnter={() => onContentChange('calendarFields')}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'CalendarDateField'}
|
||||
onClick={() => onContentChange('calendarFields')}
|
||||
LeftIcon={IconCalendar}
|
||||
text={t`Date field`}
|
||||
contextualText={calendarFieldMetadata?.label}
|
||||
contextualTextPosition="right"
|
||||
hasSubMenu
|
||||
/>
|
||||
</SelectableListItem>
|
||||
{isCalendarWeekViewEnabled && (
|
||||
{isCalendarWeekViewEnabled ? (
|
||||
<SelectableListItem
|
||||
itemId="CalendarEndDateField"
|
||||
onEnter={() => onContentChange('calendarEndFields')}
|
||||
itemId="CalendarDateFields"
|
||||
onEnter={() => onContentChange('calendarDateFields')}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'CalendarEndDateField'}
|
||||
onClick={() => onContentChange('calendarEndFields')}
|
||||
focused={selectedItemId === 'CalendarDateFields'}
|
||||
onClick={() => onContentChange('calendarDateFields')}
|
||||
LeftIcon={IconCalendar}
|
||||
text={t`End date field`}
|
||||
contextualText={
|
||||
calendarEndFieldMetadata?.label ?? t`None`
|
||||
}
|
||||
text={t`Date fields`}
|
||||
contextualText={calendarFieldMetadata?.label}
|
||||
contextualTextPosition="right"
|
||||
hasSubMenu
|
||||
/>
|
||||
</SelectableListItem>
|
||||
) : (
|
||||
<SelectableListItem
|
||||
itemId="CalendarDateField"
|
||||
onEnter={() => onContentChange('calendarFields')}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'CalendarDateField'}
|
||||
onClick={() => onContentChange('calendarFields')}
|
||||
LeftIcon={IconCalendar}
|
||||
text={t`Date field`}
|
||||
contextualText={calendarFieldMetadata?.label}
|
||||
contextualTextPosition="right"
|
||||
hasSubMenu
|
||||
/>
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ export type ObjectOptionsContentId =
|
||||
| 'recordGroupFields'
|
||||
| 'recordGroupSort'
|
||||
| 'addRecordGroup'
|
||||
| 'calendarDateFields'
|
||||
| 'calendarFields'
|
||||
| 'calendarEndFields'
|
||||
| 'calendarView'
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
const CALENDAR_FIELD_METADATA_TYPES = [
|
||||
FieldMetadataType.DATE,
|
||||
FieldMetadataType.DATE_TIME,
|
||||
] as const;
|
||||
|
||||
export const groupCalendarFieldMetadataItemsByType = <
|
||||
T extends Pick<FieldMetadataItem, 'type'>,
|
||||
>(
|
||||
fieldMetadataItems: T[],
|
||||
) =>
|
||||
CALENDAR_FIELD_METADATA_TYPES.map((fieldMetadataType) => ({
|
||||
label: SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS[fieldMetadataType].label,
|
||||
fields: fieldMetadataItems.filter(
|
||||
(fieldMetadataItem) => fieldMetadataItem.type === fieldMetadataType,
|
||||
),
|
||||
})).filter((group) => group.fields.length > 0);
|
||||
Reference in New Issue
Block a user