From dfc6c263b3c33ed9676938431b0c3794e1a9d485 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Thu, 9 Jan 2025 10:25:59 +0100 Subject: [PATCH 01/21] lmb-182: add modal with version one form for editing the form --- .../rdf-input-fields/custom-field-wrapper.hbs | 124 ++++++++++++------ .../rdf-input-fields/custom-field-wrapper.js | 34 +++++ 2 files changed, 117 insertions(+), 41 deletions(-) diff --git a/app/components/rdf-input-fields/custom-field-wrapper.hbs b/app/components/rdf-input-fields/custom-field-wrapper.hbs index 1908cd364..c2fcca41e 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.hbs +++ b/app/components/rdf-input-fields/custom-field-wrapper.hbs @@ -1,52 +1,27 @@ {{#unless this.removed}} - {{#if @inline}} +
{{this.title}} -
-
- {{yield}} -
- - Verwijder - + Verwijder + +
+
+
+ {{yield}}
- {{else}} -
- {{this.title}} - - Verwijder - -
- {{yield}} - {{/if}} +
{{#each this.errors as |error|}} {{error.resultMessage}} {{/each}} @@ -54,4 +29,71 @@ {{#each this.warnings as |warning|}} {{warning.resultMessage}} {{/each}} -{{/unless}} \ No newline at end of file +{{/unless}} + + +
+ + Naam + + + + Type + + + + Positie in formulier + + + + + + + Pas aan + + + + Verwijder + + + +
+
\ No newline at end of file diff --git a/app/components/rdf-input-fields/custom-field-wrapper.js b/app/components/rdf-input-fields/custom-field-wrapper.js index 0fdd896f6..3b0a19749 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.js +++ b/app/components/rdf-input-fields/custom-field-wrapper.js @@ -1,19 +1,36 @@ import Component from '@glimmer/component'; + import { action } from '@ember/object'; import { service } from '@ember/service'; import { tracked } from '@glimmer/tracking'; + import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; + import { consume } from 'ember-provide-consume-context'; +import { task } from 'ember-concurrency'; +import { showSuccessToast } from 'frontend-lmb/utils/toasts'; export default class RdfInputFieldsCustomFieldWrapperComponent extends Component { + @service toaster; @service formReplacements; @consume('on-form-update') onUpdate; @tracked removing = false; + @tracked showEditFieldModal; + + // Field properties + @tracked name; + @tracked type; + @tracked order; + get title() { return this.args.field?.label; } + get canSaveChanges() { + return this.name && this.type && this.order; + } + @action async onRemove() { this.removing = true; @@ -30,4 +47,21 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component this.onUpdate(); this.removed = true; } + + @action + closeEditFieldModal() { + this.showEditFieldModal = false; + } + + @action + updateField(event) { + const { name, value } = event.target; + this[name] = value; + } + + saveChanges = task(async () => { + // TODO: + this.showEditFieldModal = false; + showSuccessToast(this.toaster, 'Het veld werd succesvol aangepast.'); + }); } From ef8f025690f6cb45885c961d43fe1fdb94e5f0ed Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Thu, 9 Jan 2025 10:46:39 +0100 Subject: [PATCH 02/21] lmb-182: load in the current field values for the edit modal --- .../rdf-input-fields/custom-field-wrapper.hbs | 7 ++++--- .../rdf-input-fields/custom-field-wrapper.js | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/components/rdf-input-fields/custom-field-wrapper.hbs b/app/components/rdf-input-fields/custom-field-wrapper.hbs index c2fcca41e..29b7a32b1 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.hbs +++ b/app/components/rdf-input-fields/custom-field-wrapper.hbs @@ -12,7 +12,7 @@ @hideText={{true}} {{on "click" (fn (mut this.showEditFieldModal) true)}} > - Verwijder + Pas aan
@@ -43,7 +44,7 @@ diff --git a/app/components/rdf-input-fields/custom-field-wrapper.js b/app/components/rdf-input-fields/custom-field-wrapper.js index 3b0a19749..7931f7ebd 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.js +++ b/app/components/rdf-input-fields/custom-field-wrapper.js @@ -28,7 +28,23 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component } get canSaveChanges() { - return this.name && this.type && this.order; + return this.fieldHasChanged && this.name && this.type && this.order; + } + + get fieldHasChanged() { + const { label, order, displayType } = this.args.field; + + return ( + this.name != label || this.type != displayType || this.order != order + ); + } + + @action + async loadCurrentFieldInfo() { + const { label, order, displayType } = this.args.field; + this.name = label; + this.type = displayType; + this.order = order; } @action From c811873faef4e3e49abb58b7204b85ae7ad8b85d Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Thu, 9 Jan 2025 12:27:18 +0100 Subject: [PATCH 03/21] lmb-182: make the display type a dropdown --- .../display-type-selector.hbs | 23 +++++++++++++ .../display-type-selector.js | 34 +++++++++++++++++++ .../rdf-input-fields/custom-field-wrapper.hbs | 12 +++---- app/config/custom-inflector-rules.js | 3 ++ app/models/form-library/display-type.js | 6 ++++ .../models/form-library/display-type-test.js | 14 ++++++++ 6 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 app/components/custom-form-fields/display-type-selector.hbs create mode 100644 app/components/custom-form-fields/display-type-selector.js create mode 100644 app/models/form-library/display-type.js create mode 100644 tests/unit/models/form-library/display-type-test.js diff --git a/app/components/custom-form-fields/display-type-selector.hbs b/app/components/custom-form-fields/display-type-selector.hbs new file mode 100644 index 000000000..3c47a8308 --- /dev/null +++ b/app/components/custom-form-fields/display-type-selector.hbs @@ -0,0 +1,23 @@ +
+ {{#unless @inTable}} + + {{this.label}} + + {{/unless}} + + + {{displayType.label}} + + +
\ No newline at end of file diff --git a/app/components/custom-form-fields/display-type-selector.js b/app/components/custom-form-fields/display-type-selector.js new file mode 100644 index 000000000..c2893080c --- /dev/null +++ b/app/components/custom-form-fields/display-type-selector.js @@ -0,0 +1,34 @@ +import Component from '@glimmer/component'; + +import { action } from '@ember/object'; +import { tracked } from '@glimmer/tracking'; +import { service } from '@ember/service'; + +export default class CustomFormFieldsDisplayTypeSelectorComponent extends Component { + @service store; + + @tracked typeOptions = []; + + @action + async load() { + this.typeOptions = await this.store.findAll('form-library/display-type'); + } + + @action + async updateSelectedType(type) { + // This event.target is used in the update method of the edit field /custom-field-wrapper-js + this.args.onTypeUpdated({ + target: { name: this.args.variableName, value: type.uri }, + }); + } + + get label() { + return this.args.label || 'Type'; + } + + get selectedType() { + return this.typeOptions.find( + (option) => option.uri === this.args.displayTypeUri + ); + } +} diff --git a/app/components/rdf-input-fields/custom-field-wrapper.hbs b/app/components/rdf-input-fields/custom-field-wrapper.hbs index 29b7a32b1..4e53371da 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.hbs +++ b/app/components/rdf-input-fields/custom-field-wrapper.hbs @@ -50,13 +50,11 @@ />
- Type - diff --git a/app/config/custom-inflector-rules.js b/app/config/custom-inflector-rules.js index 2399b02d5..57498add4 100644 --- a/app/config/custom-inflector-rules.js +++ b/app/config/custom-inflector-rules.js @@ -73,3 +73,6 @@ inflector.irregular('global-system-message', 'global-system-messages'); inflector.irregular('werkingsgebied', 'werkingsgebieden'); inflector.irregular('bestuurseenheid-contact', 'bestuurseenheid-contacten'); + +// Form Library +inflector.irregular('form-library/display-type', 'display-types'); diff --git a/app/models/form-library/display-type.js b/app/models/form-library/display-type.js new file mode 100644 index 000000000..1144d47cb --- /dev/null +++ b/app/models/form-library/display-type.js @@ -0,0 +1,6 @@ +import Model, { attr } from '@ember-data/model'; + +export default class FormLibraryDisplayTypeModel extends Model { + @attr uri; + @attr label; +} diff --git a/tests/unit/models/form-library/display-type-test.js b/tests/unit/models/form-library/display-type-test.js new file mode 100644 index 000000000..02d973a66 --- /dev/null +++ b/tests/unit/models/form-library/display-type-test.js @@ -0,0 +1,14 @@ +import { module, test } from 'qunit'; + +import { setupTest } from 'frontend-lmb/tests/helpers'; + +module('Unit | Model | form library/display type', function (hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord('form-library/display-type', {}); + assert.ok(model); + }); +}); From 650cdc0d3d0f766dca4669f41e945cc399bce2b9 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Thu, 9 Jan 2025 12:32:31 +0100 Subject: [PATCH 04/21] lmb-182: make the dropdown use the full width in the form --- app/components/rdf-input-fields/custom-field-wrapper.hbs | 2 +- app/styles/_shame.scss | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/components/rdf-input-fields/custom-field-wrapper.hbs b/app/components/rdf-input-fields/custom-field-wrapper.hbs index 4e53371da..8a5f8b245 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.hbs +++ b/app/components/rdf-input-fields/custom-field-wrapper.hbs @@ -49,7 +49,7 @@ id="name" /> - + Date: Thu, 9 Jan 2025 14:46:29 +0100 Subject: [PATCH 05/21] lmb-182: the field is updated --- .../display-type-selector.js | 2 +- .../rdf-input-fields/custom-field-wrapper.js | 40 +++++++++++++++---- app/config/custom-inflector-rules.js | 3 -- app/models/form-library/display-type.js | 6 --- 4 files changed, 34 insertions(+), 17 deletions(-) delete mode 100644 app/models/form-library/display-type.js diff --git a/app/components/custom-form-fields/display-type-selector.js b/app/components/custom-form-fields/display-type-selector.js index c2893080c..5b1c74018 100644 --- a/app/components/custom-form-fields/display-type-selector.js +++ b/app/components/custom-form-fields/display-type-selector.js @@ -11,7 +11,7 @@ export default class CustomFormFieldsDisplayTypeSelectorComponent extends Compon @action async load() { - this.typeOptions = await this.store.findAll('form-library/display-type'); + this.typeOptions = await this.store.findAll('display-type'); } @action diff --git a/app/components/rdf-input-fields/custom-field-wrapper.js b/app/components/rdf-input-fields/custom-field-wrapper.js index 7931f7ebd..f943f5bd8 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.js +++ b/app/components/rdf-input-fields/custom-field-wrapper.js @@ -4,16 +4,16 @@ import { action } from '@ember/object'; import { service } from '@ember/service'; import { tracked } from '@glimmer/tracking'; -import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; - -import { consume } from 'ember-provide-consume-context'; import { task } from 'ember-concurrency'; -import { showSuccessToast } from 'frontend-lmb/utils/toasts'; + +import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; +import { showErrorToast, showSuccessToast } from 'frontend-lmb/utils/toasts'; +import { MANDATARIS_EXTRA_INFO_FORM_ID } from 'frontend-lmb/utils/well-known-ids'; export default class RdfInputFieldsCustomFieldWrapperComponent extends Component { @service toaster; @service formReplacements; - @consume('on-form-update') onUpdate; + @service semanticFormRepository; @tracked removing = false; @tracked showEditFieldModal; @@ -60,7 +60,6 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component formUri: this.args.form.uri, }), }); - this.onUpdate(); this.removed = true; } @@ -76,7 +75,34 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component } saveChanges = task(async () => { - // TODO: + try { + const result = await fetch( + `/form-content/${MANDATARIS_EXTRA_INFO_FORM_ID}/fields`, + { + method: 'POST', + headers: { + 'Content-Type': JSON_API_TYPE, + }, + body: JSON.stringify({ + displayType: this.type, + order: this.order, + name: this.name, + }), + } + ); + + const body = await result.json(); + const newFormId = body.id; + this.formReplacements.setReplacement( + MANDATARIS_EXTRA_INFO_FORM_ID, + newFormId + ); + } catch (error) { + showErrorToast( + this.toaster, + 'Er ging iets mis bij het aanpassen van het veld.' + ); + } this.showEditFieldModal = false; showSuccessToast(this.toaster, 'Het veld werd succesvol aangepast.'); }); diff --git a/app/config/custom-inflector-rules.js b/app/config/custom-inflector-rules.js index 57498add4..2399b02d5 100644 --- a/app/config/custom-inflector-rules.js +++ b/app/config/custom-inflector-rules.js @@ -73,6 +73,3 @@ inflector.irregular('global-system-message', 'global-system-messages'); inflector.irregular('werkingsgebied', 'werkingsgebieden'); inflector.irregular('bestuurseenheid-contact', 'bestuurseenheid-contacten'); - -// Form Library -inflector.irregular('form-library/display-type', 'display-types'); diff --git a/app/models/form-library/display-type.js b/app/models/form-library/display-type.js deleted file mode 100644 index 1144d47cb..000000000 --- a/app/models/form-library/display-type.js +++ /dev/null @@ -1,6 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class FormLibraryDisplayTypeModel extends Model { - @attr uri; - @attr label; -} From 15f914be7b543e30407605ef3a0bff591a1258c5 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Thu, 9 Jan 2025 15:22:49 +0100 Subject: [PATCH 06/21] lmb-182: refresh the form when updating a field --- app/components/rdf-input-fields/custom-field-wrapper.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/components/rdf-input-fields/custom-field-wrapper.js b/app/components/rdf-input-fields/custom-field-wrapper.js index f943f5bd8..fcbf86b91 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.js +++ b/app/components/rdf-input-fields/custom-field-wrapper.js @@ -5,12 +5,15 @@ import { service } from '@ember/service'; import { tracked } from '@glimmer/tracking'; import { task } from 'ember-concurrency'; +import { consume } from 'ember-provide-consume-context'; import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; import { showErrorToast, showSuccessToast } from 'frontend-lmb/utils/toasts'; import { MANDATARIS_EXTRA_INFO_FORM_ID } from 'frontend-lmb/utils/well-known-ids'; export default class RdfInputFieldsCustomFieldWrapperComponent extends Component { + @consume('on-form-update') onFormUpdate; + @service toaster; @service formReplacements; @service semanticFormRepository; @@ -60,6 +63,7 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component formUri: this.args.form.uri, }), }); + this.onFormUpdate(); this.removed = true; } @@ -97,10 +101,11 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component MANDATARIS_EXTRA_INFO_FORM_ID, newFormId ); + this.onFormUpdate(); } catch (error) { showErrorToast( this.toaster, - 'Er ging iets mis bij het aanpassen van het veld.' + 'Er ging iets mis bij het opslaan van het veld.' ); } this.showEditFieldModal = false; From 09bf43a6a2335119b6d5622c6cea2c4c9d7b4342 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Thu, 9 Jan 2025 15:42:00 +0100 Subject: [PATCH 07/21] lmb-182: provide the editable form id, this fixes the disappearing fields --- app/components/editable-form.js | 5 +++ .../rdf-input-fields/custom-field-wrapper.js | 36 ++++++++++--------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/app/components/editable-form.js b/app/components/editable-form.js index d7aec8307..9a7979cb3 100644 --- a/app/components/editable-form.js +++ b/app/components/editable-form.js @@ -38,4 +38,9 @@ export default class EditableFormComponent extends Component { onFormUpdate() { this.updateForm(); } + + @provide('editable-form-id') + get editableFormId() { + return this.currentForm.id; + } } diff --git a/app/components/rdf-input-fields/custom-field-wrapper.js b/app/components/rdf-input-fields/custom-field-wrapper.js index fcbf86b91..f38167e6e 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.js +++ b/app/components/rdf-input-fields/custom-field-wrapper.js @@ -9,10 +9,10 @@ import { consume } from 'ember-provide-consume-context'; import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; import { showErrorToast, showSuccessToast } from 'frontend-lmb/utils/toasts'; -import { MANDATARIS_EXTRA_INFO_FORM_ID } from 'frontend-lmb/utils/well-known-ids'; export default class RdfInputFieldsCustomFieldWrapperComponent extends Component { @consume('on-form-update') onFormUpdate; + @consume('editable-form-id') editableFormId; @service toaster; @service formReplacements; @@ -53,18 +53,9 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component @action async onRemove() { this.removing = true; - await fetch(`/form-content/fields`, { - method: 'DELETE', - headers: { - 'Content-Type': JSON_API_TYPE, - }, - body: JSON.stringify({ - fieldUri: this.args.field.uri.value, - formUri: this.args.form.uri, - }), - }); + await this.removeField(); this.onFormUpdate(); - this.removed = true; + this.removed = false; } @action @@ -79,9 +70,10 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component } saveChanges = task(async () => { + await this.removeField(); try { const result = await fetch( - `/form-content/${MANDATARIS_EXTRA_INFO_FORM_ID}/fields`, + `/form-content/${this.editableFormId}/fields`, { method: 'POST', headers: { @@ -97,10 +89,7 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component const body = await result.json(); const newFormId = body.id; - this.formReplacements.setReplacement( - MANDATARIS_EXTRA_INFO_FORM_ID, - newFormId - ); + this.formReplacements.setReplacement(this.editableFormId, newFormId); this.onFormUpdate(); } catch (error) { showErrorToast( @@ -111,4 +100,17 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component this.showEditFieldModal = false; showSuccessToast(this.toaster, 'Het veld werd succesvol aangepast.'); }); + + async removeField() { + await fetch(`/form-content/fields`, { + method: 'DELETE', + headers: { + 'Content-Type': JSON_API_TYPE, + }, + body: JSON.stringify({ + fieldUri: this.args.field.uri.value, + formUri: this.args.form.uri, + }), + }); + } } From 9a3c81e89bfc7df9e322802a148dddc8b12412db Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Thu, 9 Jan 2025 17:18:26 +0100 Subject: [PATCH 08/21] lmb-182: disable type selector when the field has a library entree --- .../display-type-selector.hbs | 1 + app/components/editable-form.js | 6 ++--- .../rdf-input-fields/custom-field-wrapper.hbs | 1 + .../rdf-input-fields/custom-field-wrapper.js | 27 ++++++++++++++++--- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/app/components/custom-form-fields/display-type-selector.hbs b/app/components/custom-form-fields/display-type-selector.hbs index 3c47a8308..cee392da4 100644 --- a/app/components/custom-form-fields/display-type-selector.hbs +++ b/app/components/custom-form-fields/display-type-selector.hbs @@ -5,6 +5,7 @@ {{/unless}} Date: Thu, 9 Jan 2025 17:24:06 +0100 Subject: [PATCH 09/21] lmb-182: add library entree uri to the post call --- app/components/rdf-input-fields/custom-field-wrapper.hbs | 2 +- app/components/rdf-input-fields/custom-field-wrapper.js | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/components/rdf-input-fields/custom-field-wrapper.hbs b/app/components/rdf-input-fields/custom-field-wrapper.hbs index 7ad180478..ceb51a7f9 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.hbs +++ b/app/components/rdf-input-fields/custom-field-wrapper.hbs @@ -51,7 +51,7 @@ Date: Fri, 10 Jan 2025 08:39:32 +0100 Subject: [PATCH 10/21] lmb-182: comment the order field in the edit modal as we do not want to show this as a number for the DEMO 10/01/2025 --- app/components/rdf-input-fields/custom-field-wrapper.hbs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/components/rdf-input-fields/custom-field-wrapper.hbs b/app/components/rdf-input-fields/custom-field-wrapper.hbs index ceb51a7f9..a3a1d5cb6 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.hbs +++ b/app/components/rdf-input-fields/custom-field-wrapper.hbs @@ -58,7 +58,8 @@ @onTypeUpdated={{this.updateField}} /> - + {{!-- Commented because we do not want to show the order as a number here for demo + Positie in formulier - + --}} Date: Fri, 10 Jan 2025 11:59:06 +0100 Subject: [PATCH 11/21] lmb-182: create a component that can be shown and hidden through args + dynamic title --- .../crud-custom-field-modal.hbs | 8 ++++++ .../crud-custom-field-modal.js | 20 ++++++++++++++ .../crud-custom-field-modal-test.js | 27 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 app/components/rdf-input-fields/crud-custom-field-modal.hbs create mode 100644 app/components/rdf-input-fields/crud-custom-field-modal.js create mode 100644 tests/integration/components/rdf-input-fields/crud-custom-field-modal-test.js diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.hbs b/app/components/rdf-input-fields/crud-custom-field-modal.hbs new file mode 100644 index 000000000..83e6d341b --- /dev/null +++ b/app/components/rdf-input-fields/crud-custom-field-modal.hbs @@ -0,0 +1,8 @@ + + modal + \ No newline at end of file diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.js b/app/components/rdf-input-fields/crud-custom-field-modal.js new file mode 100644 index 000000000..ceead9646 --- /dev/null +++ b/app/components/rdf-input-fields/crud-custom-field-modal.js @@ -0,0 +1,20 @@ +import Component from '@glimmer/component'; + +import { action } from '@ember/object'; + +export default class RdfInputFieldCrudCustomFieldModalComponent extends Component { + @action + closeModal() { + if (this.args.onCloseModal) { + this.args.onCloseModal(); + } + } + + get title() { + if (this.args.isCreating) { + return 'Voeg een veld toe'; + } + + return 'Pas een veld aan'; + } +} diff --git a/tests/integration/components/rdf-input-fields/crud-custom-field-modal-test.js b/tests/integration/components/rdf-input-fields/crud-custom-field-modal-test.js new file mode 100644 index 000000000..6ba42e40a --- /dev/null +++ b/tests/integration/components/rdf-input-fields/crud-custom-field-modal-test.js @@ -0,0 +1,27 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'frontend-lmb/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module( + 'Integration | Component | rdf-input-fields/crud-custom-field-modal', + function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs``); + + assert.dom(this.element).hasText(''); + + // Template block usage: + await render(hbs` + template block text +`); + + assert.dom(this.element).hasText('template block text'); + }); + } +); From fdc3edce36cf8808ad8e93d8484d7eac50f75dd2 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 12:18:19 +0100 Subject: [PATCH 12/21] lmb-182: add a start form for the modal that shows different buttons depending onj the action --- .../crud-custom-field-modal.hbs | 49 ++++++++++++++- .../crud-custom-field-modal.js | 59 +++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.hbs b/app/components/rdf-input-fields/crud-custom-field-modal.hbs index 83e6d341b..9fa8601f5 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.hbs +++ b/app/components/rdf-input-fields/crud-custom-field-modal.hbs @@ -4,5 +4,52 @@ @closable={{true}} @title={{this.title}} > - modal + <:body> + + + Naam + + + + + <:footer> + + + + {{this.saveText}} + + + {{#if @isCreating}} + + Annuleer + + {{else}} + + Verwijder + + {{/if}} + + + \ No newline at end of file diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.js b/app/components/rdf-input-fields/crud-custom-field-modal.js index ceead9646..d13004bbe 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.js +++ b/app/components/rdf-input-fields/crud-custom-field-modal.js @@ -1,8 +1,47 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; +import { tracked } from '@glimmer/tracking'; + +import { task } from 'ember-concurrency'; + +import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; export default class RdfInputFieldCrudCustomFieldModalComponent extends Component { + @tracked isRemovingField; + + // Field properties + @tracked fieldName; + + @action + updateField(event) { + const { name, value } = event.target; + this[name] = value; + } + + saveChanges = task(async () => {}); + + async removeField() { + await fetch(`/form-content/fields`, { + method: 'DELETE', + headers: { + 'Content-Type': JSON_API_TYPE, + }, + body: JSON.stringify({ + fieldUri: this.args.field.uri.value, + formUri: this.args.form.uri, + }), + }); + } + + @action + async onRemove() { + this.isRemovingField = true; + await this.removeField(); + this.onFormUpdate(); + this.isRemovingField = false; + } + @action closeModal() { if (this.args.onCloseModal) { @@ -10,6 +49,18 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen } } + get canSaveChanges() { + return this.fieldHasChanged && this.fieldName; + } + + get fieldHasChanged() { + if (this.args.isCreating) { + return true; + } + + return this.fieldName !== this.args.field.label; + } + get title() { if (this.args.isCreating) { return 'Voeg een veld toe'; @@ -17,4 +68,12 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen return 'Pas een veld aan'; } + + get saveText() { + if (this.args.isCreating) { + return 'Bewaar'; + } + + return 'Pas aan'; + } } From 1b7dd48c4156be14437fd72fdb92497b30ee9088 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 12:32:37 +0100 Subject: [PATCH 13/21] lmb-182: show the library entry dropdown --- .../crud-custom-field-modal.hbs | 22 ++++++ .../crud-custom-field-modal.js | 75 ++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.hbs b/app/components/rdf-input-fields/crud-custom-field-modal.hbs index 9fa8601f5..45c157a23 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.hbs +++ b/app/components/rdf-input-fields/crud-custom-field-modal.hbs @@ -16,6 +16,28 @@ id="fieldName" /> + {{#if @isCreating}} + + Uit bibliotheek + + {{selected.name}} + + + {{/if}} <:footer> diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.js b/app/components/rdf-input-fields/crud-custom-field-modal.js index d13004bbe..0b7899bf4 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.js +++ b/app/components/rdf-input-fields/crud-custom-field-modal.js @@ -2,16 +2,44 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; import { tracked } from '@glimmer/tracking'; +import { service } from '@ember/service'; import { task } from 'ember-concurrency'; +import { ForkingStore } from '@lblod/ember-submission-form-fields'; +import { consume } from 'ember-provide-consume-context'; -import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; +import { JSON_API_TYPE, SOURCE_GRAPH } from 'frontend-lmb/utils/constants'; +import { PROV } from 'frontend-lmb/rdf/namespaces'; +import { TEXT_CUSTOM_DISPLAY_TYPE_ID } from 'frontend-lmb/utils/well-known-ids'; export default class RdfInputFieldCrudCustomFieldModalComponent extends Component { + @consume('form-definition') formDefinition; + + @service store; + @tracked isRemovingField; + customFieldEntry = this.store.createRecord('library-entry', { + name: 'Eigen veld', + }); + // Field properties @tracked fieldName; + @tracked libraryFieldType = this.customFieldEntry; + @tracked displayType; + + constructor() { + super(...arguments); + + if (this.args.isCreating) { + this.displayTypes.then((displayTypes) => { + this.displayType = displayTypes.findBy( + 'id', + TEXT_CUSTOM_DISPLAY_TYPE_ID + ); + }); + } + } @action updateField(event) { @@ -21,6 +49,16 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen saveChanges = task(async () => {}); + @action + selectLibraryFieldType(libraryEntry) { + this.libraryFieldType = libraryEntry; + this.displayTypes.then((types) => { + this.displayType = + types.findBy('uri', libraryEntry.get('displayType.uri')) || + types.findBy('id', TEXT_CUSTOM_DISPLAY_TYPE_ID); + }); + } + async removeField() { await fetch(`/form-content/fields`, { method: 'DELETE', @@ -49,6 +87,41 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen } } + get displayTypes() { + return this.store.findAll('display-type').then((entries) => { + return entries.sortBy('label'); + }); + } + + get libraryFieldOptions() { + const forkingStore = new ForkingStore(); + forkingStore.parse( + this.formDefinition.formTtl, + SOURCE_GRAPH, + 'text/turtle' + ); + + const alreadyUsedLibraryEntries = forkingStore + .match(null, PROV('wasDerivedFrom'), null, SOURCE_GRAPH) + .map((triple) => triple.object.value); + + return this.store + .findAll('library-entry', { include: 'display-type' }) + .then((entries) => { + return [ + this.customFieldEntry, + ...entries + .sortBy('id') + .reverse() + .filter((entry) => { + return ( + entry.uri && alreadyUsedLibraryEntries.indexOf(entry.uri) < 0 + ); + }), + ]; + }); + } + get canSaveChanges() { return this.fieldHasChanged && this.fieldName; } From 244b9b56a80da43bafaa316c7aab4322d9feca53 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 12:37:19 +0100 Subject: [PATCH 14/21] lmb-182: validate input field before saving + reset values when modal closes --- .../rdf-input-fields/crud-custom-field-modal.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.js b/app/components/rdf-input-fields/crud-custom-field-modal.js index 0b7899bf4..ef8af8fc6 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.js +++ b/app/components/rdf-input-fields/crud-custom-field-modal.js @@ -83,6 +83,9 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen @action closeModal() { if (this.args.onCloseModal) { + this.fieldName = null; + this.libraryFieldType = null; + this.displayType = null; this.args.onCloseModal(); } } @@ -123,17 +126,23 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen } get canSaveChanges() { - return this.fieldHasChanged && this.fieldName; + return ( + this.fieldHasChanged && this.hasValidFieldName && this.libraryFieldType + ); } get fieldHasChanged() { if (this.args.isCreating) { - return true; + return this.fieldName && this.libraryFieldType; } return this.fieldName !== this.args.field.label; } + get hasValidFieldName() { + return this.fieldName || this.fieldName.trim().length > 1; + } + get title() { if (this.args.isCreating) { return 'Voeg een veld toe'; From 088bbc52af6153fc0226c9a93cd369a155d36e3d Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 12:50:39 +0100 Subject: [PATCH 15/21] lmb-182: add the displayType selector to the form --- .../crud-custom-field-modal.hbs | 22 ++++++++++++++++++ .../crud-custom-field-modal.js | 23 ++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.hbs b/app/components/rdf-input-fields/crud-custom-field-modal.hbs index 45c157a23..a26889e1a 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.hbs +++ b/app/components/rdf-input-fields/crud-custom-field-modal.hbs @@ -38,6 +38,28 @@ {{/if}} + {{#if this.canSelectTypeForEntry}} + + Type + + {{selected.label}} + + + {{/if}} <:footer> diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.js b/app/components/rdf-input-fields/crud-custom-field-modal.js index ef8af8fc6..e4500b0b5 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.js +++ b/app/components/rdf-input-fields/crud-custom-field-modal.js @@ -59,6 +59,11 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen }); } + @action + selectDisplayType(displayType) { + this.displayType = displayType; + } + async removeField() { await fetch(`/form-content/fields`, { method: 'DELETE', @@ -133,14 +138,26 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen get fieldHasChanged() { if (this.args.isCreating) { - return this.fieldName && this.libraryFieldType; + return true; + } + + if (!this.hasValidFieldName) { + return false; } - return this.fieldName !== this.args.field.label; + if (this.canSelectTypeForEntry) { + return this.displayType !== this.args.field.type; + } + + return false; } get hasValidFieldName() { - return this.fieldName || this.fieldName.trim().length > 1; + return this.fieldName && this.fieldName.trim().length > 1; + } + + get canSelectTypeForEntry() { + return this.libraryFieldType === this.customFieldEntry; } get title() { From c983eb166688157240e9e45bc8a99a70c0f59cf8 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 12:58:30 +0100 Subject: [PATCH 16/21] lmb-182: show the crud modal instead of the other form in generate custom field button --- .../generate-custom-field-button.hbs | 91 ++----------------- 1 file changed, 9 insertions(+), 82 deletions(-) diff --git a/app/components/generate-custom-field-button.hbs b/app/components/generate-custom-field-button.hbs index b3513605f..d8359812d 100644 --- a/app/components/generate-custom-field-button.hbs +++ b/app/components/generate-custom-field-button.hbs @@ -1,91 +1,18 @@ Voeg een veld toe -{{yield}} - -
-
- Naam - -
-
- Uit bibliotheek - - {{selected.name}} - -
-
- Type - - {{selected.label}} - -
- - - - - - Bewaar - - - - Annuleer - - - - -
+{{yield}} -
\ No newline at end of file + \ No newline at end of file From 8e8c7d786f657069e76c75fc1121e2672515b150 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 15:37:07 +0100 Subject: [PATCH 17/21] lmb-182: can create and edit a custom field --- .../crud-custom-field-modal.hbs | 2 +- .../crud-custom-field-modal.js | 76 ++++++++++++++++--- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.hbs b/app/components/rdf-input-fields/crud-custom-field-modal.hbs index a26889e1a..02576d900 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.hbs +++ b/app/components/rdf-input-fields/crud-custom-field-modal.hbs @@ -11,7 +11,7 @@ diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.js b/app/components/rdf-input-fields/crud-custom-field-modal.js index e4500b0b5..4a6d3b35d 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.js +++ b/app/components/rdf-input-fields/crud-custom-field-modal.js @@ -11,11 +11,15 @@ import { consume } from 'ember-provide-consume-context'; import { JSON_API_TYPE, SOURCE_GRAPH } from 'frontend-lmb/utils/constants'; import { PROV } from 'frontend-lmb/rdf/namespaces'; import { TEXT_CUSTOM_DISPLAY_TYPE_ID } from 'frontend-lmb/utils/well-known-ids'; +import { showErrorToast } from 'frontend-lmb/utils/toasts'; export default class RdfInputFieldCrudCustomFieldModalComponent extends Component { @consume('form-definition') formDefinition; + @consume('on-form-update') onFormUpdate; @service store; + @service toaster; + @service formReplacements; @tracked isRemovingField; @@ -31,14 +35,18 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen constructor() { super(...arguments); - if (this.args.isCreating) { - this.displayTypes.then((displayTypes) => { - this.displayType = displayTypes.findBy( - 'id', - TEXT_CUSTOM_DISPLAY_TYPE_ID - ); - }); + let byProperty = 'id'; + let withValue = TEXT_CUSTOM_DISPLAY_TYPE_ID; + if (!this.args.isCreating) { + const { label, displayType } = this.args.field; + this.fieldName = label; + byProperty = 'uri'; + withValue = displayType; } + + this.displayTypes.then((displayTypes) => { + this.displayType = displayTypes.findBy(byProperty, withValue); + }); } @action @@ -47,7 +55,40 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen this[name] = value; } - saveChanges = task(async () => {}); + saveChanges = task(async () => { + if (!this.args.isCreating) { + await this.removeField(); + } + try { + const result = await fetch( + `/form-content/${this.formDefinition.id}/fields`, + { + method: 'POST', + headers: { + 'Content-Type': JSON_API_TYPE, + }, + body: JSON.stringify({ + displayType: this.displayType.uri, + libraryEntryUri: this.libraryFieldType.uri, + order: 9000, + name: this.fieldName, + }), + } + ); + + const body = await result.json(); + const newFormId = body.id; + this.formReplacements.setReplacement(this.formDefinition.id, newFormId); + this.onFormUpdate(); + } catch (error) { + showErrorToast( + this.toaster, + 'Er ging iets mis bij het opslaan van het veld.' + ); + return; + } + this.showEditFieldModal = false; + }); @action selectLibraryFieldType(libraryEntry) { @@ -101,6 +142,19 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen }); } + get libraryEntryUri() { + const localStore = new ForkingStore(); + localStore.parse(this.formDefinition.formTtl, SOURCE_GRAPH, 'text/turtle'); + const libraryEntree = localStore.any( + this.args.field.uri, + PROV('wasDerivedFrom'), + null, + SOURCE_GRAPH + ); + + return libraryEntree?.value; + } + get libraryFieldOptions() { const forkingStore = new ForkingStore(); forkingStore.parse( @@ -157,7 +211,11 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen } get canSelectTypeForEntry() { - return this.libraryFieldType === this.customFieldEntry; + if (this.args.isCreating) { + return this.libraryFieldType === this.customFieldEntry; + } + + return this.libraryEntryUri === this.customFieldEntry.uri; } get title() { From 9fdfbbb744ebba48cedc90d5c465c13b9a13a634 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 15:39:13 +0100 Subject: [PATCH 18/21] lmb-182: cleanup the custom field wrapper --- .../rdf-input-fields/custom-field-wrapper.hbs | 76 ++--------- .../rdf-input-fields/custom-field-wrapper.js | 122 +----------------- 2 files changed, 9 insertions(+), 189 deletions(-) diff --git a/app/components/rdf-input-fields/custom-field-wrapper.hbs b/app/components/rdf-input-fields/custom-field-wrapper.hbs index a3a1d5cb6..d193bc345 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.hbs +++ b/app/components/rdf-input-fields/custom-field-wrapper.hbs @@ -10,7 +10,7 @@ @skin="link-secondary" @icon="pencil" @hideText={{true}} - {{on "click" (fn (mut this.showEditFieldModal) true)}} + {{on "click" (fn (mut this.showModal) true)}} > Pas aan @@ -31,70 +31,10 @@ {{/each}} {{/unless}} - -
- - Naam - - - - - - {{!-- Commented because we do not want to show the order as a number here for demo - - Positie in formulier - - --}} - - - - - Pas aan - - - - Verwijder - - - -
-
\ No newline at end of file + \ No newline at end of file diff --git a/app/components/rdf-input-fields/custom-field-wrapper.js b/app/components/rdf-input-fields/custom-field-wrapper.js index 6d8b6c139..48d8fe1f1 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.js +++ b/app/components/rdf-input-fields/custom-field-wrapper.js @@ -1,136 +1,16 @@ import Component from '@glimmer/component'; -import { action } from '@ember/object'; -import { service } from '@ember/service'; import { tracked } from '@glimmer/tracking'; -import { task } from 'ember-concurrency'; import { consume } from 'ember-provide-consume-context'; -import { ForkingStore } from '@lblod/ember-submission-form-fields'; - -import { JSON_API_TYPE, SOURCE_GRAPH } from 'frontend-lmb/utils/constants'; -import { showErrorToast, showSuccessToast } from 'frontend-lmb/utils/toasts'; -import { PROV } from 'frontend-lmb/rdf/namespaces'; export default class RdfInputFieldsCustomFieldWrapperComponent extends Component { @consume('on-form-update') onFormUpdate; @consume('form-definition') formDefinition; - @service toaster; - @service formReplacements; - @service semanticFormRepository; - - @tracked removing = false; - @tracked showEditFieldModal; - - // Field properties - @tracked name; - @tracked type; - @tracked order; + @tracked showModal; get title() { return this.args.field?.label; } - - get canSaveChanges() { - if (this.libraryEntree) { - return this.fieldHasChanged && this.name && this.order; - } - - return this.fieldHasChanged && this.name && this.type && this.order; - } - - get fieldHasChanged() { - const { label, order, displayType } = this.args.field; - - return ( - this.name != label || this.type != displayType || this.order != order - ); - } - - @action - async loadCurrentFieldInfo() { - const { label, order, displayType } = this.args.field; - this.name = label; - this.type = displayType; - this.order = order; - } - - @action - async onRemove() { - this.removing = true; - await this.removeField(); - this.onFormUpdate(); - this.removed = false; - } - - @action - closeEditFieldModal() { - this.showEditFieldModal = false; - } - - @action - updateField(event) { - const { name, value } = event.target; - this[name] = value; - } - - saveChanges = task(async () => { - await this.removeField(); - try { - const result = await fetch( - `/form-content/${this.formDefinition.id}/fields`, - { - method: 'POST', - headers: { - 'Content-Type': JSON_API_TYPE, - }, - body: JSON.stringify({ - displayType: this.type, - libraryEntryUri: this.libraryEntree, - order: this.order, - name: this.name, - }), - } - ); - - const body = await result.json(); - const newFormId = body.id; - this.formReplacements.setReplacement(this.formDefinition.id, newFormId); - this.onFormUpdate(); - } catch (error) { - showErrorToast( - this.toaster, - 'Er ging iets mis bij het opslaan van het veld.' - ); - } - this.showEditFieldModal = false; - showSuccessToast(this.toaster, 'Het veld werd succesvol aangepast.'); - }); - - async removeField() { - await fetch(`/form-content/fields`, { - method: 'DELETE', - headers: { - 'Content-Type': JSON_API_TYPE, - }, - body: JSON.stringify({ - fieldUri: this.args.field.uri.value, - formUri: this.args.form.uri, - }), - }); - } - - get libraryEntree() { - const localStore = new ForkingStore(); - localStore.parse(this.formDefinition.formTtl, SOURCE_GRAPH, 'text/turtle'); - const libraryEntree = localStore.any( - this.args.field.uri, - PROV('wasDerivedFrom'), - null, - SOURCE_GRAPH - ); - - return libraryEntree?.value; - } } From 3f1b67162c2b544c1b211a4ee790b19b33d04ce7 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 15:48:06 +0100 Subject: [PATCH 19/21] lmb-182: move the generate custom field component logic to editable field --- app/components/editable-form.hbs | 18 ++- app/components/editable-form.js | 5 + .../generate-custom-field-button.hbs | 18 --- .../generate-custom-field-button.js | 136 ------------------ .../generate-custom-field-button-test.js | 27 ---- 5 files changed, 21 insertions(+), 183 deletions(-) delete mode 100644 app/components/generate-custom-field-button.hbs delete mode 100644 app/components/generate-custom-field-button.js delete mode 100644 tests/integration/components/generate-custom-field-button-test.js diff --git a/app/components/editable-form.hbs b/app/components/editable-form.hbs index caa635db5..4a27f9909 100644 --- a/app/components/editable-form.hbs +++ b/app/components/editable-form.hbs @@ -8,9 +8,23 @@ @customHistoryMessage={{@customHistoryMessage}} > {{#if this.editableFormsEnabled}} - + Voeg een veld toe + + + {{yield}} + + {{/if}} {{yield}} diff --git a/app/components/editable-form.js b/app/components/editable-form.js index 4e4b2d679..d1e014c19 100644 --- a/app/components/editable-form.js +++ b/app/components/editable-form.js @@ -1,7 +1,9 @@ import Component from '@glimmer/component'; + import { action } from '@ember/object'; import { tracked } from '@glimmer/tracking'; import { service } from '@ember/service'; + import { provide } from 'ember-provide-consume-context'; export default class EditableFormComponent extends Component { @@ -12,6 +14,8 @@ export default class EditableFormComponent extends Component { @service semanticFormRepository; @service features; + @tracked showModal = false; + constructor() { super(...arguments); this.baseFormId = this.args.form.id; @@ -27,6 +31,7 @@ export default class EditableFormComponent extends Component { ); this.currentForm = form; this.loading = false; + this.showModal = false; } get editableFormsEnabled() { diff --git a/app/components/generate-custom-field-button.hbs b/app/components/generate-custom-field-button.hbs deleted file mode 100644 index d8359812d..000000000 --- a/app/components/generate-custom-field-button.hbs +++ /dev/null @@ -1,18 +0,0 @@ - - Voeg een veld toe - - -{{yield}} - - \ No newline at end of file diff --git a/app/components/generate-custom-field-button.js b/app/components/generate-custom-field-button.js deleted file mode 100644 index 8bee9d2db..000000000 --- a/app/components/generate-custom-field-button.js +++ /dev/null @@ -1,136 +0,0 @@ -import Component from '@glimmer/component'; -import { action } from '@ember/object'; -import { service } from '@ember/service'; -import { tracked } from '@glimmer/tracking'; -import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; -import { showErrorToast } from 'frontend-lmb/utils/toasts'; - -import { TEXT_CUSTOM_DISPLAY_TYPE_ID } from 'frontend-lmb/utils/well-known-ids'; -import { ForkingStore } from '@lblod/ember-submission-form-fields'; -import { SOURCE_GRAPH } from 'frontend-lmb/utils/constants'; -import { PROV } from 'frontend-lmb/rdf/namespaces'; -export default class GenerateCustomFieldButtonComponent extends Component { - @service formReplacements; - @service store; - @service toaster; - - @tracked showModal = false; - @tracked loading = false; - @tracked fieldName = ''; - customFieldEntry = this.store.createRecord('library-entry', { - name: 'Eigen veld', - }); - @tracked selectedLibraryFieldType = this.customFieldEntry; - @tracked selectedDisplayType = null; - - constructor() { - super(...arguments); - this.displayTypes.then((displayTypes) => { - this.selectedDisplayType = displayTypes.findBy( - 'id', - TEXT_CUSTOM_DISPLAY_TYPE_ID - ); - }); - } - - get invalidName() { - return !this.fieldName || this.fieldName.trim().length < 1; - } - - get disabled() { - return this.invalidName; - } - - get libraryFieldOptions() { - const forkingStore = new ForkingStore(); - forkingStore.parse(this.args.form.formTtl, SOURCE_GRAPH, 'text/turtle'); - - const alreadyUsedLibraryEntries = forkingStore - .match(null, PROV('wasDerivedFrom'), null, SOURCE_GRAPH) - .map((triple) => triple.object.value); - - return this.store - .findAll('library-entry', { include: 'display-type' }) - .then((entries) => { - return [ - this.customFieldEntry, - ...entries - .sortBy('id') - .reverse() - .filter((entry) => { - return ( - entry.uri && alreadyUsedLibraryEntries.indexOf(entry.uri) < 0 - ); - }), - ]; - }); - } - - get displayTypes() { - return this.store.findAll('display-type').then((entries) => { - return entries.sortBy('label'); - }); - } - - @action - async onAddField() { - this.showModal = true; - this.fieldName = ''; - } - - @action - closeModal() { - this.showModal = false; - } - - @action - selectLibraryFieldType(libraryEntry) { - this.selectedLibraryFieldType = libraryEntry; - this.displayTypes.then((types) => { - this.selectedDisplayType = - types.findBy('uri', libraryEntry.get('displayType.uri')) || - types.findBy('id', TEXT_CUSTOM_DISPLAY_TYPE_ID); - }); - } - - @action - selectDisplayType(displayType) { - this.selectedDisplayType = displayType; - } - - @action async onSaveField() { - this.loading = true; - try { - const result = await fetch(`/form-content/${this.args.form.id}/fields`, { - method: 'POST', - headers: { - 'Content-Type': JSON_API_TYPE, - }, - body: JSON.stringify({ - displayType: this.selectedDisplayType.uri, - libraryEntryUri: this.selectedLibraryFieldType.uri, - order: 9000, - name: this.fieldName, - }), - }); - - const body = await result.json(); - const newFormId = body.id; - this.formReplacements.setReplacement(this.args.form.id, newFormId); - if (this.args.onUpdate) { - this.args.onUpdate(); - } - } catch (error) { - showErrorToast( - this.toaster, - 'Er ging iets mis bij het opslaan van het veld.' - ); - } - this.loading = false; - this.showModal = false; - } - - @action updateName(event) { - this.fieldName = event.target.value; - } -} diff --git a/tests/integration/components/generate-custom-field-button-test.js b/tests/integration/components/generate-custom-field-button-test.js deleted file mode 100644 index 01be993b7..000000000 --- a/tests/integration/components/generate-custom-field-button-test.js +++ /dev/null @@ -1,27 +0,0 @@ -import { module, test } from 'qunit'; -import { setupRenderingTest } from 'frontend-lmb/tests/helpers'; -import { render } from '@ember/test-helpers'; -import { hbs } from 'ember-cli-htmlbars'; - -module( - 'Integration | Component | generate-custom-field-button', - function (hooks) { - setupRenderingTest(hooks); - - test('it renders', async function (assert) { - // Set any properties with this.set('myProperty', 'value'); - // Handle any actions with this.set('myAction', function(val) { ... }); - - await render(hbs``); - - assert.dom(this.element).hasText(''); - - // Template block usage: - await render(hbs` - template block text -`); - - assert.dom(this.element).hasText('template block text'); - }); - } -); From de616df70e00b7df65de0ce41d6738905c694377 Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 15:58:15 +0100 Subject: [PATCH 20/21] lmb-182: always show the annuleer button --- .../crud-custom-field-modal.hbs | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.hbs b/app/components/rdf-input-fields/crud-custom-field-modal.hbs index 02576d900..86c8134e2 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.hbs +++ b/app/components/rdf-input-fields/crud-custom-field-modal.hbs @@ -63,25 +63,26 @@ <:footer> - - - + + - {{this.saveText}} - - - {{#if @isCreating}} + + {{this.saveText}} + + Annuleer - {{else}} + + {{#unless @isCreating}} Verwijder - {{/if}} - + {{/unless}} +
\ No newline at end of file From bfd4803a61aad3182319a3c0f634b8597524757b Mon Sep 17 00:00:00 2001 From: Jonas Van Hoof Date: Fri, 10 Jan 2025 16:55:53 +0100 Subject: [PATCH 21/21] lmb-182: add changing the order to the editable form --- .../crud-custom-field-modal.js | 10 ++- .../rdf-input-fields/custom-field-wrapper.hbs | 63 +++++++++++++------ .../rdf-input-fields/custom-field-wrapper.js | 24 +++++++ 3 files changed, 75 insertions(+), 22 deletions(-) diff --git a/app/components/rdf-input-fields/crud-custom-field-modal.js b/app/components/rdf-input-fields/crud-custom-field-modal.js index 4a6d3b35d..7e8dd35b7 100644 --- a/app/components/rdf-input-fields/crud-custom-field-modal.js +++ b/app/components/rdf-input-fields/crud-custom-field-modal.js @@ -31,6 +31,7 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen @tracked fieldName; @tracked libraryFieldType = this.customFieldEntry; @tracked displayType; + @tracked order; constructor() { super(...arguments); @@ -38,12 +39,16 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen let byProperty = 'id'; let withValue = TEXT_CUSTOM_DISPLAY_TYPE_ID; if (!this.args.isCreating) { - const { label, displayType } = this.args.field; + const { label, displayType, order } = this.args.field; + console.log(`${label}: order = ${order}`); + this.fieldName = label; + this.order = order; byProperty = 'uri'; withValue = displayType; } + this.order = 9000; // This is the default order for the field this.displayTypes.then((displayTypes) => { this.displayType = displayTypes.findBy(byProperty, withValue); }); @@ -59,6 +64,7 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen if (!this.args.isCreating) { await this.removeField(); } + console.log(`${this.fieldName}: order = ${this.order}`); try { const result = await fetch( `/form-content/${this.formDefinition.id}/fields`, @@ -70,7 +76,7 @@ export default class RdfInputFieldCrudCustomFieldModalComponent extends Componen body: JSON.stringify({ displayType: this.displayType.uri, libraryEntryUri: this.libraryFieldType.uri, - order: 9000, + order: this.order, name: this.fieldName, }), } diff --git a/app/components/rdf-input-fields/custom-field-wrapper.hbs b/app/components/rdf-input-fields/custom-field-wrapper.hbs index d193bc345..009aa956c 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.hbs +++ b/app/components/rdf-input-fields/custom-field-wrapper.hbs @@ -1,27 +1,50 @@ {{#unless this.removed}} -
- {{this.title}} - - Pas aan - -
-
+
- {{yield}} +
+ {{this.title}} + + Pas aan + +
+
+
+ {{yield}} +
+
+
+
+ + Naar boven + + + Naar onder +
+ {{#each this.errors as |error|}} {{error.resultMessage}} {{/each}} diff --git a/app/components/rdf-input-fields/custom-field-wrapper.js b/app/components/rdf-input-fields/custom-field-wrapper.js index 48d8fe1f1..6e7879ee6 100644 --- a/app/components/rdf-input-fields/custom-field-wrapper.js +++ b/app/components/rdf-input-fields/custom-field-wrapper.js @@ -3,6 +3,9 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { consume } from 'ember-provide-consume-context'; +import { task } from 'ember-concurrency'; + +import { JSON_API_TYPE } from 'frontend-lmb/utils/constants'; export default class RdfInputFieldsCustomFieldWrapperComponent extends Component { @consume('on-form-update') onFormUpdate; @@ -13,4 +16,25 @@ export default class RdfInputFieldsCustomFieldWrapperComponent extends Component get title() { return this.args.field?.label; } + + moveField = task(async (direction) => { + const result = await fetch( + `/form-content/${this.formDefinition.id}/fields/move`, + { + method: 'POST', + headers: { + 'Content-Type': JSON_API_TYPE, + }, + body: JSON.stringify({ + fieldUri: this.args.field.uri.value, + formUri: this.args.form.uri, + direction, + }), + } + ); + + if (result.ok) { + this.onFormUpdate(); + } + }); }