Add fields selection in calendar view (#14500)

This commit is contained in:
Weiko
2025-09-15 15:28:05 +02:00
committed by GitHub
parent 0a0fb2e3b7
commit 9853d6c095
4 changed files with 82 additions and 39 deletions
@@ -1,5 +1,6 @@
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
import { recordIndexCalendarFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexCalendarFieldMetadataIdState';
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';
@@ -11,6 +12,7 @@ import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
import { useGetAvailableFieldsForCalendar } from '@/views/view-picker/hooks/useGetAvailableFieldsForCalendar';
import { useLingui } from '@lingui/react/macro';
import { useState } from 'react';
import { useSetRecoilState } from 'recoil';
import { IconChevronLeft, IconSettings, useIcons } from 'twenty-ui/display';
import { MenuItem, MenuItemSelect } from 'twenty-ui/navigation';
import { FieldMetadataType } from '~/generated-metadata/graphql';
@@ -27,6 +29,9 @@ export const ObjectOptionsDropdownCalendarFieldsContent = () => {
const { updateCurrentView } = useUpdateCurrentView();
const { navigateToDateFieldSettings } = useGetAvailableFieldsForCalendar();
const setRecordIndexCalendarFieldMetadataId = useSetRecoilState(
recordIndexCalendarFieldMetadataIdState,
);
const availableFieldsForCalendar = objectMetadataItem.fields.filter(
(field) =>
field.type === FieldMetadataType.DATE ||
@@ -46,6 +51,7 @@ export const ObjectOptionsDropdownCalendarFieldsContent = () => {
const handleCalendarFieldChange = async (
fieldMetadataItem: FieldMetadataItem,
) => {
setRecordIndexCalendarFieldMetadataId(fieldMetadataItem.id);
await updateCurrentView({
calendarFieldMetadataId: fieldMetadataItem.id,
});
@@ -97,7 +97,7 @@ export const ObjectOptionsDropdownCustomView = ({
const selectableItemIdArray = [
'Layout',
...(customViewData?.type !== ViewType.Calendar ? ['Fields'] : []),
'Fields',
...(customViewData?.type === ViewType.Calendar
? ['CalendarDateField', 'CalendarView']
: []),
@@ -185,50 +185,48 @@ export const ObjectOptionsDropdownCustomView = ({
</SelectableListItem>
</>
)}
<SelectableListItem
itemId="Fields"
onEnter={() => onContentChange('fields')}
>
<MenuItem
focused={selectedItemId === 'Fields'}
onClick={() => onContentChange('fields')}
LeftIcon={IconListDetails}
text={t`Fields`}
contextualText={`${visibleBoardFields.length} shown`}
hasSubMenu
/>
</SelectableListItem>
{customViewData?.type !== ViewType.Calendar && (
<>
<div id="group-by-menu-item">
<SelectableListItem
itemId="Fields"
onEnter={() => onContentChange('fields')}
itemId="Group"
onEnter={() =>
isDefined(recordGroupFieldMetadata)
? onContentChange('recordGroups')
: onContentChange('recordGroupFields')
}
>
<MenuItem
focused={selectedItemId === 'Fields'}
onClick={() => onContentChange('fields')}
LeftIcon={IconListDetails}
text={t`Fields`}
contextualText={`${visibleBoardFields.length} shown`}
hasSubMenu
/>
</SelectableListItem>
<div id="group-by-menu-item">
<SelectableListItem
itemId="Group"
onEnter={() =>
focused={selectedItemId === 'Group'}
onClick={() =>
isDefined(recordGroupFieldMetadata)
? onContentChange('recordGroups')
: onContentChange('recordGroupFields')
}
>
<MenuItem
focused={selectedItemId === 'Group'}
onClick={() =>
isDefined(recordGroupFieldMetadata)
? onContentChange('recordGroups')
: onContentChange('recordGroupFields')
}
LeftIcon={IconLayoutList}
text={t`Group`}
contextualText={
isDefaultView
? t`Not available on Default View`
: recordGroupFieldMetadata?.label
}
hasSubMenu
disabled={isDefaultView}
/>
</SelectableListItem>
</div>
</>
LeftIcon={IconLayoutList}
text={t`Group`}
contextualText={
isDefaultView
? t`Not available on Default View`
: recordGroupFieldMetadata?.label
}
hasSubMenu
disabled={isDefaultView}
/>
</SelectableListItem>
</div>
)}
{isDefaultView && (
<AppTooltip
@@ -1,7 +1,10 @@
import { RecordCalendarComponentInstanceContext } from '@/object-record/record-calendar/states/contexts/RecordCalendarComponentInstanceContext';
import { recordIndexCalendarLayoutState } from '@/object-record/record-index/states/recordIndexCalendarLayoutState';
import { Select } from '@/ui/input/components/Select';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { ViewCalendarLayout } from '~/generated/graphql';
const StyledContainer = styled.div`
display: flex;
@@ -13,6 +16,10 @@ export const RecordCalendarTopBar = () => {
RecordCalendarComponentInstanceContext,
);
const recordIndexCalendarLayout = useRecoilValue(
recordIndexCalendarLayoutState,
);
return (
<StyledContainer>
<Select
@@ -21,10 +28,19 @@ export const RecordCalendarTopBar = () => {
options={[
{
label: 'Month',
value: 'MONTH',
value: ViewCalendarLayout.MONTH,
},
{
label: 'Week',
value: ViewCalendarLayout.WEEK,
},
{
label: 'Timeline',
value: ViewCalendarLayout.DAY,
},
]}
value={''}
disabled
value={recordIndexCalendarLayout}
onChange={() => {}}
/>
</StyledContainer>
@@ -6,8 +6,10 @@ import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/ho
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { coreViewsFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreViewsFromObjectMetadataItemFamilySelector';
import { viewTypeIconMapping } from '@/views/types/ViewType';
import { useGetAvailableFieldsForCalendar } from '@/views/view-picker/hooks/useGetAvailableFieldsForCalendar';
import { useGetAvailableFieldsForKanban } from '@/views/view-picker/hooks/useGetAvailableFieldsForKanban';
import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode';
import { viewPickerCalendarFieldMetadataIdComponentState } from '@/views/view-picker/states/viewPickerCalendarFieldMetadataIdComponentState';
import { viewPickerInputNameComponentState } from '@/views/view-picker/states/viewPickerInputNameComponentState';
import { viewPickerIsDirtyComponentState } from '@/views/view-picker/states/viewPickerIsDirtyComponentState';
import { viewPickerIsPersistingComponentState } from '@/views/view-picker/states/viewPickerIsPersistingComponentState';
@@ -30,6 +32,11 @@ export const ViewPickerContentEffect = () => {
const [viewPickerKanbanFieldMetadataId, setViewPickerKanbanFieldMetadataId] =
useRecoilComponentState(viewPickerKanbanFieldMetadataIdComponentState);
const [
viewPickerCalendarFieldMetadataId,
setViewPickerCalendarFieldMetadataId,
] = useRecoilComponentState(viewPickerCalendarFieldMetadataIdComponentState);
const [viewPickerType, setViewPickerType] = useRecoilComponentState(
viewPickerTypeComponentState,
);
@@ -58,6 +65,7 @@ export const ViewPickerContentEffect = () => {
);
const { availableFieldsForKanban } = useGetAvailableFieldsForKanban();
const { availableFieldsForCalendar } = useGetAvailableFieldsForCalendar();
useEffect(() => {
if (
@@ -100,11 +108,26 @@ export const ViewPickerContentEffect = () => {
: availableFieldsForKanban[0].id,
);
}
if (
isDefined(referenceView) &&
availableFieldsForCalendar.length > 0 &&
viewPickerCalendarFieldMetadataId === ''
) {
setViewPickerCalendarFieldMetadataId(
isDefined(referenceView.calendarFieldMetadataId) &&
referenceView.calendarFieldMetadataId !== ''
? referenceView.calendarFieldMetadataId
: availableFieldsForCalendar[0].id,
);
}
}, [
referenceView,
availableFieldsForKanban,
viewPickerKanbanFieldMetadataId,
setViewPickerKanbanFieldMetadataId,
availableFieldsForCalendar,
viewPickerCalendarFieldMetadataId,
setViewPickerCalendarFieldMetadataId,
]);
return <></>;