Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add SubForm component #13564

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions frontend/language/src/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,7 @@
"ux_editor.component_properties.largeGroup": "Stor gruppevisning/gruppe i gruppe",
"ux_editor.component_properties.layers": "Kartlag",
"ux_editor.component_properties.layout": "Visning",
"ux_editor.component_properties.layoutSet": "Navn på sidegruppe",
"ux_editor.component_properties.loading": "Laster inn",
"ux_editor.component_properties.mapping": "Mapping",
"ux_editor.component_properties.maxCount": "Maks antall repetisjoner",
Expand Down Expand Up @@ -1234,8 +1235,10 @@
"ux_editor.component_properties.select_pdf": "Inkluder skjemagenerert pdf",
"ux_editor.component_properties.sender": "Den som har sendt inn skjemaet",
"ux_editor.component_properties.severity": "Alvorlighetsgrad",
"ux_editor.component_properties.showAddButton": "Vis 'Legg til'-knapp",
"ux_editor.component_properties.showAsCard": "Vis som kort",
"ux_editor.component_properties.showBackButton": "Vis Tilbake-knapp",
"ux_editor.component_properties.showDeleteButton": "Vis Slett-knapp",
"ux_editor.component_properties.showIcon": "Vis ikon",
"ux_editor.component_properties.showLabelsInTable": "Alternativene skal alltid vises i tabeller",
"ux_editor.component_properties.showValidations": "Vis valideringer",
Expand All @@ -1248,6 +1251,7 @@
"ux_editor.component_properties.stickyHeader": "Fest tittelraden",
"ux_editor.component_properties.style": "Stil",
"ux_editor.component_properties.subdomains": "Subdomener (kommaseparert)",
"ux_editor.component_properties.summaryDelimiter": "Skillelinje for sammendragsvisningsceller",
"ux_editor.component_properties.tableColumns": "Innstillinger for kolonner",
"ux_editor.component_properties.tableHeaders": "Felter som skal vises i tabellens overskrift",
"ux_editor.component_properties.tableHeadersMobile": "Felter som skal vises i tabellens overskrift (mobil)",
Expand Down Expand Up @@ -1313,6 +1317,7 @@
"ux_editor.component_title.PrintButton": "Utskriftsknapp",
"ux_editor.component_title.RadioButtons": "Radioknapper",
"ux_editor.component_title.RepeatingGroup": "Repeterende gruppe",
"ux_editor.component_title.SubForm": "Underskjema",
"ux_editor.component_title.Summary": "Oppsummering",
"ux_editor.component_title.TextArea": "Stort tekstfelt",
"ux_editor.component_unknown": "Ukjent komponent",
Expand Down Expand Up @@ -1443,6 +1448,7 @@
"ux_editor.modal_properties_maximum_files": "Maksimalt antall filvedlegg",
"ux_editor.modal_properties_minimum_files": "Minimalt antall filvedlegg",
"ux_editor.modal_properties_no_options_found_message": "Appen din inneholder ingen statiske kodelister. Last opp kodeliste for å velge fra listen. Foreløpig må dette gjøres manuelt, ved å laste opp filen i appens repository. Se beskrivelsen under for eksempel på hvordan dette gjøres. Det vil snart bli mulig å laste opp kodelistefil direkte i Studio.",
"ux_editor.modal_properties_textResourceBindings_addButton": "Avsluttende tekst for 'Legg til ny'-knapp",
"ux_editor.modal_properties_textResourceBindings_add_button": "Avsluttende tekst for 'Legg til ny'-knapp",
"ux_editor.modal_properties_textResourceBindings_add_button_add": "Legg til avsluttende tekst for 'Legg til ny'-knapp",
"ux_editor.modal_properties_textResourceBindings_add_button_full": "Hele teksten for 'Legg til ny'-knapp",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ export type ComponentSpecificConfig<T extends ComponentType = ComponentType> = {
rowsAfter?: GridRow[];
labelSettings?: LabelSettings;
};
[ComponentType.SubForm]: FormComponentProps;
[ComponentType.Summary]: SummarizableComponentProps & {
componentRef: string;
largeGroup?: boolean;
Expand Down
1 change: 1 addition & 0 deletions frontend/packages/shared/src/types/ComponentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export enum ComponentType {
PrintButton = 'PrintButton',
RadioButtons = 'RadioButtons',
RepeatingGroup = 'RepeatingGroup',
SubForm = 'SubForm',
Summary = 'Summary',
TextArea = 'TextArea',
}
3 changes: 2 additions & 1 deletion frontend/packages/shared/src/utils/featureToggleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export type SupportedFeatureFlags =
| 'shouldOverrideAppLibCheck'
| 'resourceMigration'
| 'multipleDataModelsPerTask'
| 'exportForm';
| 'exportForm'
| 'subForm';

/*
* Please add all the features that you want to be toggle on by default here.
Expand Down
11 changes: 9 additions & 2 deletions frontend/packages/ux-editor/src/data/formItemConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@ describe('formItemConfig', () => {
];
const allAvailableComponents = allAvailableLists.flat();

/** Test that all components, except Payment, are available in one of the visible lists */
/** Test that all components, except Payment and SubFrom (since behind featureFlag), are available in one of the visible lists */
it.each(
Object.values(ComponentType).filter((componentType) => componentType !== ComponentType.Payment),
Object.values(ComponentType).filter(
(componentType) =>
componentType !== ComponentType.Payment && componentType !== ComponentType.SubForm,
),
)('%s is available through one of the visible lists', (componentType) => {
expect(allAvailableComponents.map(({ name }) => name)).toContain(componentType);
});

test('that payment component is not available in the visible lists', () => {
expect(allAvailableComponents.map(({ name }) => name)).not.toContain(ComponentType.Payment);
});

test('that subFrom component is not available in the visible lists', () => {
expect(allAvailableComponents.map(({ name }) => name)).not.toContain(ComponentType.SubForm);
});
});
12 changes: 11 additions & 1 deletion frontend/packages/ux-editor/src/data/formItemConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
CalendarIcon,
CheckboxIcon,
ChevronDownDoubleIcon,
ClipboardIcon,
ElementIcon,
ExclamationmarkTriangleIcon,
FileTextIcon,
Expand Down Expand Up @@ -36,6 +37,7 @@ import {
import type { ContainerComponentType } from '../types/ContainerComponent';
import { LayoutItemType } from '../types/global';
import type { ComponentSpecificConfig } from 'app-shared/types/ComponentSpecificConfig';
import { shouldDisplayFeature } from 'app-shared/utils/featureToggleUtils';

export type FormItemConfig<T extends ComponentType = ComponentType> = {
name: T;
Expand Down Expand Up @@ -423,6 +425,13 @@ export const formItemConfigs: FormItemConfigs = {
icon: RepeatingGroupIcon,
validChildTypes: Object.values(ComponentType),
},
[ComponentType.SubForm]: {
name: ComponentType.SubForm,
itemType: LayoutItemType.Component,
defaultProperties: {},
propertyPath: 'definitions/subForm',
icon: ClipboardIcon,
},
[ComponentType.Summary]: {
name: ComponentType.Summary,
itemType: LayoutItemType.Component,
Expand Down Expand Up @@ -459,7 +468,8 @@ export const advancedItems: FormItemConfigs[ComponentType][] = [
formItemConfigs[ComponentType.Custom],
formItemConfigs[ComponentType.RepeatingGroup],
formItemConfigs[ComponentType.PaymentDetails],
];
shouldDisplayFeature('subForm') && formItemConfigs[ComponentType.SubForm],
].filter(Boolean); // When removing the featureFlag, also remove the filter

export const schemaComponents: FormItemConfigs[ComponentType][] = [
formItemConfigs[ComponentType.Input],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import PaymentSchema from './schemas/json/component/Payment.schema.v1.json';
import PrintButtonSchema from './schemas/json/component/PrintButton.schema.v1.json';
import RadioButtonsSchema from './schemas/json/component/RadioButtons.schema.v1.json';
import RepeatingGroupSchema from './schemas/json/component/RepeatingGroup.schema.v1.json';
import SubFormSchema from './schemas/json/component/Subform.schema.v1.json';
import SummarySchema from './schemas/json/component/Summary.schema.v1.json';
import TextAreaSchema from './schemas/json/component/TextArea.schema.v1.json';
import { ComponentType } from 'app-shared/types/ComponentType';
Expand Down Expand Up @@ -80,6 +81,7 @@ export const componentSchemaMocks: Record<ComponentType, JsonSchema> = {
[ComponentType.PrintButton]: PrintButtonSchema,
[ComponentType.RadioButtons]: RadioButtonsSchema,
[ComponentType.RepeatingGroup]: RepeatingGroupSchema,
[ComponentType.SubForm]: SubFormSchema,
[ComponentType.Summary]: SummarySchema,
[ComponentType.TextArea]: TextAreaSchema,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
{
"$id": "https://altinncdn.no/schemas/json/component/Subform.schema.v1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"title": "ID",
"description": "The component ID. Must be unique within all layouts/pages in a layout-set. Cannot end with <dash><number>.",
"type": "string",
"pattern": "^[0-9a-zA-Z][0-9a-zA-Z-]*(-?[a-zA-Z]+|[a-zA-Z][0-9]+|-[0-9]{6,})$"
},
"hidden": {
"title": "Hidden",
"description": "Boolean value or expression indicating if the component should be hidden. Defaults to false.",
"default": false,
"$ref": "expression.schema.v1.json#/definitions/boolean"
},
"grid": {
"properties": {
"xs": { "default": "auto", "$ref": "#/definitions/IGridSize" },
"sm": { "default": "auto", "$ref": "#/definitions/IGridSize" },
"md": { "default": "auto", "$ref": "#/definitions/IGridSize" },
"lg": { "default": "auto", "$ref": "#/definitions/IGridSize" },
"xl": { "default": "auto", "$ref": "#/definitions/IGridSize" },
"labelGrid": { "$ref": "#/definitions/IGridStyling" },
"innerGrid": { "$ref": "#/definitions/IGridStyling" }
}
},
"pageBreak": {
"title": "Page break",
"description": "Optionally insert page-break before/after component when rendered in PDF",
"type": "object",
"properties": {
"breakBefore": {
"title": "Page break before",
"description": "PDF only: Value or expression indicating whether a page break should be added before the component. Can be either: 'auto' (default), 'always', or 'avoid'.",
"examples": ["auto", "always", "avoid"],
"default": "auto",
"$ref": "expression.schema.v1.json#/definitions/string"
},
"breakAfter": {
"title": "Page break after",
"description": "PDF only: Value or expression indicating whether a page break should be added after the component. Can be either: 'auto' (default), 'always', or 'avoid'.",
"examples": ["auto", "always", "avoid"],
"default": "auto",
"$ref": "expression.schema.v1.json#/definitions/string"
}
},
"additionalProperties": false
},
"readOnly": {
"title": "Read only/disabled?",
"description": "Boolean value or expression indicating if the component should be read only/disabled. Defaults to false. <br /> <i>Please note that even with read-only fields in components, it may currently be possible to update the field by modifying the request sent to the API or through a direct API call.<i/>",
"default": false,
"$ref": "expression.schema.v1.json#/definitions/boolean"
},
"required": {
"title": "Required?",
"description": "Boolean value or expression indicating if the component should be required. Defaults to false.",
"default": false,
"$ref": "expression.schema.v1.json#/definitions/boolean"
},
"showValidations": {
"title": "Validation types",
"description": "List of validation types to show",
"type": "array",
"items": {
"enum": [
"Schema",
"Component",
"Expression",
"CustomBackend",
"Required",
"AllExceptRequired",
"All"
],
"type": "string"
}
},
"renderAsSummary": {
"title": "Render as summary",
"description": "Boolean value indicating if the component should be rendered as a summary. Defaults to false.",
"default": false,
"type": "boolean"
},
"forceShowInSummary": {
"title": "Force show in summary",
"description": "Will force show the component in a summary even if hideEmptyFields is set to true in the summary component.",
"default": false,
"$ref": "expression.schema.v1.json#/definitions/boolean"
},
"type": { "const": "Subform" },
"textResourceBindings": {
"properties": {
"title": {
"title": "Title",
"description": "The title of the subform component",
"$ref": "expression.schema.v1.json#/definitions/string"
},
"description": {
"title": "Description",
"description": "The description text shown underneath the title",
"$ref": "expression.schema.v1.json#/definitions/string"
},
"tableTitle": {
"title": "Table title",
"description": "Title used in the table view (overrides the default title)",
"$ref": "expression.schema.v1.json#/definitions/string"
},
"shortName": {
"title": "Short name (for validation)",
"description": "Alternative name used for required validation messages (overrides the default title)",
"$ref": "expression.schema.v1.json#/definitions/string"
},
"requiredValidation": {
"title": "Required validation message",
"description": "Full validation message shown when the component is required and no value has been entered (overrides both the default and shortName)",
"$ref": "expression.schema.v1.json#/definitions/string"
},
"summaryTitle": {
"title": "Summary title",
"description": "Title used in the summary view (overrides the default title)",
"$ref": "expression.schema.v1.json#/definitions/string"
},
"summaryAccessibleTitle": {
"title": "Accessible summary title",
"description": "Title used for aria-label on the edit button in the summary view (overrides the default and summary title)",
"$ref": "expression.schema.v1.json#/definitions/string"
},
"addButton": {
"title": "Add button (suffix)",
"description": "The text for the \"Add\" button (used as a suffix after the default button text)",
"$ref": "expression.schema.v1.json#/definitions/string"
}
}
},
"layoutSet": {
"title": "Layout set ID",
"description": "The layout set to load for this subform",
"type": "string"
},
"showAddButton": { "default": true, "type": "boolean" },
"showDeleteButton": { "default": true, "type": "boolean" },
"tableColumns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"headerContent": {
"title": "The column header value",
"description": "The header value to display. May contain a text resource bindings, but no data model lookups.",
"type": "string"
},
"cellContent": {
"type": "object",
"properties": {
"query": {
"title": "The cell value via data model lookup",
"description": "The cell value to display from a data model lookup (dot notation).",
"type": "string"
},
"default": {
"title": "The default cell value",
"description": "The cell value to display if `query` returns no result.",
"type": "string"
}
},
"required": ["query"],
"additionalProperties": false
}
},
"required": ["headerContent", "cellContent"],
"additionalProperties": false
}
},
"summaryDelimiter": {
"title": "The summary view cell delimiter",
"description": "The value used to separate cells/elements in a summary view where rich layout is not available. Typically a comma, dash or similar.",
"default": " — ",
"type": "string"
}
},
"required": ["id", "type", "layoutSet", "tableColumns"],
"title": "Subform component schema"
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"Paragraph",
"PrintButton",
"RadioButtons",
"SubForm",
"Summary",
"TextArea"
]
2 changes: 1 addition & 1 deletion frontend/scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Run to generate separate component schemas from the layout schemas on CDN.
Currently supports 2 versions of app-frontend:

- v3: https://altinncdn.no/schemas/json/layout/layout.schema.v1.json
- v4: https://altinncdn.no/toolkits/altinn-app-frontend/4.0.0-rc2/schemas/json/layout/layout.schema.v1.json
- v4: https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/layout.schema.v1.json

Provide the desired version as an argument when running the script.

Expand Down