From 755260f27b8be00de37c2c8c4b784606f9e7814c Mon Sep 17 00:00:00 2001 From: Jonas Dyrlie Date: Thu, 31 Oct 2024 14:44:13 +0100 Subject: [PATCH] feat(subform): tablecolumns config design update (#13902) --- frontend/language/src/nb.json | 1 + .../ColumnElement/ColumnElement.module.css | 2 +- .../ColumnElement/ColumnElement.test.tsx | 97 ++++-------- .../ColumnElement/ColumnElement.tsx | 143 +++++------------- .../EditColumnElement.module.css | 22 +++ .../EditColumnElement/EditColumnElement.tsx | 138 +++++++++++++++++ .../ColumnElement/EditColumnElement/index.ts | 1 + .../EditSubformTableColumns.module.css | 1 + .../EditSubformTableColumns.test.tsx | 65 +++++--- .../EditSubformTableColumns.tsx | 1 + .../EditSubformTableColumns/index.ts | 2 +- .../src/testing/subformLayoutMock.ts | 61 ++++++++ 12 files changed, 342 insertions(+), 192 deletions(-) create mode 100644 frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.module.css create mode 100644 frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.tsx create mode 100644 frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/index.ts create mode 100644 frontend/packages/ux-editor/src/testing/subformLayoutMock.ts diff --git a/frontend/language/src/nb.json b/frontend/language/src/nb.json index 53b5b25796b..6e8882e039f 100644 --- a/frontend/language/src/nb.json +++ b/frontend/language/src/nb.json @@ -1710,6 +1710,7 @@ "ux_editor.properties_panel.subform_table_columns.add_column": "Legg til kolonne", "ux_editor.properties_panel.subform_table_columns.cell_content_default_label": "Default", "ux_editor.properties_panel.subform_table_columns.cell_content_query_label": "Query", + "ux_editor.properties_panel.subform_table_columns.choose_component": "Velg komponenten fra underskjemaet som skal vises her", "ux_editor.properties_panel.subform_table_columns.column_header": "Kolonne {{columnNumber}}", "ux_editor.properties_panel.subform_table_columns.delete_column": "Slett kolonne {{columnNumber}}", "ux_editor.properties_panel.subform_table_columns.header_content_label": "Header Content", diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.module.css b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.module.css index 82a871787d8..7967f8d3860 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.module.css +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.module.css @@ -1,5 +1,5 @@ .wrapper { - margin-top: var(--fds-spacing-4); + margin-top: var(--fds-spacing-1); } .headerWrapper { diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.test.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.test.tsx index 76f64c3f5b9..c3952d77a97 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.test.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { screen } from '@testing-library/react'; +import { screen, waitFor } from '@testing-library/react'; import { ColumnElement, type ColumnElementProps } from './ColumnElement'; import { textMock } from '@studio/testing/mocks/i18nMock'; import { renderWithProviders } from 'dashboard/testing/mocks'; @@ -7,6 +7,10 @@ import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; import { queriesMock } from 'app-shared/mocks/queriesMock'; import userEvent from '@testing-library/user-event'; import { type TableColumn } from '../types/TableColumn'; +import { layoutSet3SubformNameMock } from '../../../../testing/layoutSetsMock'; +import { QueryKey } from 'app-shared/types/QueryKey'; +import { app, org } from '@studio/testing/testids'; +import { subformLayoutMock } from '../../../../testing/subformLayoutMock'; const headerContentMock: string = 'Header'; const cellContentQueryMock: string = 'Query'; @@ -26,6 +30,7 @@ const defaultProps: ColumnElementProps = { columnNumber: columnNumberMock, onDeleteColumn: jest.fn(), onEdit: jest.fn(), + layoutSetName: layoutSet3SubformNameMock, }; describe('ColumnElement', () => { @@ -41,79 +46,33 @@ describe('ColumnElement', () => { onEdit: onEditMock, }); - const headerInputbutton = screen.getByRole('button', { - name: `${textMock('ux_editor.properties_panel.subform_table_columns.header_content_label')}: ${headerContentMock}`, + const editButton = screen.getByRole('button', { + name: /ux_editor.properties_panel.subform_table_columns.column_header/, }); - await user.click(headerInputbutton); + await user.click(editButton); - const headerInputfield = screen.getByLabelText( - textMock('ux_editor.properties_panel.subform_table_columns.header_content_label'), - ); - const newValue: string = 'a'; - await user.type(headerInputfield, newValue); - await user.tab(); - - expect(onEditMock).toHaveBeenCalledTimes(1); - expect(onEditMock).toHaveBeenCalledWith({ - ...mockTableColumn, - headerContent: `${headerContentMock}${newValue}`, - }); - }); - - it('should call onEdit with updated query content when query text field is blurred', async () => { - const onEditMock = jest.fn(); - - const user = userEvent.setup(); - renderColumnElement({ - onEdit: onEditMock, - }); - - const queryInputbutton = screen.getByRole('button', { - name: `${textMock('ux_editor.properties_panel.subform_table_columns.cell_content_query_label')}: ${cellContentQueryMock}`, + const componentSelect = screen.getByRole('combobox', { + name: textMock('ux_editor.properties_panel.subform_table_columns.choose_component'), }); - await user.click(queryInputbutton); - const queryInputfield = screen.getByLabelText( - textMock('ux_editor.properties_panel.subform_table_columns.cell_content_query_label'), + await user.click(componentSelect); + await user.click( + screen.getByRole('option', { name: new RegExp(`${subformLayoutMock.component1Id}`) }), ); - const newValue: string = 'a'; - await user.type(queryInputfield, newValue); - await user.tab(); - expect(onEditMock).toHaveBeenCalledTimes(1); - expect(onEditMock).toHaveBeenCalledWith({ - ...mockTableColumn, - cellContent: { ...mockTableColumn.cellContent, query: `${cellContentQueryMock}${newValue}` }, + await waitFor(async () => { + await user.click( + screen.getByRole('button', { + name: textMock('general.save'), + }), + ); }); - }); - - it('should call onEdit with updated default content when default text field is blurred', async () => { - const onEditMock = jest.fn(); - - const user = userEvent.setup(); - renderColumnElement({ - onEdit: onEditMock, - }); - - const defaultInputbutton = screen.getByRole('button', { - name: `${textMock('ux_editor.properties_panel.subform_table_columns.cell_content_default_label')}: ${cellContentDefaultMock}`, - }); - await user.click(defaultInputbutton); - - const defaultInputfield = screen.getByLabelText( - textMock('ux_editor.properties_panel.subform_table_columns.cell_content_default_label'), - ); - const newValue: string = 'a'; - await user.type(defaultInputfield, newValue); - await user.tab(); expect(onEditMock).toHaveBeenCalledTimes(1); expect(onEditMock).toHaveBeenCalledWith({ ...mockTableColumn, - cellContent: { - ...mockTableColumn.cellContent, - default: `${cellContentDefaultMock}${newValue}`, - }, + headerContent: subformLayoutMock.component1.textResourceBindings.title, + cellContent: { query: subformLayoutMock.component1.dataModelBindings.simpleBinding }, }); }); @@ -125,10 +84,12 @@ describe('ColumnElement', () => { onDeleteColumn: onDeleteColumnMock, }); + const editButton = screen.getByRole('button', { + name: /ux_editor.properties_panel.subform_table_columns.column_header/, + }); + await user.click(editButton); const deleteButton = screen.getByRole('button', { - name: textMock('ux_editor.properties_panel.subform_table_columns.delete_column', { - columnNumber: columnNumberMock, - }), + name: textMock('general.delete'), }); await user.click(deleteButton); @@ -138,6 +99,10 @@ describe('ColumnElement', () => { const renderColumnElement = (props: Partial = {}) => { const queryClient = createQueryClientMock(); + queryClient.setQueryData( + [QueryKey.FormLayouts, org, app, layoutSet3SubformNameMock], + subformLayoutMock.layoutSet, + ); return renderWithProviders(, { ...queriesMock, queryClient, diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.tsx index 738c6ddf938..548770348e7 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/ColumnElement.tsx @@ -1,15 +1,15 @@ -import React, { type ReactElement, type ChangeEvent } from 'react'; +import React, { useState, type ReactElement } from 'react'; import classes from './ColumnElement.module.css'; import { type TableColumn } from '../types/TableColumn'; import { useTranslation } from 'react-i18next'; -import { - StudioButton, - StudioLabelAsParagraph, - StudioToggleableTextfield, -} from '@studio/components'; -import { KeyVerticalFillIcon, TrashFillIcon } from '@studio/icons'; +import { StudioProperty } from '@studio/components'; +import { EditColumnElement } from './EditColumnElement'; +import { useTextResourcesQuery } from 'app-shared/hooks/queries'; +import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams'; +import { textResourceByLanguageAndIdSelector } from '../../../../selectors/textResourceSelectors'; export type ColumnElementProps = { + layoutSetName: string; tableColumn: TableColumn; columnNumber: number; onDeleteColumn: () => void; @@ -21,110 +21,45 @@ export const ColumnElement = ({ columnNumber, onDeleteColumn, onEdit, + layoutSetName, }: ColumnElementProps): ReactElement => { const { t } = useTranslation(); + const [editing, setEditing] = useState(false); + const { org, app } = useStudioEnvironmentParams(); + const { data: textResources } = useTextResourcesQuery(org, app); - const handleEditHeaderContent = (event: ChangeEvent) => { - onEdit({ ...tableColumn, headerContent: event.target.value }); - }; - - const handleEditQuery = (event: ChangeEvent) => { - onEdit({ - ...tableColumn, - cellContent: { ...tableColumn.cellContent, query: event.target.value }, - }); - }; - - const handleEditDefault = (event: ChangeEvent) => { - onEdit({ - ...tableColumn, - cellContent: { ...tableColumn.cellContent, default: event.target.value }, - }); - }; - return ( -
- - - - -
- ); -}; - -type TableColumnHeaderProps = { - columnNumber: number; - onDeleteColumn: () => void; -}; - -const TableColumnHeader = ({ - columnNumber, - onDeleteColumn, -}: TableColumnHeaderProps): ReactElement => { - const { t } = useTranslation(); + const textKeyValue = textResourceByLanguageAndIdSelector( + 'nb', + tableColumn.headerContent, + )(textResources)?.value; - return ( -
- - {t('ux_editor.properties_panel.subform_table_columns.column_header', { columnNumber })} - - } - title={t('ux_editor.properties_panel.subform_table_columns.delete_column', { - columnNumber, - })} - onClick={onDeleteColumn} - color='danger' - variant='secondary' + if (editing) { + return ( + { + setEditing(false); + onEdit(col); + }} /> -
- ); -}; + ); + } -type TableColumnToggleableTextfieldProps = { - label: string; - value: string; - onBlur: (event: ChangeEvent) => void; - required?: boolean; -}; + const handleClickEdit = (): void => { + setEditing(true); + }; -const TableColumnToggleableTextfield = ({ - label, - value, - onBlur, - required = false, -}: TableColumnToggleableTextfieldProps): ReactElement => { return ( - , - label, - value, - size: 'sm', - required, - onBlur, - }} - viewProps={{ - children: ( - - {label}: {value} - - ), - variant: 'tertiary', - }} - /> + ); }; diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.module.css b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.module.css new file mode 100644 index 00000000000..6cc5e4f1786 --- /dev/null +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.module.css @@ -0,0 +1,22 @@ +.wrapper { + margin-top: var(--fds-spacing-4); + padding: var(--fds-spacing-3); +} + +.header { + padding-top: var(--fds-spacing-2); + padding-bottom: var(--fds-spacing-0); + padding-left: var(--fds-spacing-0); +} + +.content { + padding: var(--fds-spacing-0); +} + +.divider { + margin-top: var(--fds-spacing-0); +} +.buttons { + display: flex; + gap: var(--fds-spacing-2); +} diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.tsx new file mode 100644 index 00000000000..a3a7904fcfa --- /dev/null +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.tsx @@ -0,0 +1,138 @@ +import React, { useState, type ReactElement } from 'react'; +import classes from './EditColumnElement.module.css'; +import { type TableColumn } from '../../types/TableColumn'; +import { useTranslation } from 'react-i18next'; +import { + StudioActionCloseButton, + StudioCard, + StudioCombobox, + StudioDeleteButton, + StudioDivider, + StudioParagraph, + StudioTextfield, +} from '@studio/components'; +import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams'; +import { useFormLayoutsQuery } from '../../../../../hooks/queries/useFormLayoutsQuery'; +import { getAllLayoutComponents } from '../../../../../utils/formLayoutUtils'; +import type { FormItem } from '../../../../../types/FormItem'; +import { PadlockLockedFillIcon } from '@studio/icons'; +import { useTextResourcesQuery } from 'app-shared/hooks/queries'; +import { textResourceByLanguageAndIdSelector } from '../../../../../selectors/textResourceSelectors'; + +export type ColumnElementProps = { + sourceColumn: TableColumn; + columnNumber: number; + onDeleteColumn: () => void; + onEdit: (tableColumn: TableColumn) => void; + layoutSetName: string; +}; + +export const EditColumnElement = ({ + sourceColumn, + columnNumber, + onDeleteColumn, + onEdit, + layoutSetName, +}: ColumnElementProps): ReactElement => { + const { t } = useTranslation(); + const { org, app } = useStudioEnvironmentParams(); + const subformLayout = layoutSetName; + const [tableColumn, setTableColumn] = useState(sourceColumn); + const { data: formLayouts } = useFormLayoutsQuery(org, app, subformLayout); + const { data: textResources } = useTextResourcesQuery(org, app); + + const textKeyValue = textResourceByLanguageAndIdSelector( + 'nb', + tableColumn.headerContent, + )(textResources)?.value; + const components = formLayouts + ? Object.values(formLayouts).flatMap((layout) => { + return getAllLayoutComponents(layout); + }) + : []; + + const selectComponent = (values: string[]) => { + const selectedComponentId = values[0]; + const selectedComponent = components.find((comp) => comp.id === selectedComponentId); + + const updatedTableColumn = { + ...sourceColumn, + headerContent: selectedComponent.textResourceBindings?.title, + cellContent: { query: selectedComponent.dataModelBindings?.simpleBinding }, + }; + setTableColumn(updatedTableColumn); + }; + + return ( + + + + + + + {t('ux_editor.modal_properties_textResourceBindings_title')} + + } + disabled={true} + size='sm' + value={textKeyValue} + /> +
+ onEdit(tableColumn)} + title={t('general.save')} + > + +
+
+
+ ); +}; + +type EditColumnElementHeaderProps = { + columnNumber: number; +}; +const EditColumnElementHeader = ({ columnNumber }: EditColumnElementHeaderProps) => { + const { t } = useTranslation(); + return ( + <> + + + {t('ux_editor.properties_panel.subform_table_columns.column_header', { columnNumber })} + + + + + ); +}; + +type EditColumnElementComponentSelectProps = { + components: FormItem[]; + onSelectComponent: (values: string[]) => void; +}; +const EditColumnElementComponentSelect = ({ + components, + onSelectComponent, +}: EditColumnElementComponentSelectProps) => { + const { t } = useTranslation(); + return ( + + {components.map((comp: FormItem) => ( + + {comp.id} + + ))} + + ); +}; diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/index.ts b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/index.ts new file mode 100644 index 00000000000..80f9defc0a0 --- /dev/null +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/index.ts @@ -0,0 +1 @@ +export { EditColumnElement } from './EditColumnElement'; diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.module.css b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.module.css index b498d5a8497..f3cbba5a95c 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.module.css +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.module.css @@ -10,4 +10,5 @@ .addColumnButton { margin-top: var(--fds-spacing-3); + margin-left: var(--fds-spacing-5); } diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.test.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.test.tsx index b26046cdd21..1c676a21f6f 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.test.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.test.tsx @@ -1,16 +1,19 @@ import React from 'react'; -import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { screen, waitFor } from '@testing-library/react'; +import { ComponentType } from 'app-shared/types/ComponentType'; +import { componentMocks } from '@altinn/ux-editor/testing/componentMocks'; +import { subformLayoutMock } from '../../../testing/subformLayoutMock'; +import { QueryKey } from 'app-shared/types/QueryKey'; +import { app, org } from '@studio/testing/testids'; import { EditSubformTableColumns, type EditSubformTableColumnsProps, } from './EditSubformTableColumns'; import { textMock } from '@studio/testing/mocks/i18nMock'; import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; +import { renderWithProviders } from '../../../testing/mocks'; import { queriesMock } from 'app-shared/mocks/queriesMock'; -import userEvent from '@testing-library/user-event'; -import { ComponentType } from 'app-shared/types/ComponentType'; -import { componentMocks } from '@altinn/ux-editor/testing/componentMocks'; -import { renderWithProviders } from '@altinn/ux-editor/testing/mocks'; const subformComponentMock = componentMocks[ComponentType.Subform]; @@ -20,7 +23,10 @@ jest.mock('./hooks/useSubformLayoutValidation', () => ({ })); const defaultProps: EditSubformTableColumnsProps = { - component: subformComponentMock, + component: { + ...subformComponentMock, + layoutSet: subformLayoutMock.layoutSetName, + }, handleComponentChange: jest.fn(), }; @@ -78,24 +84,33 @@ describe('EditSubformTableColumns', () => { props: { handleComponentChange: handleComponentChangeMock }, }); - const headerInputbutton = screen.getByRole('button', { - name: `${textMock('ux_editor.properties_panel.subform_table_columns.header_content_label')}: ${subformComponentMock.tableColumns[0].headerContent}`, + const editButton = screen.getByRole('button', { + name: /ux_editor.properties_panel.subform_table_columns.column_header/, }); + await user.click(editButton); - await user.click(headerInputbutton); + const componentSelect = screen.getByRole('combobox', { + name: textMock('ux_editor.properties_panel.subform_table_columns.choose_component'), + }); - const headerInputfield = screen.getByLabelText( - textMock('ux_editor.properties_panel.subform_table_columns.header_content_label'), + await user.click(componentSelect); + await user.click( + screen.getByRole('option', { name: new RegExp(`${subformLayoutMock.component1Id}`) }), ); - const newValue = 'Updated Header'; - await user.clear(headerInputfield); - await user.type(headerInputfield, newValue); - await user.tab(); + await waitFor(async () => { + await user.click( + screen.getByRole('button', { + name: textMock('general.save'), + }), + ); + }); expect(handleComponentChangeMock).toHaveBeenCalledTimes(1); const updatedComponent = handleComponentChangeMock.mock.calls[0][0]; - expect(updatedComponent.tableColumns[0].headerContent).toBe(newValue); + expect(updatedComponent.tableColumns[0].headerContent).toBe( + subformLayoutMock.component1.textResourceBindings.title, + ); }); it('should call handleComponentChange when a column is deleted', async () => { @@ -106,12 +121,14 @@ describe('EditSubformTableColumns', () => { props: { handleComponentChange: handleComponentChangeMock }, }); - const deleteButton = screen.getByRole('button', { - name: textMock('ux_editor.properties_panel.subform_table_columns.delete_column', { - columnNumber: 1, - }), + const editButton = screen.getByRole('button', { + name: /ux_editor.properties_panel.subform_table_columns.column_header/, }); + await user.click(editButton); + const deleteButton = screen.getByRole('button', { + name: textMock('general.delete'), + }); await user.click(deleteButton); expect(handleComponentChangeMock).toHaveBeenCalledTimes(1); @@ -135,6 +152,9 @@ describe('EditSubformTableColumns', () => { }); }); +const textKeyId = subformLayoutMock.component1.textResourceBindings.title; +const textKeyValue = 'testtext'; +const textResourcesMock = { ['nb']: [{ id: textKeyId, value: textKeyValue }] }; type renderEditSubformTableColumnsParameters = { props?: Partial; isSubformLayoutConfigured?: boolean; @@ -147,6 +167,11 @@ const renderEditSubformTableColumns = ( ) => { mockSubformLayoutValidation.mockReturnValue(isSubformLayoutConfigured); const queryClient = createQueryClientMock(); + queryClient.setQueryData([QueryKey.TextResources, org, app], textResourcesMock); + queryClient.setQueryData( + [QueryKey.FormLayouts, org, app, subformLayoutMock.layoutSetName], + subformLayoutMock.layoutSet, + ); return renderWithProviders(, { ...queriesMock, queryClient, diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.tsx index e4b20dba989..1eb7721efc9 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/EditSubformTableColumns.tsx @@ -58,6 +58,7 @@ export const EditSubformTableColumns = ({ {tableColumns.length > 0 && tableColumns.map((tableColum: TableColumn, index: number) => (