Skip to content

Commit

Permalink
feat: Add dynamic lists component (#808)
Browse files Browse the repository at this point in the history
* chore: rename expression-language folder

* wip: implemented protoype repeatRenderManager

* feat: `subform` component

* feat: integrated prototype repeatRenderModule

* feat: hooked up indexing to update cycle

Related to #796

* feat: subform properties panel configuration

Related to #796

* feat: added group styles to subform

* feat: form initializer works with repeatable

Related to #796

* chore: display key and path from config

Related to #796

* feat: enforce path for repeatable groups

Related to #796

* feat: adjusted getSubmitData for repeatable

Related to #796

* feat: repeat render manager

Closes #796

* chore: renamed subform to dynamic list

Related to #796

* chore: adjusted path tooltip for repeating

Related to #796

* feat: repeated element validation

Related to #796

* wip: custom editor list renderer (missing icon)

Related to #796

* wip: collapse / expand dynamic lists

Related to #796

* feat: implement group/list alignment

Related to #796

* chore: added empty states to group and list

Related to #796

* feat: brought in new icons and matched visuals

Related to #796

* fix: form root outline never shows

* fix: editor no longer refreshes on element hover

Closes #807
Related to #796

* feat: add/remove items in dynamic lists

Related to #796

* feat: local expression contexts

Related to #796

* feat: add/remove styles

Related to #796

* feat: automatically scroll when adding item

Related to #796

* feat: refine add/remove UX

Related to #796

* chore: use karma-spec reporter for tests

* chore: refactored viewer and editor tests

Related to #808

* chore: large rebase test cleanups

Related to #808

* fix(submit): only modify error object when needed

Related to #808

* fix: final repeated subforms test adjustments

Related to #808

* chore: fixed minor tabs and naming issues

Related to #808

* feat: added carbon styles for dynamic list

Related to #907

* fix: improved dynamic list button outlines

Related to #808

* chore: rebase changes on `develop`

* chore: reduced nesting and improved docs in Form.js core functions

Related to #808

* chore: removed pointless useMemo

Related to #808

* chore: cleanup remnants of ai generation

Related to #808

* chore: switch from hardcoded to computed componentCount test
Related to #808

* fix(performance): centralize variable filtering

Related to camunda/tasklist#3758

* chore: optimize svgs

Related to #808

* feat: implemented proper path management for repeatable fields

Related to #808

* fix: always expand when uncollapsible

Related to #808

* fix: proper key change handling and repeatable filtering

Related to #808

* feat: implement proper variable hiding within repeated field

Related to #808

* chore: adjust table/iframe tests following rebase

Related to #808

* fix: adjust numerical configs of dynamic list to prevent crashes

Related to #808

* fix: properly split path replacements in pathEntry

Related to #808

* fix: ensure dynamic list buttons don't submit

Related to #808

* feat: Carbonise dynamic list

* fix: show proper default uncollapsed items in propspan

Related to #808

* feat(schema): added dynamic list component

Related to #808

* chore(schema): adjust test indexes

Related to #808

---------

Co-authored-by: Niklas Kiefer <[email protected]>
Co-authored-by: Vinicius Goulart <[email protected]>
  • Loading branch information
3 people authored Dec 13, 2023
1 parent 9786c95 commit 62f71cf
Show file tree
Hide file tree
Showing 195 changed files with 5,355 additions and 3,005 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"karma-firefox-launcher": "^2.1.1",
"karma-mocha": "^2.0.1",
"karma-sinon-chai": "^2.0.2",
"karma-spec-reporter": "^0.0.36",
"karma-webpack": "^5.0.0",
"lerna": "^8.0.0",
"mocha": "^10.0.0",
Expand Down
14 changes: 13 additions & 1 deletion packages/form-js-carbon-styles/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,19 @@ module.exports = function(karma) {
[ suite ]: [ 'webpack', 'env' ]
},

reporters: [ 'progress' ],
reporters: [ 'spec' ],

specReporter: {
maxLogLines: 10,
suppressSummary: true,
suppressErrorSummary: false,
suppressFailed: false,
suppressPassed: false,
suppressSkipped: true,
showBrowser: false,
showSpecTiming: false,
failFast: false
},

browsers,

Expand Down
2 changes: 1 addition & 1 deletion packages/form-js-carbon-styles/src/carbon-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ const LABEL_DESCRIPTION_ERROR_STYLES = css`
letter-spacing: var(--cds-label-01-letter-spacing);
}
.fjs-form-field:not(.fjs-form-field-checkbox, .fjs-form-field-group)
.fjs-form-field:not(.fjs-form-field-checkbox, .fjs-form-field-grouplike)
.fjs-form-field-label:first-child {
margin: 0;
margin-bottom: var(--cds-spacing-03);
Expand Down
60 changes: 59 additions & 1 deletion packages/form-js-carbon-styles/src/carbon-styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,17 @@
padding: 2px 0px;
}
}

&.fjs-form-field-dynamiclist button.fjs-repeat-render-add,
&.fjs-form-field-dynamiclist button .fjs-repeat-row-remove-icon-container {
color: var(--cds-text-on-color-disabled);

&:hover {
color: var(--cds-text-on-color-disabled);
background-color: transparent;
cursor: not-allowed;
}
}
}
}

Expand Down Expand Up @@ -492,7 +503,7 @@
letter-spacing: var(--cds-label-01-letter-spacing);
}

.fjs-form-field:not(.fjs-form-field-checkbox, .fjs-form-field-group, .fjs-form-field-table) .fjs-form-field-label:first-child {
.fjs-form-field:not(.fjs-form-field-checkbox, .fjs-form-field-grouplike, .fjs-form-field-table) .fjs-form-field-label:first-child {
margin: 0;
margin-bottom: var(--cds-spacing-03);
}
Expand Down Expand Up @@ -1312,4 +1323,51 @@
.fjs-table-nav-button {
border-left: 1px solid var(--cds-border-subtle-02);
}
}

// Dynamic lists ////////////


.fjs-container .fjs-form-field-dynamiclist {
.fjs-repeat-row-container .fjs-repeat-row-remove-icon-container {
border-radius: 0;
color: var(--cds-button-danger-secondary);
min-width: rem(40);
min-height: rem(40);

&:hover {
color: var(--cds-text-on-color);
background-color: var(--cds-button-danger-hover);
}
}

.fjs-repeat-row-container .fjs-repeat-row-remove:focus-visible .fjs-repeat-row-remove-icon-container {
outline: 2px solid var(--cds-focus);
outline-offset: 1px;
border-radius: 0;
}

.fjs-repeat-render-footer {
padding-left: 8px;
padding-right: 8px;
margin-right: 0;
}

.fjs-repeat-render-add,
.fjs-repeat-render-collapse {
min-height: rem(40);
padding-inline-end: rem(15);

&:focus {
outline: 2px solid var(--cds-focus);
outline-offset: 1px;
border: none;
border-radius: 0;
}

&:hover {
color: var(--cds-link-primary-hover);
background-color: var(--cds-background-hover);
}
}
}
24 changes: 24 additions & 0 deletions packages/form-js-carbon-styles/test/spec/complex.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,30 @@
"type": "iframe",
"label": "I am an iframe"
},
{
"id": "DynamicList_1a82jj2",
"type": "dynamiclist",
"label": "Clients",
"path": "clients",
"showOutline": true,
"isRepeating": true,
"defaultRepetitions": 2,
"allowAddRemove": true,
"components": [
{
"id": "DynamicListTextField_1",
"type": "textfield",
"key": "clientSurname",
"label": "Surname"
},
{
"id": "DynamicListTextField_2",
"type": "textfield",
"key": "clientName",
"label": "Name"
}
]
},
{
"label": "I am a textfield",
"type": "textfield",
Expand Down
45 changes: 38 additions & 7 deletions packages/form-js-editor/assets/form-js-editor-base.css
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@

.fjs-editor-container .fjs-form > .fjs-element {
border: none;
outline: none;
}

.fjs-editor-container .fjs-form-field:not(.fjs-powered-by) {
Expand All @@ -288,29 +289,31 @@
border-color: var(--color-children-hover-border);
}

.fjs-editor-container .fjs-layout-column:first-child > .fjs-element[data-field-type="group"] {
.fjs-editor-container .fjs-layout-column:first-child > .fjs-element[data-field-type="group"],
.fjs-editor-container .fjs-layout-column:first-child > .fjs-element[data-field-type="dynamiclist"] {
margin-left: -6px;
}

.fjs-editor-container .fjs-layout-column:last-child > .fjs-element[data-field-type="group"] {
.fjs-editor-container .fjs-layout-column:last-child > .fjs-element[data-field-type="group"],
.fjs-editor-container .fjs-layout-column:last-child > .fjs-element[data-field-type="dynamiclist"] {
margin-right: -6px;
}

.fjs-editor-container .fjs-form-field-group,
.fjs-editor-container .fjs-form-field-group .fjs-form-field-group .fjs-form-field-group {
.fjs-editor-container .fjs-form-field-grouplike,
.fjs-editor-container .fjs-form-field-grouplike .fjs-form-field-grouplike .fjs-form-field-grouplike {
margin: 1px 6px;
padding: 0px;
}

.fjs-editor-container .fjs-form-field-group.fjs-outlined {
.fjs-editor-container .fjs-form-field-grouplike.fjs-outlined {
outline: none;
}

.fjs-editor-container .fjs-form-field-group .cds--grid {
.fjs-editor-container .fjs-form-field-grouplike .cds--grid {
padding: 0 2rem;
}

.fjs-editor-container .fjs-form-field-group > label {
.fjs-editor-container .fjs-form-field-grouplike > label {
margin-top: 6px;
}

Expand All @@ -331,6 +334,19 @@
user-select: none;
}

.fjs-editor-container .fjs-empty-component {
display: flex;
justify-content: center;
align-items: center;
height: 80px;
width: calc(100% - 4rem);
position: absolute;
}

.fjs-editor-container .fjs-empty-component span {
color: var(--cds-text-disabled, var(--color-grey-225-10-55));
}

.fjs-editor-container .fjs-empty-editor {
display: flex;
align-items: center;
Expand Down Expand Up @@ -442,6 +458,21 @@
top: 0;
}

.fjs-editor-container .fjs-repeat-render-footer {
font-size: var(--font-size-label);
background: var(--cds-field, var(--color-background-disabled));
color: var(--cds-text-disabled, var(--color-grey-225-10-45));
padding: 3px;
display: flex;
align-items: center;
justify-content: center;
margin: 0px 5px 3px 5px;
}

.fjs-editor-container .fjs-repeat-render-footer svg {
margin-right: 4px;
}

/* do not show resize handles on small screens */
@media (max-width: 66rem) {
.fjs-editor-container .fjs-children .fjs-editor-selected .fjs-field-resize-handle {
Expand Down
14 changes: 13 additions & 1 deletion packages/form-js-editor/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,19 @@ module.exports = function(karma) {
'NODE_ENV'
],

reporters: [ 'progress' ].concat(coverage ? 'coverage' : []),
reporters: [ 'spec' ].concat(coverage ? 'coverage' : []),

specReporter: {
maxLogLines: 10,
suppressSummary: true,
suppressErrorSummary: false,
suppressFailed: false,
suppressPassed: false,
suppressSkipped: true,
showBrowser: false,
showSpecTiming: false,
failFast: false
},

coverageReporter: {
reporters: [
Expand Down
4 changes: 3 additions & 1 deletion packages/form-js-editor/src/FormEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SelectionModule from './features/selection';
import PaletteModule from './features/palette';
import PropertiesPanelModule from './features/properties-panel';
import RenderInjectionModule from './features/render-injection';
import RepeatRenderManagerModule from './features/repeat-render';
import ExpressionLanguageModule from './features/expression-language';

import { MarkdownModule } from '@bpmn-io/form-js-viewer';
Expand Down Expand Up @@ -309,7 +310,8 @@ export default class FormEditor {
ExpressionLanguageModule,
MarkdownModule,
PropertiesPanelModule,
RenderInjectionModule
RenderInjectionModule,
RepeatRenderManagerModule
];
}

Expand Down
5 changes: 3 additions & 2 deletions packages/form-js-editor/src/features/dragging/Dragging.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import dragula from '@bpmn-io/draggle';

import { set as setCursor } from '../../render/util/Cursor';
import { getAncestryList } from '@bpmn-io/form-js-viewer';

export const DRAG_CONTAINER_CLS = 'fjs-drag-container';
export const DROP_CONTAINER_VERTICAL_CLS = 'fjs-drop-container-vertical';
Expand Down Expand Up @@ -111,13 +112,13 @@ export default class Dragging {

if (targetParentPath.join('.') !== currentParentPath.join('.')) {

const isDropAllowedByPathRegistry = this._pathRegistry.executeRecursivelyOnFields(formField, ({ field, isClosed }) => {
const isDropAllowedByPathRegistry = this._pathRegistry.executeRecursivelyOnFields(formField, ({ field, isClosed, isRepeatable }) => {
const options = {
cutoffNode: currentParentFormField.id,
};

const fieldPath = this._pathRegistry.getValuePath(field, options);
return this._pathRegistry.canClaimPath([ ...targetParentPath, ...fieldPath ], isClosed);
return this._pathRegistry.canClaimPath([ ...targetParentPath, ...fieldPath ], { isClosed, isRepeatable, knownAncestorIds: getAncestryList(targetParentId, this._formFieldRegistry) });
});

if (!isDropAllowedByPathRegistry) {
Expand Down
Loading

0 comments on commit 62f71cf

Please sign in to comment.