Baptiste Devessier
2026-02-20 14:18:00 +01:00
committed by GitHub
parent b107020ad3
commit 00209f7e2c
136 changed files with 4875 additions and 835 deletions
@@ -3,12 +3,15 @@ import { SidePanelSubPageNavigationHeader } from '@/command-menu/pages/common/co
import { usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord } from '@/command-menu/pages/page-layout/hooks/usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord';
import { useWidgetInEditMode } from '@/command-menu/pages/page-layout/hooks/useWidgetInEditMode';
import { useTemporaryFieldsConfiguration } from '@/page-layout/hooks/useTemporaryFieldsConfiguration';
import { type FieldsConfiguration } from '@/page-layout/types/FieldsConfiguration';
import { FieldsConfigurationEditor } from '@/page-layout/widgets/fields/components/FieldsConfigurationEditor';
import { FieldsWidgetGroupsDraftInitializationEffect } from '@/page-layout/widgets/fields/components/FieldsWidgetGroupsDraftInitializationEffect';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import {
type FieldsConfiguration,
WidgetConfigurationType,
} from '~/generated-metadata/graphql';
const StyledOuterContainer = styled.div`
display: flex;
@@ -28,25 +31,23 @@ const StyledContainer = styled.div`
export const CommandMenuPageLayoutFieldsLayout = () => {
const { goBackFromCommandMenu } = useCommandMenuHistory();
const { pageLayoutId, objectNameSingular } =
const { pageLayoutId } =
usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord();
const { widgetInEditMode } = useWidgetInEditMode(pageLayoutId);
const defaultFieldsConfiguration =
useTemporaryFieldsConfiguration(objectNameSingular);
const [fieldsConfiguration, setFieldsConfiguration] =
useState<FieldsConfiguration>(defaultFieldsConfiguration);
const temporaryFieldsConfiguration = useTemporaryFieldsConfiguration();
if (!isDefined(widgetInEditMode)) {
return null;
}
const handleConfigurationChange = (
updatedConfiguration: FieldsConfiguration,
) => {
// TODO: replace with a call to updatePageLayoutWidget
setFieldsConfiguration(updatedConfiguration);
};
const widgetConfiguration = widgetInEditMode.configuration;
const fieldsConfiguration: FieldsConfiguration =
isDefined(widgetConfiguration) &&
widgetConfiguration.configurationType === WidgetConfigurationType.FIELDS
? (widgetConfiguration as FieldsConfiguration)
: temporaryFieldsConfiguration;
return (
<StyledOuterContainer>
@@ -55,9 +56,14 @@ export const CommandMenuPageLayoutFieldsLayout = () => {
onBackClick={goBackFromCommandMenu}
/>
<StyledContainer>
<FieldsWidgetGroupsDraftInitializationEffect
viewId={fieldsConfiguration.viewId ?? null}
pageLayoutId={pageLayoutId}
widgetId={widgetInEditMode.id}
/>
<FieldsConfigurationEditor
configuration={fieldsConfiguration}
onChange={handleConfigurationChange}
pageLayoutId={pageLayoutId}
widgetId={widgetInEditMode.id}
/>
</StyledContainer>
</StyledOuterContainer>
@@ -6,12 +6,13 @@ import { useNavigatePageLayoutCommandMenu } from '@/command-menu/pages/page-layo
import { usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord } from '@/command-menu/pages/page-layout/hooks/usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord';
import { useWidgetInEditMode } from '@/command-menu/pages/page-layout/hooks/useWidgetInEditMode';
import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages';
import { useTemporaryFieldsConfiguration } from '@/page-layout/hooks/useTemporaryFieldsConfiguration';
import { useFieldsWidgetGroups } from '@/page-layout/widgets/fields/hooks/useFieldsWidgetGroups';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { isDefined } from 'twenty-shared/utils';
import { IconLayoutSidebarRight } from 'twenty-ui/display';
import { type FieldsConfiguration } from '~/generated-metadata/graphql';
const StyledContainer = styled.div`
display: flex;
@@ -33,15 +34,22 @@ export const CommandMenuPageLayoutFieldsSettings = () => {
usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord();
const { widgetInEditMode } = useWidgetInEditMode(pageLayoutId);
const fieldsConfiguration =
useTemporaryFieldsConfiguration(objectNameSingular);
const fieldsConfiguration = widgetInEditMode?.configuration as
| FieldsConfiguration
| undefined;
const { groups } = useFieldsWidgetGroups({
viewId: fieldsConfiguration?.viewId ?? null,
objectNameSingular,
});
if (!isDefined(widgetInEditMode)) {
return null;
}
const totalFieldsCount = fieldsConfiguration.sections.reduce(
(count, section) => count + section.fields.length,
const totalFieldsCount = groups.reduce(
(count, group) => count + group.fields.length,
0,
);
@@ -5,7 +5,6 @@ import { type ChartConfiguration } from '@/command-menu/pages/page-layout/types/
import { getDateGranularityLabel } from '@/command-menu/pages/page-layout/utils/getDateGranularityLabel';
import { isWidgetConfigurationOfType } from '@/command-menu/pages/page-layout/utils/isWidgetConfigurationOfType';
import { type FieldConfiguration } from '@/page-layout/types/FieldConfiguration';
import { type FieldsConfiguration } from '@/page-layout/types/FieldsConfiguration';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
@@ -17,7 +16,10 @@ import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useR
import { ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { MenuItemSelect } from 'twenty-ui/navigation';
import { type WidgetConfiguration } from '~/generated-metadata/graphql';
import {
type FieldsConfiguration,
type WidgetConfiguration,
} from '~/generated-metadata/graphql';
type ChartDateGranularitySelectionDropdownContentProps = {
axis?: 'primary' | 'secondary';
@@ -32,10 +32,7 @@ export const usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord =
throw new Error('Only one record should be selected');
}
const recordId: string = targetedRecordsRule.selectedRecordIds[0];
const { pageLayoutId } = useRecordPageLayoutIdFromRecordStoreOrThrow({
id: recordId,
targetObjectNameSingular: objectMetadataItem.nameSingular,
});
@@ -1,13 +1,9 @@
import { type ChartWidget } from '@/command-menu/pages/page-layout/types/ChartWidget';
import { isWidgetConfigurationOfTypeGraph } from '@/command-menu/pages/page-layout/utils/isWidgetConfigurationOfTypeGraph';
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
import { type WidgetConfiguration } from '~/generated-metadata/graphql';
export const isChartWidget = (
pageLayoutWidget: PageLayoutWidget,
): pageLayoutWidget is ChartWidget => {
return isWidgetConfigurationOfTypeGraph(
// TODO: Remove this cast when we FieldsConfiguration and FieldConfiguration are in the backend
pageLayoutWidget.configuration as WidgetConfiguration,
);
return isWidgetConfigurationOfTypeGraph(pageLayoutWidget.configuration);
};
@@ -1,11 +1,11 @@
import { type FieldConfiguration } from '@/page-layout/types/FieldConfiguration';
import { type FieldsConfiguration } from '@/page-layout/types/FieldsConfiguration';
import {
type AggregateChartConfiguration,
type BarChartConfiguration,
type CalendarConfiguration,
type EmailsConfiguration,
type FieldRichTextConfiguration,
type FieldsConfiguration,
type FilesConfiguration,
type FrontComponentConfiguration,
type GaugeChartConfiguration,
@@ -1,8 +1,10 @@
import { type ChartConfiguration } from '@/command-menu/pages/page-layout/types/ChartConfiguration';
import { isWidgetConfigurationOfType } from '@/command-menu/pages/page-layout/utils/isWidgetConfigurationOfType';
import { type FieldConfiguration } from '@/page-layout/types/FieldConfiguration';
import { type FieldsConfiguration } from '@/page-layout/types/FieldsConfiguration';
import { type WidgetConfiguration } from '~/generated-metadata/graphql';
import {
type FieldsConfiguration,
type WidgetConfiguration,
} from '~/generated-metadata/graphql';
export const isWidgetConfigurationOfTypeGraph = (
configuration: