From fedacc860628484bac84368c474d40e77c296726 Mon Sep 17 00:00:00 2001 From: lassopicasso Date: Wed, 12 Feb 2025 15:52:11 +0100 Subject: [PATCH 1/8] update type of IDataModelBindings --- frontend/packages/ux-editor/src/types/global.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/packages/ux-editor/src/types/global.ts b/frontend/packages/ux-editor/src/types/global.ts index eba03131314..66c136625c5 100644 --- a/frontend/packages/ux-editor/src/types/global.ts +++ b/frontend/packages/ux-editor/src/types/global.ts @@ -16,7 +16,14 @@ export interface IOption { export type ITextResourceBindings = KeyValuePairs; -export type IDataModelBindings = KeyValuePairs; +export type ImplicitDataModelBinding = KeyValuePairs; +//** Undefined to be backward compatible */ +export type ExplicitDataModelBinding = { + dataType: string | undefined; + field: string | undefined; +}; + +export type IDataModelBindings = ImplicitDataModelBinding | ExplicitDataModelBinding; export type IFormDesignerComponents = KeyValuePairs; export type IFormDesignerContainers = KeyValuePairs; export type IFormLayouts = KeyValuePairs; From 90b8934654c35eed32adeb9e9e9214fd0b3aebca Mon Sep 17 00:00:00 2001 From: lassopicasso Date: Wed, 12 Feb 2025 15:53:04 +0100 Subject: [PATCH 2/8] update types for specificConfig --- .../src/types/ComponentSpecificConfig.ts | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/frontend/packages/shared/src/types/ComponentSpecificConfig.ts b/frontend/packages/shared/src/types/ComponentSpecificConfig.ts index 4070d791908..92a7fa1480d 100644 --- a/frontend/packages/shared/src/types/ComponentSpecificConfig.ts +++ b/frontend/packages/shared/src/types/ComponentSpecificConfig.ts @@ -7,44 +7,40 @@ import type { ActionButtonAction } from 'app-shared/types/ActionButtonAction'; import type { GridRow } from 'app-shared/types/GridRow'; import type { HTMLAutoCompleteValue } from 'app-shared/types/HTMLAutoCompleteValue'; import type { BooleanExpression, StringExpression } from '@studio/components'; -import type { InternalBindingFormat } from '@altinn/ux-editor/utils/dataModelUtils'; +import type { IDataModelBindings } from '@altinn/ux-editor/types/global'; type DataModelBindingsForAddress = { - address: string; - zipCode: string; - postPlace: string; - careOf?: string; - houseNumber?: string; + address: IDataModelBindings; + zipCode: IDataModelBindings; + postPlace: IDataModelBindings; + careOf?: IDataModelBindings; + houseNumber?: IDataModelBindings; }; -type DataModelBindingsForCustom = { - [id: string]: string; -}; +type DataModelBindingsForCustom = IDataModelBindings; type DataModelBindingsForGroup = { - group: string; + group: IDataModelBindings; }; -type DataModelBindingsForList = { - [id: string]: string; -}; +type DataModelBindingsForList = IDataModelBindings; type DataModelBindingsLikert = { - answer: string; - questions: string; + answer: IDataModelBindings; + questions: IDataModelBindings; }; type DataModelBindingsList = { - list: string; + list: IDataModelBindings; }; type DataModelBindingsOptionsSimple = { - simpleBinding: string | InternalBindingFormat; - metadata?: string; + simpleBinding: IDataModelBindings; + metadata?: IDataModelBindings; }; export type DataModelBindingsSimple = { - simpleBinding: string | InternalBindingFormat; + simpleBinding: IDataModelBindings; }; type DataModelBindingsForFileUpload = DataModelBindingsSimple | DataModelBindingsList; From b311b7c54b275bfd776510a584009da3d980fad2 Mon Sep 17 00:00:00 2001 From: lassopicasso Date: Thu, 13 Feb 2025 14:42:22 +0100 Subject: [PATCH 3/8] fix types - distinguish between with and without KeyValuePairs --- .../src/types/ComponentSpecificConfig.ts | 26 +++++++++---------- .../src/types/api/FormLayoutsResponse.ts | 3 ++- .../ColumnElement/ColumnElement.test.tsx | 7 ++++- .../EditColumnElement.test.tsx | 23 ++++++++++++---- .../packages/ux-editor/src/types/global.ts | 16 ++++++++---- .../ux-editor/src/utils/dataModelUtils.ts | 23 +++++----------- 6 files changed, 57 insertions(+), 41 deletions(-) diff --git a/frontend/packages/shared/src/types/ComponentSpecificConfig.ts b/frontend/packages/shared/src/types/ComponentSpecificConfig.ts index 92a7fa1480d..acf42461e43 100644 --- a/frontend/packages/shared/src/types/ComponentSpecificConfig.ts +++ b/frontend/packages/shared/src/types/ComponentSpecificConfig.ts @@ -7,40 +7,40 @@ import type { ActionButtonAction } from 'app-shared/types/ActionButtonAction'; import type { GridRow } from 'app-shared/types/GridRow'; import type { HTMLAutoCompleteValue } from 'app-shared/types/HTMLAutoCompleteValue'; import type { BooleanExpression, StringExpression } from '@studio/components'; -import type { IDataModelBindings } from '@altinn/ux-editor/types/global'; +import type { ExplicitDataModelBinding, IDataModelBindings } from '@altinn/ux-editor/types/global'; type DataModelBindingsForAddress = { - address: IDataModelBindings; - zipCode: IDataModelBindings; - postPlace: IDataModelBindings; - careOf?: IDataModelBindings; - houseNumber?: IDataModelBindings; + address: string | ExplicitDataModelBinding; + zipCode: string | ExplicitDataModelBinding; + postPlace: string | ExplicitDataModelBinding; + careOf?: string | ExplicitDataModelBinding; + houseNumber?: string | ExplicitDataModelBinding; }; type DataModelBindingsForCustom = IDataModelBindings; type DataModelBindingsForGroup = { - group: IDataModelBindings; + group: string | ExplicitDataModelBinding; }; type DataModelBindingsForList = IDataModelBindings; type DataModelBindingsLikert = { - answer: IDataModelBindings; - questions: IDataModelBindings; + answer: string | ExplicitDataModelBinding; + questions: string | ExplicitDataModelBinding; }; type DataModelBindingsList = { - list: IDataModelBindings; + list: string | ExplicitDataModelBinding; }; type DataModelBindingsOptionsSimple = { - simpleBinding: IDataModelBindings; - metadata?: IDataModelBindings; + simpleBinding: string | ExplicitDataModelBinding; + metadata?: string | ExplicitDataModelBinding; }; export type DataModelBindingsSimple = { - simpleBinding: IDataModelBindings; + simpleBinding: string | ExplicitDataModelBinding; }; type DataModelBindingsForFileUpload = DataModelBindingsSimple | DataModelBindingsList; diff --git a/frontend/packages/shared/src/types/api/FormLayoutsResponse.ts b/frontend/packages/shared/src/types/api/FormLayoutsResponse.ts index d564ea0b616..2f5ff302f41 100644 --- a/frontend/packages/shared/src/types/api/FormLayoutsResponse.ts +++ b/frontend/packages/shared/src/types/api/FormLayoutsResponse.ts @@ -2,6 +2,7 @@ import type { KeyValuePairs } from 'app-shared/types/KeyValuePairs'; import type { ComponentType } from 'app-shared/types/ComponentType'; import type { ComponentSpecificConfig } from 'app-shared/types/ComponentSpecificConfig'; import type { Expression } from '@studio/components'; +import type { IDataModelBindings } from '@altinn/ux-editor/types/global'; export type FormLayoutsResponse = KeyValuePairs; @@ -20,7 +21,7 @@ export interface ExternalData { export type ExternalComponentBase = { id: string; type: T; - dataModelBindings?: KeyValuePairs; + dataModelBindings?: IDataModelBindings; textResourceBindings?: KeyValuePairs; [key: string]: any; }; 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 ccc012a27a1..e2ff9f5cd6d 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 @@ -11,11 +11,16 @@ import { layoutSet3SubformNameMock } from '../../../../testing/layoutSetsMock'; import { QueryKey } from 'app-shared/types/QueryKey'; import { app, org } from '@studio/testing/testids'; import { subformLayoutMock } from '../../../../testing/subformLayoutMock'; +import { convertDataBindingToInternalFormat } from '@altinn/ux-editor/utils/dataModelUtils'; const headerContentMock: string = 'Header'; const cellContentQueryMock: string = 'Query'; const cellContentDefaultMock: string = 'Default'; const columnNumberMock: number = 1; +const addressDataField = convertDataBindingToInternalFormat( + subformLayoutMock.component4.dataModelBindings, + 'address', +).field; const mockTableColumn: TableColumn = { headerContent: headerContentMock, @@ -47,7 +52,7 @@ describe('ColumnElement', () => { onChange: onChangeMock, tableColumn: { headerContent: subformLayoutMock.component4.textResourceBindings.title, - cellContent: { query: subformLayoutMock.component4.dataModelBindings.address }, + cellContent: { query: addressDataField }, }, }); diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx index f18396b5878..eabd5fe4194 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx @@ -10,6 +10,7 @@ import { renderWithProviders } from '../../../../../testing/mocks'; import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; import { QueryKey } from 'app-shared/types/QueryKey'; import { app, org } from '@studio/testing/testids'; +import { convertDataBindingToInternalFormat } from '@altinn/ux-editor/utils/dataModelUtils'; const subformComponentMock = componentMocks[ComponentType.Subform]; @@ -23,6 +24,14 @@ const defaultProps: EditColumnElementProps = { }; const textKeyMock = 'textkeymock1'; const textValueMock = 'textkeymock1'; +const addressDataField = convertDataBindingToInternalFormat( + subformLayoutMock.component4.dataModelBindings, + 'address', +).field; +const postPlaceDataField = convertDataBindingToInternalFormat( + subformLayoutMock.component4.dataModelBindings, + 'postPlace', +).field; describe('EditColumnElementComponentSelect', () => { afterEach(() => { @@ -128,7 +137,9 @@ describe('EditColumnElementComponentSelect', () => { renderEditColumnElement({ tableColumn: { headerContent: subformLayoutMock.component4.textResourceBindings.title, - cellContent: { query: subformLayoutMock.component4.dataModelBindings.address }, + cellContent: { + query: addressDataField, + }, }, }); const componentSelect = screen.getByRole('combobox', { @@ -154,7 +165,9 @@ describe('EditColumnElementComponentSelect', () => { renderEditColumnElement({ tableColumn: { headerContent: subformLayoutMock.component4.textResourceBindings.title, - cellContent: { query: subformLayoutMock.component4.dataModelBindings.address }, + cellContent: { + query: addressDataField, + }, }, }); const componentSelect = screen.getByRole('combobox', { @@ -265,7 +278,7 @@ describe('EditColumnElementComponentSelect', () => { onChange: onChangeMock, tableColumn: { headerContent: subformLayoutMock.component4.textResourceBindings.title, - cellContent: { query: subformLayoutMock.component4.dataModelBindings.address }, + cellContent: { query: addressDataField }, }, }); @@ -303,7 +316,7 @@ describe('EditColumnElementComponentSelect', () => { onChange: onChangeMock, tableColumn: { headerContent: subformLayoutMock.component4.textResourceBindings.title, - cellContent: { query: subformLayoutMock.component4.dataModelBindings.address }, + cellContent: { query: addressDataField }, }, }); const componentSelect = screen.getByRole('combobox', { @@ -326,7 +339,7 @@ describe('EditColumnElementComponentSelect', () => { }); await user.click( screen.getByRole('option', { - name: new RegExp(subformLayoutMock.component4.dataModelBindings.postPlace), + name: new RegExp(postPlaceDataField), }), ); diff --git a/frontend/packages/ux-editor/src/types/global.ts b/frontend/packages/ux-editor/src/types/global.ts index 66c136625c5..0f0fa630d29 100644 --- a/frontend/packages/ux-editor/src/types/global.ts +++ b/frontend/packages/ux-editor/src/types/global.ts @@ -16,14 +16,20 @@ export interface IOption { export type ITextResourceBindings = KeyValuePairs; -export type ImplicitDataModelBinding = KeyValuePairs; -//** Undefined to be backward compatible */ +export type ImplicitDataModelBinding = string; export type ExplicitDataModelBinding = { - dataType: string | undefined; - field: string | undefined; + dataType: string; + field: string; }; -export type IDataModelBindings = ImplicitDataModelBinding | ExplicitDataModelBinding; +export const isExplicitDataModelBinding = ( + binding: IDataModelBindings, +): binding is KeyValuePairs | undefined => + typeof binding === 'object' && 'dataType' in binding && 'field' in binding; + +export type IDataModelBindings = + | KeyValuePairs + | KeyValuePairs; export type IFormDesignerComponents = KeyValuePairs; export type IFormDesignerContainers = KeyValuePairs; export type IFormLayouts = KeyValuePairs; diff --git a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts index 26454cc3f01..0ee3f899d05 100644 --- a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts +++ b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts @@ -1,6 +1,6 @@ import type { DataModelFieldElement } from 'app-shared/types/DataModelFieldElement'; import { ComponentType } from 'app-shared/types/ComponentType'; -import type { IDataModelBindings } from '../types/global'; +import { isExplicitDataModelBinding, type IDataModelBindings } from '../types/global'; export const getMinOccursFromDataModelFields = ( dataBindingName: string, @@ -106,21 +106,12 @@ export const convertDataBindingToInternalFormat = ( dataModelBindings: IDataModelBindings, bindingKey: string, ): InternalBindingFormat => { - const dataModelBinding = - dataModelBindings && bindingKey in dataModelBindings - ? dataModelBindings[bindingKey] - : undefined; - - const isOldFormatOrNotSet = - typeof dataModelBinding === 'string' || typeof dataModelBinding === 'undefined'; - - if (isOldFormatOrNotSet) { - return { - field: dataModelBinding, - dataType: '', - }; - } - return dataModelBinding; + if (isExplicitDataModelBinding(dataModelBindings)) return dataModelBindings[bindingKey]; + + return { + field: dataModelBindings[bindingKey], + dataType: '', + }; }; export const validateSelectedDataModel = ( From b62135d288b073ccdfbbb2fea06e14f2a6b74be5 Mon Sep 17 00:00:00 2001 From: lassopicasso Date: Thu, 13 Feb 2025 15:04:17 +0100 Subject: [PATCH 4/8] remove InternalBindingFormat type and fix some type errors --- .../EditColumnElement/EditColumnElement.test.tsx | 16 ++++++---------- .../utils/editSubformTableColumnsUtils.test.ts | 2 +- .../DefinedBinding/DefinedBinding.tsx | 4 ++-- .../EditBinding/EditBinding.test.tsx | 13 +++++++++---- .../EditBinding/EditBinding.tsx | 6 +++--- .../EditBinding/EditBindingButtons.tsx | 4 ++-- .../EditBinding/SelectDataFieldBinding.tsx | 6 +++--- .../EditBinding/SelectDataModelBinding.tsx | 4 ++-- .../ux-editor/src/utils/dataModelUtils.ts | 13 ++++++------- 9 files changed, 34 insertions(+), 34 deletions(-) diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx index eabd5fe4194..c8a855cb677 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx @@ -24,14 +24,14 @@ const defaultProps: EditColumnElementProps = { }; const textKeyMock = 'textkeymock1'; const textValueMock = 'textkeymock1'; -const addressDataField = convertDataBindingToInternalFormat( +const { field: addressDataField } = convertDataBindingToInternalFormat( subformLayoutMock.component4.dataModelBindings, 'address', -).field; -const postPlaceDataField = convertDataBindingToInternalFormat( +); +const { field: postPlaceDataField } = convertDataBindingToInternalFormat( subformLayoutMock.component4.dataModelBindings, 'postPlace', -).field; +); describe('EditColumnElementComponentSelect', () => { afterEach(() => { @@ -137,9 +137,7 @@ describe('EditColumnElementComponentSelect', () => { renderEditColumnElement({ tableColumn: { headerContent: subformLayoutMock.component4.textResourceBindings.title, - cellContent: { - query: addressDataField, - }, + cellContent: { query: addressDataField }, }, }); const componentSelect = screen.getByRole('combobox', { @@ -165,9 +163,7 @@ describe('EditColumnElementComponentSelect', () => { renderEditColumnElement({ tableColumn: { headerContent: subformLayoutMock.component4.textResourceBindings.title, - cellContent: { - query: addressDataField, - }, + cellContent: { query: addressDataField }, }, }); const componentSelect = screen.getByRole('combobox', { diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/utils/editSubformTableColumnsUtils.test.ts b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/utils/editSubformTableColumnsUtils.test.ts index 7e1a7e6ce59..4257046a3d8 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/utils/editSubformTableColumnsUtils.test.ts +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/utils/editSubformTableColumnsUtils.test.ts @@ -47,7 +47,7 @@ const formLayouts: IFormLayouts = { ...componentMocks[ComponentType.Input], textResourceBindings: { title: 'mockDescriptionId' }, dataModelBindings: { - simpleBinding: { dataType: 'mockDataModel', field: 'mockDataModelBinding4' } as any, // TODO: remove as any when https://github.com/Altinn/altinn-studio/issues/14441 is solved + simpleBinding: { dataType: 'mockDataModel', field: 'mockDataModelBinding4' }, }, }, }, diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/DefinedBinding/DefinedBinding.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/DefinedBinding/DefinedBinding.tsx index 5dc048992d4..7024465ab5f 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/DefinedBinding/DefinedBinding.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/DefinedBinding/DefinedBinding.tsx @@ -6,15 +6,15 @@ import { useTranslation } from 'react-i18next'; import { getDataModelFields, validateSelectedDataField, - type InternalBindingFormat, } from '@altinn/ux-editor/utils/dataModelUtils'; import type { ComponentType } from 'app-shared/types/ComponentType'; import { useValidDataModels } from '@altinn/ux-editor/hooks/useValidDataModels'; +import type { ExplicitDataModelBinding } from '@altinn/ux-editor/types/global'; export type DefinedBindingProps = { onClick: () => void; label: string; - internalBindingFormat: InternalBindingFormat; + internalBindingFormat: ExplicitDataModelBinding; componentType: ComponentType; bindingKey: string; }; diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.test.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.test.tsx index 2db64183ed1..2972eed5296 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.test.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.test.tsx @@ -9,10 +9,11 @@ import type { ServicesContextProps } from 'app-shared/contexts/ServicesContext'; import { screen, waitForElementToBeRemoved } from '@testing-library/react'; import { textMock } from '@studio/testing/mocks/i18nMock'; import userEvent from '@testing-library/user-event'; -import type { InternalBindingFormat } from '@altinn/ux-editor/utils/dataModelUtils'; import { layoutSet1NameMock } from '../../../../../testing/layoutSetsMock'; import { QueryKey } from 'app-shared/types/QueryKey'; import { app, org } from '@studio/testing/testids'; +import type { ExplicitDataModelBinding } from '@altinn/ux-editor/types/global'; +import { convertDataBindingToInternalFormat } from '@altinn/ux-editor/utils/dataModelUtils'; const defaultLabel = 'label'; const defaultBindingKey = 'simpleBinding'; @@ -37,15 +38,19 @@ type MockedParentComponentProps = EditBindingProps; const MockedParentComponent = (props: MockedParentComponentProps) => { const [newInternalBindingFormat, setNewInternalBindingFormat] = - React.useState(props.internalBindingFormat); + React.useState(props.internalBindingFormat); + return ( { - const fieldBinding = formItem.dataModelBindings[defaultBindingKey] as InternalBindingFormat; + const { field } = convertDataBindingToInternalFormat( + props.component.dataModelBindings, + props.bindingKey, + ); setNewInternalBindingFormat((prev) => ({ ...prev, - field: fieldBinding.field, + field, })); }} internalBindingFormat={newInternalBindingFormat} diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.tsx index 330b6ca7c43..427495f1294 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.tsx @@ -8,7 +8,6 @@ import { getMaxOccursFromDataModelFields, getMinOccursFromDataModelFields, getXsdDataTypeFromDataModelFields, - type InternalBindingFormat, } from '@altinn/ux-editor/utils/dataModelUtils'; import { useAppContext } from '@altinn/ux-editor/hooks'; import type { UpdateFormMutateOptions } from '@altinn/ux-editor/containers/FormItemContext'; @@ -17,6 +16,7 @@ import { useValidDataModels } from '@altinn/ux-editor/hooks/useValidDataModels'; import { StudioSpinner } from '@studio/components'; import { useTranslation } from 'react-i18next'; import { formItemConfigs } from '@altinn/ux-editor/data/formItemConfig'; +import type { ExplicitDataModelBinding } from '@altinn/ux-editor/types/global'; export type EditBindingProps = { bindingKey: string; @@ -24,7 +24,7 @@ export type EditBindingProps = { label: string; handleComponentChange: (component: FormItem, mutateOptions?: UpdateFormMutateOptions) => void; onSetDataModelSelectVisible: (visible: boolean) => void; - internalBindingFormat: InternalBindingFormat; + internalBindingFormat: ExplicitDataModelBinding; }; export const EditBinding = ({ @@ -41,7 +41,7 @@ export const EditBinding = ({ internalBindingFormat.dataType, ); - const handleBindingChange = (updatedBinding?: InternalBindingFormat) => { + const handleBindingChange = (updatedBinding?: ExplicitDataModelBinding) => { const selectedDataFieldElement = updatedBinding?.field; const value = diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBindingButtons.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBindingButtons.tsx index 178e0bd5389..9b93435b6d6 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBindingButtons.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBindingButtons.tsx @@ -3,10 +3,10 @@ import { StudioButton, StudioDeleteButton } from '@studio/components'; import { XMarkIcon } from '@studio/icons'; import classes from './EditBindingButtons.module.css'; import { useTranslation } from 'react-i18next'; -import type { InternalBindingFormat } from '@altinn/ux-editor/utils/dataModelUtils'; +import type { ExplicitDataModelBinding } from '@altinn/ux-editor/types/global'; export type EditBindingButtons = { - handleBindingChange: (binding: InternalBindingFormat) => void; + handleBindingChange: (binding: ExplicitDataModelBinding) => void; onSetDataModelSelectVisible: (visible: boolean) => void; }; diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/SelectDataFieldBinding.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/SelectDataFieldBinding.tsx index 37f43fbf79c..5521f09b271 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/SelectDataFieldBinding.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/SelectDataFieldBinding.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { getDataModelFields, validateSelectedDataField, - type InternalBindingFormat, } from '@altinn/ux-editor/utils/dataModelUtils'; import { useTranslation } from 'react-i18next'; import { FormField } from 'app-shared/components/FormField'; @@ -11,10 +10,11 @@ import { useValidDataModels } from '@altinn/ux-editor/hooks/useValidDataModels'; import type { ComponentType } from 'app-shared/types/ComponentType'; import classes from './SelectDataFieldBinding.module.css'; import { useComponentPropertyHelpText } from '../../../../../hooks'; +import type { ExplicitDataModelBinding } from '@altinn/ux-editor/types/global'; type SelectDataFieldProps = { - internalBindingFormat: InternalBindingFormat; - handleBindingChange: (dataModelBindings: InternalBindingFormat) => void; + internalBindingFormat: ExplicitDataModelBinding; + handleBindingChange: (dataModelBindings: ExplicitDataModelBinding) => void; bindingKey: string; componentType: ComponentType; }; diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/SelectDataModelBinding.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/SelectDataModelBinding.tsx index 4888002b749..5cf6b880c37 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/SelectDataModelBinding.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/SelectDataModelBinding.tsx @@ -3,16 +3,16 @@ import classes from './SelectDataModelBinding.module.css'; import { FormField } from 'app-shared/components/FormField'; import { StudioNativeSelect } from '@studio/components'; import { useTranslation } from 'react-i18next'; -import type { InternalBindingFormat } from '@altinn/ux-editor/utils/dataModelUtils'; import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams'; import { useAppContext } from '../../../../../hooks'; import { useGetBindableDataTypes } from '../../../../../hooks/useGetBindableDataTypes'; import { useValidDataModels } from '../../../../../hooks/useValidDataModels'; +import type { ExplicitDataModelBinding } from '@altinn/ux-editor/types/global'; type SelectDataModelProps = { currentDataModel: string; bindingKey: string; - handleBindingChange: (dataModelBindings: InternalBindingFormat) => void; + handleBindingChange: (dataModelBindings: ExplicitDataModelBinding) => void; }; export const SelectDataModelBinding = ({ diff --git a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts index 0ee3f899d05..a51ad8ec9ef 100644 --- a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts +++ b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts @@ -1,6 +1,10 @@ import type { DataModelFieldElement } from 'app-shared/types/DataModelFieldElement'; import { ComponentType } from 'app-shared/types/ComponentType'; -import { isExplicitDataModelBinding, type IDataModelBindings } from '../types/global'; +import { + type ExplicitDataModelBinding, + isExplicitDataModelBinding, + type IDataModelBindings, +} from '../types/global'; export const getMinOccursFromDataModelFields = ( dataBindingName: string, @@ -97,15 +101,10 @@ export const getDataModelFields = ({ return filterDataModelFields(filter, dataModelMetadata); }; -export type InternalBindingFormat = { - field: string | undefined; - dataType: string | undefined; -}; - export const convertDataBindingToInternalFormat = ( dataModelBindings: IDataModelBindings, bindingKey: string, -): InternalBindingFormat => { +): ExplicitDataModelBinding => { if (isExplicitDataModelBinding(dataModelBindings)) return dataModelBindings[bindingKey]; return { From 795d06135aaacfd55aa522cc8edbe278ccf0e5d2 Mon Sep 17 00:00:00 2001 From: lassopicasso Date: Fri, 14 Feb 2025 07:42:20 +0100 Subject: [PATCH 5/8] fix tests --- frontend/packages/ux-editor/src/types/global.ts | 6 +----- .../packages/ux-editor/src/utils/dataModelUtils.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/frontend/packages/ux-editor/src/types/global.ts b/frontend/packages/ux-editor/src/types/global.ts index 0f0fa630d29..c26980b8fe6 100644 --- a/frontend/packages/ux-editor/src/types/global.ts +++ b/frontend/packages/ux-editor/src/types/global.ts @@ -22,14 +22,10 @@ export type ExplicitDataModelBinding = { field: string; }; -export const isExplicitDataModelBinding = ( - binding: IDataModelBindings, -): binding is KeyValuePairs | undefined => - typeof binding === 'object' && 'dataType' in binding && 'field' in binding; - export type IDataModelBindings = | KeyValuePairs | KeyValuePairs; + export type IFormDesignerComponents = KeyValuePairs; export type IFormDesignerContainers = KeyValuePairs; export type IFormLayouts = KeyValuePairs; diff --git a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts index a51ad8ec9ef..1880294b121 100644 --- a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts +++ b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts @@ -1,10 +1,7 @@ import type { DataModelFieldElement } from 'app-shared/types/DataModelFieldElement'; import { ComponentType } from 'app-shared/types/ComponentType'; -import { - type ExplicitDataModelBinding, - isExplicitDataModelBinding, - type IDataModelBindings, -} from '../types/global'; +import { type ExplicitDataModelBinding, type IDataModelBindings } from '../types/global'; +import type { KeyValuePairs } from 'app-shared/types/KeyValuePairs'; export const getMinOccursFromDataModelFields = ( dataBindingName: string, @@ -101,6 +98,11 @@ export const getDataModelFields = ({ return filterDataModelFields(filter, dataModelMetadata); }; +const isExplicitDataModelBinding = ( + binding: IDataModelBindings, +): binding is KeyValuePairs | undefined => + typeof binding === 'object' && 'dataType' in binding && 'field' in binding; + export const convertDataBindingToInternalFormat = ( dataModelBindings: IDataModelBindings, bindingKey: string, @@ -108,7 +110,7 @@ export const convertDataBindingToInternalFormat = ( if (isExplicitDataModelBinding(dataModelBindings)) return dataModelBindings[bindingKey]; return { - field: dataModelBindings[bindingKey], + field: dataModelBindings?.[bindingKey] || '', dataType: '', }; }; From 03a45a09aa41a8fcee348ecb10c52d9f8f2e9578 Mon Sep 17 00:00:00 2001 From: lassopicasso Date: Fri, 14 Feb 2025 09:59:51 +0100 Subject: [PATCH 6/8] refactor convertDataBindingToInternalFormat logic --- .../ColumnElement/ColumnElement.test.tsx | 3 +-- .../DataModelBindingsCombobox.tsx | 2 +- .../EditColumnElement.test.tsx | 6 ++---- .../EditColumnElement/EditColumnElement.tsx | 5 ++--- .../utils/editSubformTableColumnsUtils.ts | 3 +-- .../EditBinding/EditBinding.test.tsx | 3 +-- .../EditDataModelBinding.tsx | 6 ++---- .../src/utils/dataModelUtils.test.ts | 19 ++++--------------- .../ux-editor/src/utils/dataModelUtils.ts | 14 ++++++-------- 9 files changed, 20 insertions(+), 41 deletions(-) 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 e2ff9f5cd6d..f7fda67693e 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 @@ -18,8 +18,7 @@ const cellContentQueryMock: string = 'Query'; const cellContentDefaultMock: string = 'Default'; const columnNumberMock: number = 1; const addressDataField = convertDataBindingToInternalFormat( - subformLayoutMock.component4.dataModelBindings, - 'address', + subformLayoutMock.component4.dataModelBindings['address'], ).field; const mockTableColumn: TableColumn = { diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/DataModelBindingsCombobox.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/DataModelBindingsCombobox.tsx index 403e6fed55b..dbd49be60d0 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/DataModelBindingsCombobox.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/DataModelBindingsCombobox.tsx @@ -40,7 +40,7 @@ export const DataModelBindingsCombobox = ({ onValueChange={(values) => onValueChange(values[0])} > {Object.keys(dataModelBindings).map((key) => { - const { field } = convertDataBindingToInternalFormat(dataModelBindings, key); + const { field } = convertDataBindingToInternalFormat(dataModelBindings?.[key]); return ( field && ( diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx index c8a855cb677..0d91cd1fbe2 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/EditColumnElement.test.tsx @@ -25,12 +25,10 @@ const defaultProps: EditColumnElementProps = { const textKeyMock = 'textkeymock1'; const textValueMock = 'textkeymock1'; const { field: addressDataField } = convertDataBindingToInternalFormat( - subformLayoutMock.component4.dataModelBindings, - 'address', + subformLayoutMock.component4.dataModelBindings['address'], ); const { field: postPlaceDataField } = convertDataBindingToInternalFormat( - subformLayoutMock.component4.dataModelBindings, - 'postPlace', + subformLayoutMock.component4.dataModelBindings['postPlace'], ); describe('EditColumnElementComponentSelect', () => { 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 index 97e9b0fae9b..cdf8fba6e5e 100644 --- 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 @@ -56,8 +56,7 @@ export const EditColumnElement = ({ const bindingKey = Object.keys(selectedComponent.dataModelBindings)[0]; const binding = convertDataBindingToInternalFormat( - selectedComponent?.dataModelBindings, - bindingKey, + selectedComponent?.dataModelBindings?.[bindingKey], ); onChange({ @@ -71,7 +70,7 @@ export const EditColumnElement = ({ dataModelBindings: IDataModelBindings, dataModelBindingKey: string, ) => { - const { field } = convertDataBindingToInternalFormat(dataModelBindings, dataModelBindingKey); + const { field } = convertDataBindingToInternalFormat(dataModelBindings[dataModelBindingKey]); const updatedTableColumn = { ...tableColumn, cellContent: { query: field }, diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/utils/editSubformTableColumnsUtils.ts b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/utils/editSubformTableColumnsUtils.ts index 586ea829e36..654b87f043b 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/utils/editSubformTableColumnsUtils.ts +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/utils/editSubformTableColumnsUtils.ts @@ -41,8 +41,7 @@ const componentsWithTitleAndDefaultDataModel = ( const hasValidDataBinding = (comp: FormItem) => Object.keys(comp.dataModelBindings ?? {}).some((binding) => { const { dataType, field } = convertDataBindingToInternalFormat( - comp?.dataModelBindings, - binding, + comp?.dataModelBindings?.[binding], ); return dataType === defaultDataModel || (dataType === '' && field !== ''); }); diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.test.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.test.tsx index 2972eed5296..29edba0c1a3 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.test.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditBinding/EditBinding.test.tsx @@ -45,8 +45,7 @@ const MockedParentComponent = (props: MockedParentComponentProps) => { {...props} handleComponentChange={(formItem) => { const { field } = convertDataBindingToInternalFormat( - props.component.dataModelBindings, - props.bindingKey, + props.component.dataModelBindings[props.bindingKey], ); setNewInternalBindingFormat((prev) => ({ ...prev, diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditDataModelBinding.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditDataModelBinding.tsx index 1b238b4d748..81ac9275f59 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditDataModelBinding.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditDataModelBinding.tsx @@ -23,13 +23,11 @@ export const EditDataModelBinding = ({ renderOptions, }: EditDataModelBindingProps) => { const { key, label } = renderOptions || {}; - const bindingKey = key || 'simpleBinding'; const { t } = useTranslation(); const [dataModelSelectVisible, setDataModelSelectVisible] = useState(false); - + const bindingKey = key || 'simpleBinding'; const internalBindingFormat = convertDataBindingToInternalFormat( - component?.dataModelBindings, - bindingKey, + component?.dataModelBindings[bindingKey], ); const labelSpecificText = label diff --git a/frontend/packages/ux-editor/src/utils/dataModelUtils.test.ts b/frontend/packages/ux-editor/src/utils/dataModelUtils.test.ts index 852f680cdd9..bfe4d76d7a0 100644 --- a/frontend/packages/ux-editor/src/utils/dataModelUtils.test.ts +++ b/frontend/packages/ux-editor/src/utils/dataModelUtils.test.ts @@ -11,7 +11,6 @@ import { validateSelectedDataModel, } from './dataModelUtils'; import { dataModelMetadataMock } from '@altinn/ux-editor/testing/dataModelMock'; -import type { FormItem } from '../types/FormItem'; describe('getMinOccursFromDataModelFields', () => { it('should be truthy if minOccurs is bigger than 0', () => { @@ -157,8 +156,7 @@ describe('convertDataBindingToInternalFormat', () => { }; const bindingKey = 'simpleBinding'; const internalFormat = convertDataBindingToInternalFormat( - (component as unknown as FormItem)?.dataModelBindings, - bindingKey, + component.dataModelBindings[bindingKey], ); expect(internalFormat).toEqual({ dataType: 'dataType', field: 'field' }); }); @@ -166,23 +164,14 @@ describe('convertDataBindingToInternalFormat', () => { it('should return correct format when it has old format', () => { const bindingKey = 'simpleBinding'; const internalFormat = convertDataBindingToInternalFormat( - testComponent?.dataModelBindings, - bindingKey, + testComponent.dataModelBindings[bindingKey], ); expect(internalFormat).toEqual({ dataType: '', field: '' }); }); it('should return correct format when dataModelBindings and bindingKey is not defined', () => { - const component = { - ...testComponent, - dataModelBindings: undefined, - }; - const bindingKey = undefined; - const internalFormat = convertDataBindingToInternalFormat( - component?.dataModelBindings, - bindingKey, - ); - expect(internalFormat).toEqual({ dataType: '', field: undefined }); + const internalFormat = convertDataBindingToInternalFormat(undefined); + expect(internalFormat).toEqual({ dataType: '', field: '' }); }); }); diff --git a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts index 1880294b121..51062d11733 100644 --- a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts +++ b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts @@ -1,7 +1,6 @@ import type { DataModelFieldElement } from 'app-shared/types/DataModelFieldElement'; import { ComponentType } from 'app-shared/types/ComponentType'; -import { type ExplicitDataModelBinding, type IDataModelBindings } from '../types/global'; -import type { KeyValuePairs } from 'app-shared/types/KeyValuePairs'; +import type { ExplicitDataModelBinding } from '../types/global'; export const getMinOccursFromDataModelFields = ( dataBindingName: string, @@ -99,18 +98,17 @@ export const getDataModelFields = ({ }; const isExplicitDataModelBinding = ( - binding: IDataModelBindings, -): binding is KeyValuePairs | undefined => + binding?: string | ExplicitDataModelBinding, +): binding is ExplicitDataModelBinding | undefined => typeof binding === 'object' && 'dataType' in binding && 'field' in binding; export const convertDataBindingToInternalFormat = ( - dataModelBindings: IDataModelBindings, - bindingKey: string, + binding?: string | ExplicitDataModelBinding, ): ExplicitDataModelBinding => { - if (isExplicitDataModelBinding(dataModelBindings)) return dataModelBindings[bindingKey]; + if (isExplicitDataModelBinding(binding)) return binding; return { - field: dataModelBindings?.[bindingKey] || '', + field: binding || '', dataType: '', }; }; From b9f9dfdcc7cd2fb53faabcf4f154af079135cba3 Mon Sep 17 00:00:00 2001 From: lassopicasso Date: Fri, 14 Feb 2025 11:43:33 +0100 Subject: [PATCH 7/8] IDataModelBindings & IDataModelBindingsKeyValue --- .../src/types/ComponentSpecificConfig.ts | 33 ++++++++++--------- .../src/types/api/FormLayoutsResponse.ts | 4 +-- .../DataModelBindingsCombobox.tsx | 4 +-- .../EditColumnElement/EditColumnElement.tsx | 4 +-- .../useUpdateFormComponentMutation.test.ts | 4 +-- .../ux-editor/src/types/FormComponent.ts | 4 +-- .../ux-editor/src/types/FormContainer.ts | 4 +-- .../packages/ux-editor/src/types/global.ts | 3 +- .../ux-editor/src/utils/dataModelUtils.ts | 6 ++-- 9 files changed, 35 insertions(+), 31 deletions(-) diff --git a/frontend/packages/shared/src/types/ComponentSpecificConfig.ts b/frontend/packages/shared/src/types/ComponentSpecificConfig.ts index acf42461e43..80420c48bab 100644 --- a/frontend/packages/shared/src/types/ComponentSpecificConfig.ts +++ b/frontend/packages/shared/src/types/ComponentSpecificConfig.ts @@ -7,40 +7,43 @@ import type { ActionButtonAction } from 'app-shared/types/ActionButtonAction'; import type { GridRow } from 'app-shared/types/GridRow'; import type { HTMLAutoCompleteValue } from 'app-shared/types/HTMLAutoCompleteValue'; import type { BooleanExpression, StringExpression } from '@studio/components'; -import type { ExplicitDataModelBinding, IDataModelBindings } from '@altinn/ux-editor/types/global'; +import type { + IDataModelBindings, + IDataModelBindingsKeyValue, +} from '@altinn/ux-editor/types/global'; type DataModelBindingsForAddress = { - address: string | ExplicitDataModelBinding; - zipCode: string | ExplicitDataModelBinding; - postPlace: string | ExplicitDataModelBinding; - careOf?: string | ExplicitDataModelBinding; - houseNumber?: string | ExplicitDataModelBinding; + address: IDataModelBindings; + zipCode: IDataModelBindings; + postPlace: IDataModelBindings; + careOf?: IDataModelBindings; + houseNumber?: IDataModelBindings; }; -type DataModelBindingsForCustom = IDataModelBindings; +type DataModelBindingsForCustom = IDataModelBindingsKeyValue; type DataModelBindingsForGroup = { - group: string | ExplicitDataModelBinding; + group: IDataModelBindings; }; -type DataModelBindingsForList = IDataModelBindings; +type DataModelBindingsForList = IDataModelBindingsKeyValue; type DataModelBindingsLikert = { - answer: string | ExplicitDataModelBinding; - questions: string | ExplicitDataModelBinding; + answer: IDataModelBindings; + questions: IDataModelBindings; }; type DataModelBindingsList = { - list: string | ExplicitDataModelBinding; + list: IDataModelBindings; }; type DataModelBindingsOptionsSimple = { - simpleBinding: string | ExplicitDataModelBinding; - metadata?: string | ExplicitDataModelBinding; + simpleBinding: IDataModelBindings; + metadata?: IDataModelBindings; }; export type DataModelBindingsSimple = { - simpleBinding: string | ExplicitDataModelBinding; + simpleBinding: IDataModelBindings; }; type DataModelBindingsForFileUpload = DataModelBindingsSimple | DataModelBindingsList; diff --git a/frontend/packages/shared/src/types/api/FormLayoutsResponse.ts b/frontend/packages/shared/src/types/api/FormLayoutsResponse.ts index 2f5ff302f41..fcbdc56017b 100644 --- a/frontend/packages/shared/src/types/api/FormLayoutsResponse.ts +++ b/frontend/packages/shared/src/types/api/FormLayoutsResponse.ts @@ -2,7 +2,7 @@ import type { KeyValuePairs } from 'app-shared/types/KeyValuePairs'; import type { ComponentType } from 'app-shared/types/ComponentType'; import type { ComponentSpecificConfig } from 'app-shared/types/ComponentSpecificConfig'; import type { Expression } from '@studio/components'; -import type { IDataModelBindings } from '@altinn/ux-editor/types/global'; +import type { IDataModelBindingsKeyValue } from '@altinn/ux-editor/types/global'; export type FormLayoutsResponse = KeyValuePairs; @@ -21,7 +21,7 @@ export interface ExternalData { export type ExternalComponentBase = { id: string; type: T; - dataModelBindings?: IDataModelBindings; + dataModelBindings?: IDataModelBindingsKeyValue; textResourceBindings?: KeyValuePairs; [key: string]: any; }; diff --git a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/DataModelBindingsCombobox.tsx b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/DataModelBindingsCombobox.tsx index dbd49be60d0..682782688cd 100644 --- a/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/DataModelBindingsCombobox.tsx +++ b/frontend/packages/ux-editor/src/components/Properties/EditSubformTableColumns/ColumnElement/EditColumnElement/DataModelBindingsCombobox.tsx @@ -1,12 +1,12 @@ import React, { useState } from 'react'; import { StudioCombobox } from '@studio/components'; import { useTranslation } from 'react-i18next'; -import type { IDataModelBindings } from '../../../../../types/global'; +import type { IDataModelBindingsKeyValue } from '../../../../../types/global'; import { convertDataBindingToInternalFormat } from '../../../../../utils/dataModelUtils'; type DataModelBindingsComboboxProps = { componentType: string; - dataModelBindings?: IDataModelBindings; + dataModelBindings?: IDataModelBindingsKeyValue; onDataModelBindingChange: (dataModelBindingKey: string) => void; initialDataModelBindingKey: string; }; 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 index cdf8fba6e5e..db1034b228b 100644 --- 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 @@ -21,7 +21,7 @@ import { import { convertDataBindingToInternalFormat } from '../../../../../utils/dataModelUtils'; import { DataModelBindingsCombobox } from './DataModelBindingsCombobox'; import { useLayoutSetsQuery } from 'app-shared/hooks/queries/useLayoutSetsQuery'; -import type { IDataModelBindings } from '../../../../../types/global'; +import type { IDataModelBindingsKeyValue } from '../../../../../types/global'; export type EditColumnElementProps = { tableColumn: TableColumn; @@ -67,7 +67,7 @@ export const EditColumnElement = ({ }; const handleBindingChange = ( - dataModelBindings: IDataModelBindings, + dataModelBindings: IDataModelBindingsKeyValue, dataModelBindingKey: string, ) => { const { field } = convertDataBindingToInternalFormat(dataModelBindings[dataModelBindingKey]); diff --git a/frontend/packages/ux-editor/src/hooks/mutations/useUpdateFormComponentMutation.test.ts b/frontend/packages/ux-editor/src/hooks/mutations/useUpdateFormComponentMutation.test.ts index a9e3832eb54..91fca83646d 100644 --- a/frontend/packages/ux-editor/src/hooks/mutations/useUpdateFormComponentMutation.test.ts +++ b/frontend/packages/ux-editor/src/hooks/mutations/useUpdateFormComponentMutation.test.ts @@ -16,7 +16,7 @@ import type { FormFileUploaderComponent, FormRadioButtonsComponent, } from '../../types/FormComponent'; -import type { IDataModelBindings } from '../../types/global'; +import type { IDataModelBindingsKeyValue } from '../../types/global'; import { QueryKey } from 'app-shared/types/QueryKey'; import { convertExternalLayoutsToInternalFormat } from '../../utils/formLayoutsUtils'; import { ruleConfig as ruleConfigMock } from '../../testing/ruleConfigMock'; @@ -30,7 +30,7 @@ const selectedLayoutName = layout1NameMock; const selectedLayoutSet = layoutSet1NameMock; const id = component1IdMock; const type = ComponentType.TextArea; -const dataModelBindings: IDataModelBindings & DataModelBindingsSimple = { +const dataModelBindings: IDataModelBindingsKeyValue & DataModelBindingsSimple = { simpleBinding: 'some-path', }; const updatedComponent: FormComponent = { diff --git a/frontend/packages/ux-editor/src/types/FormComponent.ts b/frontend/packages/ux-editor/src/types/FormComponent.ts index 78cef2dd92d..60b30ede3f7 100644 --- a/frontend/packages/ux-editor/src/types/FormComponent.ts +++ b/frontend/packages/ux-editor/src/types/FormComponent.ts @@ -1,5 +1,5 @@ import type { ComponentType } from 'app-shared/types/ComponentType'; -import type { IDataModelBindings, ITextResourceBindings, IOption } from './global'; +import type { IDataModelBindingsKeyValue, ITextResourceBindings, IOption } from './global'; import type { ComponentSpecificConfig } from 'app-shared/types/ComponentSpecificConfig'; import type { SimpleComponentType } from './SimpleComponentType'; import type { GridSizes } from '../components/config/editModal/EditGrid/types/GridSizes'; @@ -14,7 +14,7 @@ export interface FormComponentBase { size?: string; options?: IOption[]; pageIndex?: number; - dataModelBindings?: IDataModelBindings; + dataModelBindings?: IDataModelBindingsKeyValue; textResourceBindings?: ITextResourceBindings; customType?: string; codeListId?: string; diff --git a/frontend/packages/ux-editor/src/types/FormContainer.ts b/frontend/packages/ux-editor/src/types/FormContainer.ts index d3044fbb278..28c8499f012 100644 --- a/frontend/packages/ux-editor/src/types/FormContainer.ts +++ b/frontend/packages/ux-editor/src/types/FormContainer.ts @@ -1,4 +1,4 @@ -import type { IDataModelBindings, ITextResourceBindings } from './global'; +import type { IDataModelBindingsKeyValue, ITextResourceBindings } from './global'; import type { ContainerComponentType } from './ContainerComponent'; import type { GridSizes } from '../components/config/editModal/EditGrid/types/GridSizes'; import type { BooleanExpression, StringExpression } from '@studio/components'; @@ -10,7 +10,7 @@ export type FormContainer = { - dataModelBindings?: IDataModelBindings; + dataModelBindings?: IDataModelBindingsKeyValue; grid?: GridSizes; hidden?: BooleanExpression; id: string; diff --git a/frontend/packages/ux-editor/src/types/global.ts b/frontend/packages/ux-editor/src/types/global.ts index c26980b8fe6..81f2d740d22 100644 --- a/frontend/packages/ux-editor/src/types/global.ts +++ b/frontend/packages/ux-editor/src/types/global.ts @@ -22,9 +22,10 @@ export type ExplicitDataModelBinding = { field: string; }; -export type IDataModelBindings = +export type IDataModelBindingsKeyValue = | KeyValuePairs | KeyValuePairs; +export type IDataModelBindings = ImplicitDataModelBinding | ExplicitDataModelBinding; export type IFormDesignerComponents = KeyValuePairs; export type IFormDesignerContainers = KeyValuePairs; diff --git a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts index 51062d11733..0f3ded97818 100644 --- a/frontend/packages/ux-editor/src/utils/dataModelUtils.ts +++ b/frontend/packages/ux-editor/src/utils/dataModelUtils.ts @@ -1,6 +1,6 @@ import type { DataModelFieldElement } from 'app-shared/types/DataModelFieldElement'; import { ComponentType } from 'app-shared/types/ComponentType'; -import type { ExplicitDataModelBinding } from '../types/global'; +import type { ExplicitDataModelBinding, IDataModelBindings } from '../types/global'; export const getMinOccursFromDataModelFields = ( dataBindingName: string, @@ -98,12 +98,12 @@ export const getDataModelFields = ({ }; const isExplicitDataModelBinding = ( - binding?: string | ExplicitDataModelBinding, + binding?: IDataModelBindings, ): binding is ExplicitDataModelBinding | undefined => typeof binding === 'object' && 'dataType' in binding && 'field' in binding; export const convertDataBindingToInternalFormat = ( - binding?: string | ExplicitDataModelBinding, + binding?: IDataModelBindings, ): ExplicitDataModelBinding => { if (isExplicitDataModelBinding(binding)) return binding; From f6ad050dcf8dd5a4a596cfae0ac810b1152b02c8 Mon Sep 17 00:00:00 2001 From: lassopicasso Date: Fri, 14 Feb 2025 12:02:43 +0100 Subject: [PATCH 8/8] fix test --- .../editModal/EditDataModelBinding/EditDataModelBinding.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditDataModelBinding.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditDataModelBinding.tsx index 81ac9275f59..9748957b2ea 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditDataModelBinding.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditDataModelBinding/EditDataModelBinding.tsx @@ -27,7 +27,7 @@ export const EditDataModelBinding = ({ const [dataModelSelectVisible, setDataModelSelectVisible] = useState(false); const bindingKey = key || 'simpleBinding'; const internalBindingFormat = convertDataBindingToInternalFormat( - component?.dataModelBindings[bindingKey], + component?.dataModelBindings?.[bindingKey], ); const labelSpecificText = label