@projectcaluma/ember-form-builder 12.8.0 → 12.10.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.
@@ -0,0 +1,16 @@
1
+ <UkButton
2
+ @color="link"
3
+ @onClick={{toggle-action "showAdvanced" this}}
4
+ class="uk-flex uk-flex-middle uk-margin"
5
+ >
6
+ {{#if this.showAdvanced}}
7
+ <UkIcon @icon="triangle-down" />
8
+ {{else}}
9
+ <UkIcon @icon="triangle-right" />
10
+ {{/if}}
11
+ {{t "caluma.form-builder.question.advancedSettings"}}
12
+ </UkButton>
13
+
14
+ {{#if this.showAdvanced}}
15
+ {{yield}}
16
+ {{/if}}
@@ -0,0 +1,6 @@
1
+ import Component from "@glimmer/component";
2
+ import { tracked } from "@glimmer/tracking";
3
+
4
+ export default class CfbFormEditorCfbAdvancedSettings extends Component {
5
+ @tracked showAdvanced = false;
6
+ }
@@ -0,0 +1,50 @@
1
+ <UkModal
2
+ @visible={{this.visible}}
3
+ @onHide={{fn (mut this.visible) false}}
4
+ data-test-copy-form-modal
5
+ as |modal|
6
+ >
7
+ {{#if this.visible}}
8
+ <ValidatedForm
9
+ @model={{this.changeset}}
10
+ @on-submit={{perform this.submit}}
11
+ as |f|
12
+ >
13
+ <modal.header>
14
+ <h2 class="uk-modal-title">
15
+ {{t "caluma.form-builder.copy-modal.title" form=@item.name}}
16
+ </h2>
17
+ </modal.header>
18
+ <modal.body>
19
+ <f.input
20
+ @name="name"
21
+ @label={{t "caluma.form-builder.copy-modal.name.label"}}
22
+ @hint={{t "caluma.form-builder.copy-modal.name.hint" name=@item.name}}
23
+ data-test-copy-modal-input-name
24
+ />
25
+ <f.input
26
+ @name="slug"
27
+ @label={{t "caluma.form-builder.copy-modal.slug.label"}}
28
+ @hint={{t "caluma.form-builder.copy-modal.slug.hint" slug=@item.slug}}
29
+ @renderComponent={{component "cfb-slug-input" hidePrefix=false}}
30
+ data-test-copy-modal-input-slug
31
+ />
32
+ </modal.body>
33
+ <modal.footer class="uk-text-right">
34
+ <f.submit
35
+ @loading={{this.submit.isRunning}}
36
+ @disabled={{or
37
+ this.submit.isRunning
38
+ (not this.changeset.isValid)
39
+ (eq @item.slug this.changeset.slug)
40
+ }}
41
+ data-test-copy-form-submit
42
+ >
43
+ {{t "caluma.form-builder.copy-modal.submit"}}
44
+ </f.submit>
45
+ </modal.footer>
46
+ </ValidatedForm>
47
+ {{/if}}
48
+ </UkModal>
49
+
50
+ {{yield (hash toggle=this.toggle)}}
@@ -0,0 +1,63 @@
1
+ import { action } from "@ember/object";
2
+ import { inject as service } from "@ember/service";
3
+ import Component from "@glimmer/component";
4
+ import { tracked } from "@glimmer/tracking";
5
+ import { queryManager } from "ember-apollo-client";
6
+ import { Changeset } from "ember-changeset";
7
+ import lookupValidator from "ember-changeset-validations";
8
+ import { dropTask } from "ember-concurrency";
9
+
10
+ import copyFormMutation from "@projectcaluma/ember-form-builder/gql/mutations/copy-form.graphql";
11
+ import validations from "@projectcaluma/ember-form-builder/validations/form";
12
+
13
+ export default class CfbFormEditorCopyModal extends Component {
14
+ @queryManager apollo;
15
+ @service notification;
16
+ @service router;
17
+ @service intl;
18
+ @tracked visible = false;
19
+
20
+ constructor(owner, args) {
21
+ super(owner, args);
22
+
23
+ this.changeset = Changeset(
24
+ { ...this.args.item, id: undefined },
25
+ lookupValidator(validations),
26
+ validations,
27
+ );
28
+ }
29
+
30
+ @action
31
+ toggle() {
32
+ this.visible = !this.visible;
33
+ }
34
+
35
+ @dropTask
36
+ *submit(changeset) {
37
+ try {
38
+ yield this.apollo.mutate(
39
+ {
40
+ mutation: copyFormMutation,
41
+ variables: {
42
+ input: {
43
+ source: this.args.item.slug,
44
+ name: changeset.name,
45
+ slug: changeset.slug,
46
+ },
47
+ },
48
+ },
49
+ "copyForm.form",
50
+ );
51
+
52
+ this.notification.success(
53
+ this.intl.t("caluma.form-builder.notification.form.create.success"),
54
+ );
55
+
56
+ this.router.transitionTo("edit", changeset.slug);
57
+ } catch (e) {
58
+ this.notification.danger(
59
+ this.intl.t("caluma.form-builder.notification.form.create.error"),
60
+ );
61
+ }
62
+ }
63
+ }
@@ -49,7 +49,24 @@
49
49
  @renderComponent={{component "cfb-toggle-switch" size="small"}}
50
50
  />
51
51
 
52
+ <CfbFormEditor::CfbAdvancedSettings>
53
+ <f.input
54
+ @label={{t "caluma.form-builder.question.meta"}}
55
+ @name="meta"
56
+ @renderComponent={{component "cfb-code-editor" language="json"}}
57
+ />
58
+ </CfbFormEditor::CfbAdvancedSettings>
59
+
52
60
  <div class="uk-text-right">
61
+ <CfbFormEditor::CopyModal @item={{this.data}} as |modal|>
62
+ <f.button
63
+ @disabled={{f.loading}}
64
+ @label={{t "caluma.form-builder.copy-modal.submit"}}
65
+ {{on "click" modal.toggle}}
66
+ data-test-copy-form-button={{@slug}}
67
+ />
68
+ </CfbFormEditor::CopyModal>
69
+
53
70
  <f.submit
54
71
  @disabled={{f.loading}}
55
72
  @label={{t "caluma.form-builder.global.save"}}
@@ -58,6 +58,8 @@ export default class CfbFormEditorGeneral extends Component {
58
58
 
59
59
  @dropTask
60
60
  *submit(changeset) {
61
+ const rawMeta = changeset.get("meta");
62
+
61
63
  try {
62
64
  const form = yield this.apollo.mutate(
63
65
  {
@@ -69,6 +71,7 @@ export default class CfbFormEditorGeneral extends Component {
69
71
  description: changeset.get("description"),
70
72
  isArchived: changeset.get("isArchived"),
71
73
  isPublished: changeset.get("isPublished"),
74
+ meta: JSON.stringify(rawMeta?.unwrap?.() ?? rawMeta),
72
75
  },
73
76
  },
74
77
  },
@@ -10,7 +10,7 @@
10
10
  type="button"
11
11
  class="uk-icon-button uk-animation-slide-top"
12
12
  uk-icon="close"
13
- title={{t "caluma.form-builder.global.ca ncel"}}
13
+ title={{t "caluma.form-builder.global.cancel"}}
14
14
  {{on "click" (fn this.setMode "reorder")}}
15
15
  >
16
16
  </button>
@@ -11,6 +11,7 @@ export default class CfbFormEditorQuestionUsage extends Component {
11
11
  @queryManager apollo;
12
12
 
13
13
  @tracked modalVisible = false;
14
+ @tracked _forms = null;
14
15
 
15
16
  get title() {
16
17
  return this.intl.t("caluma.form-builder.question.usage.title", {
@@ -25,18 +26,29 @@ export default class CfbFormEditorQuestionUsage extends Component {
25
26
  }
26
27
 
27
28
  forms = trackedFunction(this, async () => {
29
+ if (!this.args.slug) {
30
+ // The shown question hasn't completely loaded yet
31
+ return [];
32
+ }
33
+ if (this._forms) {
34
+ // we have already fetched the forms previously
35
+ return this._forms;
36
+ }
37
+
28
38
  try {
29
39
  const forms = await this.apollo.query(
30
40
  {
31
41
  query: allFormsForQuestionQuery,
32
42
  variables: {
33
- slug: this.args.model.slug,
43
+ slug: this.args.slug,
34
44
  },
35
45
  fetchPolicy: "no-cache",
36
46
  },
37
47
  "allForms.edges",
38
48
  );
39
49
 
50
+ this._forms = forms; // cache the result
51
+
40
52
  return forms;
41
53
  } catch (error) {
42
54
  console.error(error);
@@ -384,20 +384,7 @@
384
384
  @renderComponent={{component "cfb-toggle-switch" size="small"}}
385
385
  />
386
386
 
387
- <UkButton
388
- @color="link"
389
- @onClick={{toggle-action "showAdvanced" this}}
390
- class="uk-flex uk-flex-middle uk-margin"
391
- >
392
- {{#if this.showAdvanced}}
393
- <UkIcon @icon="triangle-down" />
394
- {{else}}
395
- <UkIcon @icon="triangle-right" />
396
- {{/if}}
397
- {{t "caluma.form-builder.question.advancedSettings"}}
398
- </UkButton>
399
-
400
- {{#if this.showAdvanced}}
387
+ <CfbFormEditor::CfbAdvancedSettings>
401
388
  {{#if (has-question-type f.model "action-button")}}
402
389
  <f.input
403
390
  @name="validateOnEnter"
@@ -438,10 +425,13 @@
438
425
  @name="meta"
439
426
  @renderComponent={{component "cfb-code-editor" language="json"}}
440
427
  />
441
- {{/if}}
428
+ </CfbFormEditor::CfbAdvancedSettings>
442
429
 
443
430
  <div class="uk-flex uk-flex-between uk-flex-middle uk-flex-row-reverse">
444
- <CfbFormEditor::QuestionUsage @model={{f.model}} class="uk-flex-last" />
431
+ <CfbFormEditor::QuestionUsage
432
+ @slug={{changeset-get f.model "slug"}}
433
+ class="uk-flex-last"
434
+ />
445
435
 
446
436
  <f.submit
447
437
  @disabled={{f.loading}}
@@ -14,6 +14,7 @@
14
14
  </span>
15
15
  {{/if}}
16
16
  <input
17
+ ...attributes
17
18
  id={{@inputId}}
18
19
  name={{or @inputName @name}}
19
20
  type="text"
@@ -1,4 +1,5 @@
1
1
  import { action } from "@ember/object";
2
+ import { scheduleOnce } from "@ember/runloop";
2
3
  import { inject as service } from "@ember/service";
3
4
  import { htmlSafe } from "@ember/template";
4
5
  import Component from "@glimmer/component";
@@ -30,6 +31,12 @@ export default class CfbSlugInputComponent extends Component {
30
31
 
31
32
  @action
32
33
  calculatePadding(element) {
34
+ // Ensures that the element is already visible in combined use
35
+ // with modal dialogs.
36
+ scheduleOnce("afterRender", this, "_calculatePadding", element);
37
+ }
38
+
39
+ _calculatePadding(element) {
33
40
  const prefixWidth = element.clientWidth;
34
41
  const prefixMargin = window.getComputedStyle(element).marginLeft;
35
42
 
@@ -5,4 +5,5 @@ fragment FormInfo on Form {
5
5
  description
6
6
  isArchived
7
7
  isPublished
8
+ meta
8
9
  }
@@ -0,0 +1,8 @@
1
+ mutation CopyForm($input: CopyFormInput!) {
2
+ copyForm(input: $input) {
3
+ form {
4
+ id
5
+ }
6
+ clientMutationId
7
+ }
8
+ }
@@ -0,0 +1 @@
1
+ export { default } from "@projectcaluma/ember-form-builder/components/cfb-form-editor/cfb-advanced-settings";
@@ -0,0 +1 @@
1
+ export { default } from "@projectcaluma/ember-form-builder/components/cfb-form-editor/copy-modal";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectcaluma/ember-form-builder",
3
- "version": "12.8.0",
3
+ "version": "12.10.0",
4
4
  "description": "Ember engine for building Caluma forms.",
5
5
  "keywords": [
6
6
  "ember-addon",
@@ -10,7 +10,7 @@
10
10
  "homepage": "https://docs.caluma.io/ember-caluma",
11
11
  "repository": "github:projectcaluma/ember-caluma",
12
12
  "dependencies": {
13
- "@babel/core": "^7.23.6",
13
+ "@babel/core": "^7.23.9",
14
14
  "@ember/legacy-built-in-components": "^0.5.0",
15
15
  "@ember/render-modifiers": "^2.1.0",
16
16
  "@ember/string": "^3.1.1",
@@ -19,7 +19,7 @@
19
19
  "@glimmer/tracking": "^1.1.2",
20
20
  "codejar": "^4.2.0",
21
21
  "ember-apollo-client": "~4.0.2",
22
- "ember-auto-import": "^2.7.1",
22
+ "ember-auto-import": "^2.7.2",
23
23
  "ember-changeset": "^4.1.2",
24
24
  "ember-changeset-validations": "^4.1.1",
25
25
  "ember-cli-babel": "^8.2.0",
@@ -28,7 +28,7 @@
28
28
  "ember-concurrency": "^3.1.1",
29
29
  "ember-engines-router-service": "^0.5.0",
30
30
  "ember-fetch": "^8.1.2",
31
- "ember-flatpickr": "^4.0.0",
31
+ "ember-flatpickr": "^6.0.0",
32
32
  "ember-intl": "^6.4.0",
33
33
  "ember-math-helpers": "^4.0.0",
34
34
  "ember-power-select": "^7.2.0",
@@ -36,6 +36,7 @@
36
36
  "ember-test-selectors": "^6.0.0",
37
37
  "ember-uikit": "^9.0.0",
38
38
  "ember-validated-form": "^7.0.0",
39
+ "flatpickr": "^4.6.13",
39
40
  "graphql": "^15.8.0",
40
41
  "graphql-tag": "^2.12.6",
41
42
  "highlight.js": "^11.9.0",
@@ -43,8 +44,8 @@
43
44
  "jexl": "^2.3.0",
44
45
  "lodash.isequal": "^4.5.0",
45
46
  "uikit": "^3.17.11",
46
- "@projectcaluma/ember-form": "^12.8.0",
47
- "@projectcaluma/ember-core": "^12.8.0"
47
+ "@projectcaluma/ember-core": "^12.10.0",
48
+ "@projectcaluma/ember-form": "^12.10.0"
48
49
  },
49
50
  "//": [
50
51
  "TODO: remove obsolete dependency to `ember-data` which is only necessary",
@@ -53,10 +54,10 @@
53
54
  "docs app) but not as direct dependency of the package."
54
55
  ],
55
56
  "devDependencies": {
56
- "@ember/optional-features": "2.0.0",
57
+ "@ember/optional-features": "2.1.0",
57
58
  "@ember/test-helpers": "3.2.1",
58
59
  "@embroider/test-setup": "3.0.3",
59
- "@faker-js/faker": "8.3.1",
60
+ "@faker-js/faker": "8.4.1",
60
61
  "broccoli-asset-rev": "3.0.0",
61
62
  "ember-autoresize-modifier": "0.7.0",
62
63
  "ember-cli": "5.5.0",
@@ -72,15 +73,15 @@
72
73
  "ember-load-initializers": "2.1.2",
73
74
  "ember-qunit": "8.0.2",
74
75
  "ember-resolver": "11.0.1",
75
- "ember-source": "5.5.0",
76
+ "ember-source": "5.6.0",
76
77
  "ember-source-channel-url": "3.0.0",
77
78
  "ember-try": "3.0.0",
78
79
  "loader.js": "4.7.0",
79
80
  "miragejs": "0.1.48",
80
81
  "qunit": "2.20.0",
81
82
  "qunit-dom": "3.0.0",
82
- "webpack": "5.89.0",
83
- "@projectcaluma/ember-testing": "12.8.0"
83
+ "webpack": "5.90.0",
84
+ "@projectcaluma/ember-testing": "12.10.0"
84
85
  },
85
86
  "peerDependencies": {
86
87
  "ember-engines": "^0.9.0",
@@ -129,6 +129,7 @@ caluma:
129
129
  widgetOverrides:
130
130
  powerselect: "Power Select"
131
131
  hidden: "Versteckt"
132
+ number-separator: "Zahlentrennzeichen"
132
133
 
133
134
  not-found: "Keine Frage mit dem Slug '{slug}' gefunden"
134
135
 
@@ -175,6 +176,16 @@ caluma:
175
176
  success: "Ihre Frage wurde erfolgreich gespeichert!"
176
177
  error: "Hoppla, beim Speichern der Frage ist etwas schief gelaufen..."
177
178
 
179
+ copy-modal:
180
+ title: '"{form}" kopieren'
181
+ name:
182
+ label: "Name"
183
+ hint: "Original: {name}"
184
+ slug:
185
+ label: "Slug"
186
+ hint: "Original: {slug}"
187
+ submit: "Kopieren"
188
+
178
189
  validations:
179
190
  form:
180
191
  slug: "Ein Formular mit diesem Slug existiert bereits"
@@ -129,6 +129,7 @@ caluma:
129
129
  widgetOverrides:
130
130
  powerselect: "Power Select"
131
131
  hidden: "Hidden"
132
+ number-separator: "Number separator"
132
133
 
133
134
  not-found: "No question with slug '{slug}' found"
134
135
 
@@ -175,6 +176,16 @@ caluma:
175
176
  success: "Your question was successfully saved!"
176
177
  error: "Ooops, something went wrong while saving the question..."
177
178
 
179
+ copy-modal:
180
+ title: 'Copy "{form}"'
181
+ name:
182
+ label: "Name"
183
+ hint: "Original: {name}"
184
+ slug:
185
+ label: "Slug"
186
+ hint: "Original: {slug}"
187
+ submit: "Copy"
188
+
178
189
  validations:
179
190
  form:
180
191
  slug: "A form with this slug already exists"
@@ -129,6 +129,7 @@ caluma:
129
129
  widgetOverrides:
130
130
  powerselect: "Power Select"
131
131
  hidden: "Caché"
132
+ number-separator: "Séparateur de chiffres"
132
133
 
133
134
  not-found: "Aucune question trouvée avec le slug '{slug}'"
134
135
 
@@ -175,6 +176,16 @@ caluma:
175
176
  success: "Votre question a été enregistrée avec succès !"
176
177
  error: "Oups, quelque chose s'est mal passé lors de l'enregistrement de la question..."
177
178
 
179
+ copy-modal:
180
+ title: 'Copier "{form}"'
181
+ name:
182
+ label: "Nom"
183
+ hint: "Original : {name}"
184
+ slug:
185
+ label: "Slug"
186
+ hint: "Original : {slug}"
187
+ submit: "Copier"
188
+
178
189
  validations:
179
190
  form:
180
191
  slug: "Un formulaire avec ce slug existe déjà"