Migrate field widgets to backend (#18808)
- Renamed FieldConfiguration's layout field to fieldDisplayMode as it caused issues with the layout field of BarChartConfiguration - Create relation Field widgets for standard objects --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
committed by
GitHub
parent
d90d2e3151
commit
be89ef30cd
+92
-14
@@ -60,19 +60,19 @@ describe('convertPageLayoutDraftToUpdateInput', () => {
|
||||
expect(result.tabs[0].widgets[0].id).toBe('w1');
|
||||
});
|
||||
|
||||
it('should filter out dynamic relation widgets', () => {
|
||||
const regularWidget = makeWidget({ id: 'w1' });
|
||||
const dynamicWidget = makeWidget({
|
||||
id: `${DYNAMIC_RELATION_WIDGET_ID_PREFIX}relation-1`,
|
||||
type: WidgetType.VIEW,
|
||||
it('should handle multiple widget types', () => {
|
||||
const fieldsWidget = makeWidget({ id: 'w1', type: WidgetType.FIELDS });
|
||||
const timelineWidget = makeWidget({
|
||||
id: 'w2',
|
||||
type: WidgetType.TIMELINE,
|
||||
});
|
||||
|
||||
const draft = makeDraft([makeTab('tab-1', [regularWidget, dynamicWidget])]);
|
||||
const draft = makeDraft([makeTab('tab-1', [fieldsWidget, timelineWidget])]);
|
||||
|
||||
const result = convertPageLayoutDraftToUpdateInput(draft);
|
||||
|
||||
expect(result.tabs[0].widgets).toHaveLength(1);
|
||||
expect(result.tabs[0].widgets[0].id).toBe('w1');
|
||||
expect(result.tabs[0].widgets).toHaveLength(2);
|
||||
expect(result.tabs[0].widgets.map((w) => w.id)).toEqual(['w1', 'w2']);
|
||||
});
|
||||
|
||||
it('should map gridPosition correctly', () => {
|
||||
@@ -121,24 +121,25 @@ describe('convertPageLayoutDraftToUpdateInput', () => {
|
||||
expect(result.tabs[1].id).toBe('tab-2');
|
||||
});
|
||||
|
||||
it('should keep all non-dynamic widgets when multiple widget types exist', () => {
|
||||
it('should keep all widgets when multiple widget types exist', () => {
|
||||
const fieldsWidget = makeWidget({ id: 'w1', type: WidgetType.FIELDS });
|
||||
const timelineWidget = makeWidget({
|
||||
id: 'w2',
|
||||
type: WidgetType.TIMELINE,
|
||||
});
|
||||
const dynamicWidget = makeWidget({
|
||||
id: `${DYNAMIC_RELATION_WIDGET_ID_PREFIX}rel`,
|
||||
const fieldWidget = makeWidget({
|
||||
id: 'w3',
|
||||
type: WidgetType.FIELD,
|
||||
});
|
||||
|
||||
const draft = makeDraft([
|
||||
makeTab('tab-1', [fieldsWidget, dynamicWidget, timelineWidget]),
|
||||
makeTab('tab-1', [fieldsWidget, fieldWidget, timelineWidget]),
|
||||
]);
|
||||
|
||||
const result = convertPageLayoutDraftToUpdateInput(draft);
|
||||
|
||||
expect(result.tabs[0].widgets).toHaveLength(2);
|
||||
expect(result.tabs[0].widgets.map((w) => w.id)).toEqual(['w1', 'w2']);
|
||||
expect(result.tabs[0].widgets).toHaveLength(3);
|
||||
expect(result.tabs[0].widgets.map((w) => w.id)).toEqual(['w1', 'w3', 'w2']);
|
||||
});
|
||||
|
||||
it('should produce VERTICAL_LIST position with index from widget.position when tab is VERTICAL_LIST', () => {
|
||||
@@ -326,4 +327,81 @@ describe('convertPageLayoutDraftToUpdateInput', () => {
|
||||
columnSpan: 6,
|
||||
});
|
||||
});
|
||||
|
||||
describe('shouldFilterDynamicRelationWidgets', () => {
|
||||
it('should filter out dynamic relation widgets when shouldFilterDynamicRelationWidgets is true', () => {
|
||||
const regularWidget = makeWidget({ id: 'w1' });
|
||||
const dynamicWidget = makeWidget({
|
||||
id: `${DYNAMIC_RELATION_WIDGET_ID_PREFIX}relation-1`,
|
||||
type: WidgetType.VIEW,
|
||||
});
|
||||
|
||||
const draft = makeDraft([
|
||||
makeTab('tab-1', [regularWidget, dynamicWidget]),
|
||||
]);
|
||||
|
||||
const result = convertPageLayoutDraftToUpdateInput(draft, {
|
||||
shouldFilterDynamicRelationWidgets: true,
|
||||
});
|
||||
|
||||
expect(result.tabs[0].widgets).toHaveLength(1);
|
||||
expect(result.tabs[0].widgets[0].id).toBe('w1');
|
||||
});
|
||||
|
||||
it('should keep all non-dynamic widgets when shouldFilterDynamicRelationWidgets is true and multiple widget types exist', () => {
|
||||
const fieldsWidget = makeWidget({ id: 'w1', type: WidgetType.FIELDS });
|
||||
const timelineWidget = makeWidget({
|
||||
id: 'w2',
|
||||
type: WidgetType.TIMELINE,
|
||||
});
|
||||
const dynamicWidget = makeWidget({
|
||||
id: `${DYNAMIC_RELATION_WIDGET_ID_PREFIX}rel`,
|
||||
});
|
||||
|
||||
const draft = makeDraft([
|
||||
makeTab('tab-1', [fieldsWidget, dynamicWidget, timelineWidget]),
|
||||
]);
|
||||
|
||||
const result = convertPageLayoutDraftToUpdateInput(draft, {
|
||||
shouldFilterDynamicRelationWidgets: true,
|
||||
});
|
||||
|
||||
expect(result.tabs[0].widgets).toHaveLength(2);
|
||||
expect(result.tabs[0].widgets.map((w) => w.id)).toEqual(['w1', 'w2']);
|
||||
});
|
||||
|
||||
it('should not filter dynamic relation widgets when shouldFilterDynamicRelationWidgets is false', () => {
|
||||
const regularWidget = makeWidget({ id: 'w1' });
|
||||
const dynamicWidget = makeWidget({
|
||||
id: `${DYNAMIC_RELATION_WIDGET_ID_PREFIX}relation-1`,
|
||||
type: WidgetType.VIEW,
|
||||
});
|
||||
|
||||
const draft = makeDraft([
|
||||
makeTab('tab-1', [regularWidget, dynamicWidget]),
|
||||
]);
|
||||
|
||||
const result = convertPageLayoutDraftToUpdateInput(draft, {
|
||||
shouldFilterDynamicRelationWidgets: false,
|
||||
});
|
||||
|
||||
expect(result.tabs[0].widgets).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should not filter dynamic relation widgets by default', () => {
|
||||
const regularWidget = makeWidget({ id: 'w1' });
|
||||
const dynamicWidget = makeWidget({
|
||||
id: `${DYNAMIC_RELATION_WIDGET_ID_PREFIX}relation-1`,
|
||||
type: WidgetType.VIEW,
|
||||
});
|
||||
|
||||
const draft = makeDraft([
|
||||
makeTab('tab-1', [regularWidget, dynamicWidget]),
|
||||
]);
|
||||
|
||||
const result = convertPageLayoutDraftToUpdateInput(draft);
|
||||
|
||||
expect(result.tabs[0].widgets).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ import { type PageLayoutTab } from '@/page-layout/types/PageLayoutTab';
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { injectRelationWidgetsIntoLayout } from '@/page-layout/utils/injectRelationWidgetsIntoLayout';
|
||||
import {
|
||||
FieldDisplayMode,
|
||||
WidgetConfigurationType,
|
||||
WidgetType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
@@ -195,7 +196,7 @@ describe('injectRelationWidgetsIntoLayout', () => {
|
||||
expect(injectedWidget.configuration).toEqual(
|
||||
expect.objectContaining({
|
||||
fieldMetadataId: 'f1',
|
||||
layout: 'CARD',
|
||||
fieldDisplayMode: FieldDisplayMode.CARD,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
+16
-9
@@ -40,19 +40,25 @@ const buildWidgetPosition = (
|
||||
|
||||
export const convertPageLayoutDraftToUpdateInput = (
|
||||
pageLayoutDraft: DraftPageLayout,
|
||||
options?: { shouldFilterDynamicRelationWidgets?: boolean },
|
||||
): UpdatePageLayoutWithTabsInput => {
|
||||
const shouldFilter = options?.shouldFilterDynamicRelationWidgets ?? false;
|
||||
|
||||
return {
|
||||
name: pageLayoutDraft.name,
|
||||
type: pageLayoutDraft.type,
|
||||
objectMetadataId: pageLayoutDraft.objectMetadataId ?? null,
|
||||
tabs: pageLayoutDraft.tabs.map((tab) => ({
|
||||
id: tab.id,
|
||||
title: tab.title,
|
||||
position: tab.position,
|
||||
layoutMode: tab.layoutMode,
|
||||
widgets: tab.widgets
|
||||
.filter((widget) => !isDynamicRelationWidget(widget))
|
||||
.map((widget, widgetIndex) => ({
|
||||
tabs: pageLayoutDraft.tabs.map((tab) => {
|
||||
const widgets = shouldFilter
|
||||
? tab.widgets.filter((widget) => !isDynamicRelationWidget(widget))
|
||||
: tab.widgets;
|
||||
|
||||
return {
|
||||
id: tab.id,
|
||||
title: tab.title,
|
||||
position: tab.position,
|
||||
layoutMode: tab.layoutMode,
|
||||
widgets: widgets.map((widget, widgetIndex) => ({
|
||||
id: widget.id,
|
||||
pageLayoutTabId: widget.pageLayoutTabId,
|
||||
title: widget.title,
|
||||
@@ -71,6 +77,7 @@ export const convertPageLayoutDraftToUpdateInput = (
|
||||
),
|
||||
configuration: widget.configuration ?? null,
|
||||
})),
|
||||
})),
|
||||
};
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import {
|
||||
FieldDisplayMode,
|
||||
PageLayoutTabLayoutMode,
|
||||
WidgetConfigurationType,
|
||||
WidgetType,
|
||||
@@ -28,7 +29,7 @@ export const createDefaultFieldWidget = ({
|
||||
__typename: 'FieldConfiguration',
|
||||
configurationType: WidgetConfigurationType.FIELD,
|
||||
fieldMetadataId,
|
||||
layout: 'CARD',
|
||||
fieldDisplayMode: FieldDisplayMode.CARD,
|
||||
},
|
||||
gridPosition: {
|
||||
__typename: 'GridPosition',
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { DYNAMIC_RELATION_WIDGET_ID_PREFIX } from '@/page-layout/utils/isDynamicRelationWidget';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
FieldDisplayMode,
|
||||
PageLayoutTabLayoutMode,
|
||||
WidgetConfigurationType,
|
||||
WidgetType,
|
||||
@@ -38,7 +39,7 @@ const getRelationFieldWidgetToInsert = (
|
||||
__typename: 'FieldConfiguration' as const,
|
||||
configurationType: WidgetConfigurationType.FIELD,
|
||||
fieldMetadataId: field.id,
|
||||
layout: 'CARD' as const,
|
||||
fieldDisplayMode: FieldDisplayMode.CARD,
|
||||
},
|
||||
isOverridden: false,
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
|
||||
Reference in New Issue
Block a user