@projectcaluma/ember-form-builder 9.0.5 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/addon/components/cfb-float-input.hbs +14 -0
  3. package/addon/components/cfb-float-input.js +10 -4
  4. package/addon/components/cfb-form-editor/general.hbs +90 -86
  5. package/addon/components/cfb-form-editor/general.js +43 -45
  6. package/addon/components/cfb-form-editor/question/default.hbs +11 -9
  7. package/addon/components/cfb-form-editor/question/default.js +19 -29
  8. package/addon/components/cfb-form-editor/question/options.hbs +80 -82
  9. package/addon/components/cfb-form-editor/question/options.js +116 -105
  10. package/addon/components/cfb-form-editor/question/validation.hbs +14 -12
  11. package/addon/components/cfb-form-editor/question/validation.js +22 -31
  12. package/addon/components/cfb-form-editor/question-list/item.js +2 -4
  13. package/addon/components/cfb-form-editor/question.hbs +455 -380
  14. package/addon/components/cfb-form-editor/question.js +162 -138
  15. package/addon/components/cfb-form-list.hbs +1 -1
  16. package/addon/components/cfb-jexl-boolean-toggle-switch.hbs +12 -10
  17. package/addon/components/cfb-jexl-boolean-toggle-switch.js +11 -10
  18. package/addon/components/cfb-label.hbs +12 -4
  19. package/addon/components/cfb-toggle-switch.hbs +14 -12
  20. package/addon/gql/mutations/add-form-question.graphql +2 -2
  21. package/addon/gql/mutations/remove-form-question.graphql +2 -2
  22. package/addon/gql/mutations/reorder-form-questions.graphql +2 -2
  23. package/addon/gql/mutations/save-action-button-question.graphql +15 -0
  24. package/addon/gql/mutations/save-calculated-float-question.graphql +1 -1
  25. package/addon/gql/mutations/save-choice-question.graphql +1 -1
  26. package/addon/gql/mutations/save-date-question.graphql +1 -1
  27. package/addon/gql/mutations/save-default-date-answer.graphql +2 -6
  28. package/addon/gql/mutations/save-default-float-answer.graphql +2 -6
  29. package/addon/gql/mutations/save-default-integer-answer.graphql +2 -6
  30. package/addon/gql/mutations/save-default-list-answer.graphql +2 -6
  31. package/addon/gql/mutations/save-default-string-answer.graphql +2 -6
  32. package/addon/gql/mutations/save-default-table-answer.graphql +2 -6
  33. package/addon/gql/mutations/save-dynamic-choice-question.graphql +1 -1
  34. package/addon/gql/mutations/save-dynamic-multiple-choice-question.graphql +1 -1
  35. package/addon/gql/mutations/save-file-question.graphql +1 -1
  36. package/addon/gql/mutations/save-float-question.graphql +1 -1
  37. package/addon/gql/mutations/save-form-question.graphql +1 -1
  38. package/addon/gql/mutations/save-form.graphql +1 -1
  39. package/addon/gql/mutations/save-integer-question.graphql +1 -1
  40. package/addon/gql/mutations/save-multiple-choice-question.graphql +1 -1
  41. package/addon/gql/mutations/save-static-question.graphql +1 -1
  42. package/addon/gql/mutations/save-table-question.graphql +1 -1
  43. package/addon/gql/mutations/save-text-question.graphql +1 -1
  44. package/addon/gql/mutations/save-textarea-question.graphql +1 -1
  45. package/addon/gql/queries/form-editor-general.graphql +1 -1
  46. package/addon/gql/queries/form-editor-question.graphql +7 -3
  47. package/addon/gql/queries/form-list.graphql +1 -1
  48. package/addon/gql/queries/search-form-question.graphql +1 -1
  49. package/addon/gql/queries/search-question.graphql +1 -1
  50. package/addon/routes/edit/questions/edit.js +1 -1
  51. package/addon/routes/edit.js +1 -1
  52. package/package.json +21 -21
  53. package/translations/de.yaml +18 -4
  54. package/translations/en.yaml +18 -4
  55. package/addon/components/cfb-float-input/input.js +0 -12
  56. package/addon/components/cfb-label.js +0 -5
  57. package/addon/gql/fragments/field-answer.graphql +0 -57
  58. package/addon/gql/fragments/field-question.graphql +0 -159
  59. package/addon/gql/mutations/archive-form.graphql +0 -5
  60. package/addon/gql/mutations/remove-document.graphql +0 -5
  61. package/addon/gql/queries/all-format-validators.graphql +0 -12
  62. package/addon/gql/queries/all-work-items.graphql +0 -9
  63. package/addon/gql/queries/data-source.graphql +0 -10
  64. package/addon/gql/queries/get-document-answers.graphql +0 -21
  65. package/addon/gql/queries/get-document-forms.graphql +0 -20
  66. package/addon/gql/queries/get-document-used-dynamic-options.graphql +0 -12
  67. package/addon/gql/queries/get-dynamic-options.graphql +0 -29
  68. package/addon/gql/queries/get-fileanswer-info.graphql +0 -13
  69. package/app/components/cfb-float-input/input.js +0 -1
@@ -1,91 +1,89 @@
1
- {{component labelComponent}}
1
+ <div class="uk-margin">
2
+ {{component @labelComponent}}
2
3
 
3
- <UkSortable
4
- @handle=".uk-sortable-handle"
5
- @on-moved={{action "_handleMoved"}}
6
- @tagName="ul"
7
- class="uk-list uk-list-divider uk-margin-remove-bottom uk-margin-small-top"
8
- >
9
- {{#each this.optionRows as |row i|}}
10
- <li data-test-row={{concat "option-" (add i 1)}}>
11
- <ValidatedForm @model={{row}} as |f|>
12
- <div
13
- uk-grid
14
- class="uk-grid-small uk-flex uk-flex-middle"
15
- id={{row.slug}}
16
- >
17
- {{#if (not (and row.isNew (gt this.optionRows.length 1)))}}
18
- <span
19
- data-test-sort-handle
20
- uk-icon="menu"
21
- class="uk-sortable-handle"
22
- role="button"
23
- ></span>
24
- {{/if}}
25
- <div class="uk-width-auto">
26
- {{#if (and row.isNew (gt this.optionRows.length 1))}}
4
+ <UkSortable
5
+ @handle=".uk-sortable-handle"
6
+ @on-moved={{this._handleMoved}}
7
+ @tagName="ul"
8
+ class="uk-list uk-list-divider uk-margin-remove-bottom uk-margin-small-top"
9
+ >
10
+ {{#each this.optionRows as |row i|}}
11
+ <li data-test-row={{concat "option-" (add i 1)}}>
12
+ <ValidatedForm @model={{row}} as |f|>
13
+ <div
14
+ uk-grid
15
+ class="uk-grid-small uk-flex uk-flex-middle"
16
+ id={{row.slug}}
17
+ >
18
+ {{#if (not (and row.isNew (gt this.optionRows.length 1)))}}
19
+ <span
20
+ data-test-sort-handle
21
+ uk-icon="menu"
22
+ class="uk-sortable-handle"
23
+ role="button"
24
+ ></span>
25
+ {{/if}}
26
+ <div class="uk-width-auto">
27
+ {{#if (and row.isNew (gt this.optionRows.length 1))}}
28
+ <button
29
+ data-test-delete-row
30
+ type="button"
31
+ class="uk-icon-button"
32
+ uk-icon="trash"
33
+ title={{t "caluma.form-builder.options.delete"}}
34
+ {{on "click" (fn this.deleteRow row)}}
35
+ >
36
+ </button>
37
+ {{/if}}
27
38
  <button
28
- data-test-delete-row
39
+ data-test-archive-row
29
40
  type="button"
30
41
  class="uk-icon-button"
31
- uk-icon="trash"
32
- title={{t "caluma.form-builder.options.delete"}}
33
- {{action "deleteRow" row}}
42
+ uk-icon={{if row.isArchived "plus" "close"}}
43
+ title={{t
44
+ (concat
45
+ "caluma.form-builder.options."
46
+ (if row.isArchived "restore" "archive")
47
+ )
48
+ }}
49
+ {{on "click" (fn this.toggleRowArchived row)}}
34
50
  >
35
51
  </button>
36
- {{/if}}
37
- <button
38
- data-test-archive-row
39
- type="button"
40
- class="uk-icon-button"
41
- uk-icon={{if row.isArchived "plus" "close"}}
42
- title={{t
43
- (concat
44
- "caluma.form-builder.options."
45
- (if row.isArchived "restore" "archive")
46
- )
47
- }}
48
- {{action "toggleRowArchived" row}}
49
- >
50
- </button>
51
- </div>
52
- <div class="uk-width-expand">
53
- <f.input
54
- @name="label"
55
- @inputName={{concat "option-" (add i 1) "-label"}}
56
- @required={{true}}
57
- @disabled={{row.isArchived}}
58
- @on-update={{action
59
- (queue (action "updateLabel") (action "update"))
60
- }}
61
- />
62
- </div>
63
- <div class="uk-width-1-4">
64
- <f.input
65
- @name="slug"
66
- @inputName={{concat "option-" (add i 1) "-slug"}}
67
- @required={{true}}
68
- @disabled={{not row.isNew}}
69
- @on-update={{action
70
- (queue (action "updateSlug") (action "update"))
71
- }}
72
- />
52
+ </div>
53
+ <div class="uk-width-expand">
54
+ <f.input
55
+ @name="label"
56
+ @inputName={{concat "option-" (add i 1) "-label"}}
57
+ @required={{true}}
58
+ @disabled={{row.isArchived}}
59
+ @on-update={{this.updateLabel}}
60
+ />
61
+ </div>
62
+ <div class="uk-width-1-4">
63
+ <f.input
64
+ @name="slug"
65
+ @inputName={{concat "option-" (add i 1) "-slug"}}
66
+ @required={{true}}
67
+ @disabled={{not row.isNew}}
68
+ @on-update={{this.updateSlug}}
69
+ />
70
+ </div>
73
71
  </div>
74
- </div>
75
- </ValidatedForm>
72
+ </ValidatedForm>
73
+ </li>
74
+ {{/each}}
75
+ <li class="uk-text-center">
76
+ <button
77
+ data-test-add-row
78
+ type="button"
79
+ class="uk-icon-button"
80
+ uk-icon="plus"
81
+ {{on "click" this.addRow}}
82
+ >
83
+ </button>
76
84
  </li>
77
- {{/each}}
78
- <li class="uk-text-center">
79
- <button
80
- data-test-add-row
81
- type="button"
82
- class="uk-icon-button"
83
- uk-icon="plus"
84
- {{action "addRow"}}
85
- >
86
- </button>
87
- </li>
88
- </UkSortable>
85
+ </UkSortable>
89
86
 
90
- {{component hintComponent}}
91
- {{component errorComponent}}
87
+ {{component @hintComponent}}
88
+ {{component @errorComponent}}
89
+ </div>
@@ -1,11 +1,11 @@
1
- import { get } from "@ember/object";
2
- import { reads } from "@ember/object/computed";
1
+ import { action } from "@ember/object";
3
2
  import { inject as service } from "@ember/service";
3
+ import Component from "@glimmer/component";
4
+ import { tracked } from "@glimmer/tracking";
4
5
  import { queryManager } from "ember-apollo-client";
5
- import Changeset from "ember-changeset";
6
+ import { Changeset } from "ember-changeset";
6
7
  import lookupValidator from "ember-changeset-validations";
7
8
  import { task } from "ember-concurrency";
8
- import RenderComponent from "ember-validated-form/components/validated-input/-themes/uikit/render";
9
9
 
10
10
  import slugify from "@projectcaluma/ember-core/utils/slugify";
11
11
  import saveChoiceQuestionMutation from "@projectcaluma/ember-form-builder/gql/mutations/save-choice-question.graphql";
@@ -25,46 +25,49 @@ const addQuestionPrefix = (slug, questionSlug) => {
25
25
  return `${questionSlug}-${slug}`;
26
26
  };
27
27
 
28
- export default RenderComponent.extend({
29
- intl: service(),
30
- notification: service(),
31
- apollo: queryManager(),
32
-
33
- questionSlug: reads("model.slug"),
34
-
35
- init(...args) {
36
- this._super(...args);
37
-
38
- const value = this.value;
39
-
40
- this.set(
41
- "optionRows",
42
- get(value, "edges.length")
43
- ? value.edges.map(
44
- (edge) =>
45
- new Changeset(
46
- {
47
- slug: removeQuestionPrefix(edge.node.slug, this.questionSlug),
48
- label: edge.node.label,
49
- isArchived: edge.node.isArchived,
50
- isNew: false,
51
- },
52
- lookupValidator(OptionValidations),
53
- OptionValidations
54
- )
55
- )
56
- : [
28
+ export default class CfbFormEditorQuestionOptions extends Component {
29
+ @tracked _optionRows;
30
+
31
+ @service intl;
32
+ @service notification;
33
+ @queryManager apollo;
34
+
35
+ constructor(...args) {
36
+ super(...args);
37
+
38
+ this._optionRows = this.args.value?.edges?.length
39
+ ? this.args.value.edges.map(
40
+ (edge) =>
57
41
  new Changeset(
58
- { slug: "", label: "", isNew: true, linkSlug: true },
42
+ {
43
+ slug: removeQuestionPrefix(edge.node.slug, this.questionSlug),
44
+ label: edge.node.label,
45
+ isArchived: edge.node.isArchived,
46
+ isNew: false,
47
+ },
59
48
  lookupValidator(OptionValidations),
60
49
  OptionValidations
61
- ),
62
- ]
63
- );
64
- },
50
+ )
51
+ )
52
+ : [
53
+ new Changeset(
54
+ { slug: "", label: "", isNew: true, linkSlug: true },
55
+ lookupValidator(OptionValidations),
56
+ OptionValidations
57
+ ),
58
+ ];
59
+ }
60
+
61
+ get questionSlug() {
62
+ return this.args.model.slug;
63
+ }
64
+
65
+ get optionRows() {
66
+ return this._optionRows;
67
+ }
65
68
 
66
69
  _update() {
67
- this.update({
70
+ this.args.update({
68
71
  edges: this.optionRows
69
72
  .filter((row) => !row.isNew || row.isDirty)
70
73
  .map((row) => {
@@ -87,17 +90,18 @@ export default RenderComponent.extend({
87
90
  }),
88
91
  });
89
92
 
90
- this.setDirty();
91
- },
93
+ this.args.setDirty();
94
+ }
92
95
 
93
- reorderOptions: task(function* (slugs) {
96
+ @task
97
+ *reorderOptions(slugs) {
94
98
  try {
95
99
  yield this.apollo.mutate({
96
- mutation: TYPES[this.model.__typename],
100
+ mutation: TYPES[this.args.model.__typename],
97
101
  variables: {
98
102
  input: {
99
103
  slug: this.questionSlug,
100
- label: this.model.label,
104
+ label: this.args.model.label,
101
105
  options: slugs,
102
106
  },
103
107
  },
@@ -115,66 +119,73 @@ export default RenderComponent.extend({
115
119
  )
116
120
  );
117
121
  }
118
- }),
119
-
120
- actions: {
121
- addRow() {
122
- this.set("optionRows", [
123
- ...this.optionRows,
124
- new Changeset(
125
- { slug: "", label: "", isNew: true, linkSlug: true },
126
- lookupValidator(OptionValidations),
127
- OptionValidations
128
- ),
129
- ]);
130
-
131
- this._update();
132
- },
133
-
134
- deleteRow(row) {
135
- this.set(
136
- "optionRows",
137
- this.optionRows.filter((r) => r !== row)
122
+ }
123
+
124
+ @action
125
+ addRow() {
126
+ this._optionRows = [
127
+ ...this.optionRows,
128
+ new Changeset(
129
+ { slug: "", label: "", isNew: true, linkSlug: true },
130
+ lookupValidator(OptionValidations),
131
+ OptionValidations
132
+ ),
133
+ ];
134
+
135
+ this._update();
136
+ }
137
+
138
+ @action
139
+ deleteRow(row) {
140
+ this._optionRows = this.optionRows.filter((r) => r !== row);
141
+
142
+ this._update();
143
+ }
144
+
145
+ @action
146
+ toggleRowArchived(row) {
147
+ row.set("isArchived", !row.get("isArchived"));
148
+
149
+ this._update();
150
+ }
151
+
152
+ @action
153
+ updateLabel(value, changeset) {
154
+ changeset.set("label", value);
155
+
156
+ if (changeset.get("isNew") && changeset.get("linkSlug")) {
157
+ changeset.set(
158
+ "slug",
159
+ slugify(value, { locale: this.intl.primaryLocale })
138
160
  );
139
-
140
- this._update();
141
- },
142
-
143
- toggleRowArchived(row) {
144
- row.set("isArchived", !row.get("isArchived"));
145
-
146
- this._update();
147
- },
148
-
149
- updateLabel(value, changeset) {
150
- changeset.set("label", value);
151
-
152
- if (changeset.get("isNew") && changeset.get("linkSlug")) {
153
- changeset.set(
154
- "slug",
155
- slugify(value, { locale: this.intl.primaryLocale })
156
- );
157
- }
158
- },
159
-
160
- updateSlug(value, changeset) {
161
- changeset.set("slug", value);
162
- changeset.set("linkSlug", false);
163
- },
164
-
165
- update() {
166
- this._update();
167
- },
168
-
169
- _handleMoved({ detail: [sortable] }) {
170
- // Remove last element as it is the add row button
171
- const options = [...sortable.$el.children].slice(0, -1);
172
-
173
- this.reorderOptions.perform(
174
- options.map((option) =>
175
- addQuestionPrefix(option.firstElementChild.id, this.questionSlug)
161
+ }
162
+ this._update();
163
+ }
164
+
165
+ @action
166
+ updateSlug(value, changeset) {
167
+ changeset.set("slug", value);
168
+ changeset.set("linkSlug", false);
169
+ this._update();
170
+ }
171
+
172
+ @action
173
+ update() {
174
+ this._update();
175
+ }
176
+
177
+ @action
178
+ _handleMoved({ detail: [sortable] }) {
179
+ // Remove last element as it is the add row button
180
+ const options = [...sortable.$el.children].slice(0, -1);
181
+
182
+ this.reorderOptions.perform(
183
+ options.map((option) =>
184
+ addQuestionPrefix(
185
+ option.firstElementChild.firstElementChild.id,
186
+ this.questionSlug
176
187
  )
177
- );
178
- },
179
- },
180
- });
188
+ )
189
+ );
190
+ }
191
+ }
@@ -1,14 +1,16 @@
1
- {{component labelComponent}}
1
+ <div class="uk-margin" {{did-insert (perform this.availableFormatValidators)}}>
2
+ {{component @labelComponent}}
2
3
 
3
- <PowerSelectMultiple
4
- @selected={{selected}}
5
- @placeholder={{placeholder}}
6
- @options={{validators}}
7
- @onChange={{action "updateValidators"}}
8
- as |item|
9
- >
10
- {{item.name}}
11
- </PowerSelectMultiple>
4
+ <PowerSelectMultiple
5
+ @selected={{this.selected}}
6
+ @placeholder={{this.placeholder}}
7
+ @options={{this.validators}}
8
+ @onChange={{this.updateValidators}}
9
+ as |item|
10
+ >
11
+ {{item.name}}
12
+ </PowerSelectMultiple>
12
13
 
13
- {{component hintComponent}}
14
- {{component errorComponent}}
14
+ {{component @hintComponent}}
15
+ {{component @errorComponent}}
16
+ </div>
@@ -1,44 +1,35 @@
1
- import Component from "@ember/component";
2
- import { computed } from "@ember/object";
1
+ import { action } from "@ember/object";
2
+ import Component from "@glimmer/component";
3
3
  import { queryManager } from "ember-apollo-client";
4
- import { task } from "ember-concurrency";
4
+ import { dropTask } from "ember-concurrency";
5
5
 
6
- import allFormatValidatorsQuery from "@projectcaluma/ember-form-builder/gql/queries/all-format-validators.graphql";
6
+ import allFormatValidatorsQuery from "@projectcaluma/ember-core/gql/queries/all-format-validators.graphql";
7
7
 
8
- export default Component.extend({
9
- apollo: queryManager(),
8
+ export default class CfbFormEditorQuestionValidation extends Component {
9
+ @queryManager apollo;
10
10
 
11
- init(...args) {
12
- this._super(...args);
13
-
14
- this.availableFormatValidators.perform();
15
- },
16
-
17
- availableFormatValidators: task(function* () {
11
+ @dropTask
12
+ *availableFormatValidators() {
18
13
  const formatValidators = yield this.apollo.watchQuery(
19
14
  { query: allFormatValidatorsQuery, fetchPolicy: "cache-and-network" },
20
15
  "allFormatValidators.edges"
21
16
  );
22
17
  return formatValidators.map((edge) => edge.node);
23
- }).drop(),
18
+ }
24
19
 
25
- validators: computed(
26
- "availableFormatValidators.lastSuccessful.value.[]",
27
- function () {
28
- return this.get("availableFormatValidators.lastSuccessful.value") || [];
29
- }
30
- ),
20
+ get validators() {
21
+ return this.availableFormatValidators?.lastSuccessful?.value || [];
22
+ }
31
23
 
32
- selected: computed("value.[]", "validators.@each.slug", function () {
24
+ get selected() {
33
25
  return this.validators.filter((validator) =>
34
- (this.value || []).includes(validator.slug)
26
+ (this.args.value || []).includes(validator.slug)
35
27
  );
36
- }),
37
-
38
- actions: {
39
- updateValidators(value) {
40
- this.update(value.map((validator) => validator.slug));
41
- this.setDirty();
42
- },
43
- },
44
- });
28
+ }
29
+
30
+ @action
31
+ updateValidators(value) {
32
+ this.args.update(value.map((validator) => validator.slug));
33
+ this.args.setDirty();
34
+ }
35
+ }
@@ -6,10 +6,8 @@ import jexl from "jexl";
6
6
  import { hasQuestionType } from "@projectcaluma/ember-core/helpers/has-question-type";
7
7
 
8
8
  export default class CfbFormEditorQuestionListItem extends Component {
9
- constructor(...args) {
10
- super(...args);
11
-
12
- this.elementId = guidFor(this);
9
+ get elementId() {
10
+ return guidFor(this);
13
11
  }
14
12
 
15
13
  get required() {