@projectcaluma/ember-form 12.9.0 → 12.10.1

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.
@@ -4,7 +4,7 @@ import { inject as service } from "@ember/service";
4
4
  import Component from "@glimmer/component";
5
5
  import { queryManager } from "ember-apollo-client";
6
6
  import { dropTask } from "ember-concurrency";
7
- import { trackedTask } from "ember-resources/util/ember-concurrency";
7
+ import { trackedTask } from "reactiveweb/ember-concurrency";
8
8
 
9
9
  import getDocumentAnswersQuery from "@projectcaluma/ember-form/gql/queries/document-answers.graphql";
10
10
  import getDocumentFormsQuery from "@projectcaluma/ember-form/gql/queries/document-forms.graphql";
@@ -0,0 +1,12 @@
1
+ <input
2
+ type="text"
3
+ class="uk-input
4
+ {{if @field.isInvalid 'uk-form-danger'}}
5
+ {{if this.disabled 'uk-disabled'}}"
6
+ name={{@field.pk}}
7
+ id={{@field.pk}}
8
+ value={{this.displayValue}}
9
+ placeholder={{@field.question.raw.placeholder}}
10
+ readonly={{this.disabled}}
11
+ {{on "input" this.input}}
12
+ />
@@ -0,0 +1,46 @@
1
+ import { action } from "@ember/object";
2
+ import { inject as service } from "@ember/service";
3
+ import Component from "@glimmer/component";
4
+ import { cached } from "tracked-toolbox";
5
+
6
+ export default class CfFieldInputNumberSeparatorComponent extends Component {
7
+ @service intl;
8
+
9
+ get disabled() {
10
+ return this.args.disabled || this.args.field?.question.isCalculated;
11
+ }
12
+
13
+ get displayValue() {
14
+ if (!this.args.field.value) {
15
+ return "";
16
+ }
17
+
18
+ return this.intl.formatNumber(this.args.field.value, {
19
+ maximumFractionDigits: 20,
20
+ });
21
+ }
22
+
23
+ @cached
24
+ get thousandSeparator() {
25
+ return this.intl.formatNumber(11111).replace(/\p{Number}/gu, "");
26
+ }
27
+
28
+ @cached
29
+ get decimalSeparator() {
30
+ return this.intl.formatNumber(1.1).replace(/\p{Number}/gu, "");
31
+ }
32
+
33
+ @action
34
+ input({ target: { value } }) {
35
+ // We need to remove the thousand separator and replace the decimal
36
+ // separator with a dot in order to parse it into a number. Which character
37
+ // those are is determined per locale in the getters above.
38
+ const serialized = Number(
39
+ value
40
+ .replace(new RegExp(`\\${this.thousandSeparator}`, "g"), "")
41
+ .replace(new RegExp(`\\${this.decimalSeparator}`), "."),
42
+ );
43
+
44
+ this.args.onSave(isNaN(serialized) ? null : serialized);
45
+ }
46
+ }
@@ -23,7 +23,7 @@
23
23
  {{/if}}
24
24
  </label>
25
25
  {{/each}}
26
- {{#if (and @field.optional @field.answer.value)}}
26
+ {{#if (and @field.optional @field.answer.value (not @disabled))}}
27
27
  <br />
28
28
  <a href="" data-test-radio-reset {{on "click" this.reset}}>
29
29
  {{t "caluma.form.power-select.reset"}}
@@ -21,6 +21,15 @@
21
21
  @onClick={{fn this.download file.id}}
22
22
  />
23
23
  {{/each}}
24
+ {{else if
25
+ (and
26
+ @field.answer.value
27
+ (eq
28
+ @field.question.raw.meta.widgetOverride "cf-field/input/number-separator"
29
+ )
30
+ )
31
+ }}
32
+ {{format-number @field.answer.value maximumFractionDigits=20}}
24
33
  {{else}}
25
34
  {{@field.answer.value}}
26
35
  {{/if}}
@@ -23,7 +23,7 @@
23
23
  }}
24
24
  <FieldComponent
25
25
  @field={{@field}}
26
- @disabled={{@disabled}}
26
+ @disabled={{or @disabled @field.refreshAnswer.isRunning}}
27
27
  @context={{@context}}
28
28
  @onSave={{perform this.save}}
29
29
  />
@@ -38,7 +38,7 @@
38
38
  <div
39
39
  class="cf-field__icon uk-padding-remove-vertical uk-flex uk-flex-middle uk-flex-center"
40
40
  >
41
- {{#if this.save.isRunning}}
41
+ {{#if (or this.save.isRunning @field.refreshAnswer.isRunning)}}
42
42
  <UkSpinner class="uk-animation-fade" />
43
43
  {{else if (or this.save.last.isError @field.isInvalid)}}
44
44
  <div class="uk-flex-inline">
@@ -214,6 +214,7 @@ fragment FieldQuestion on Question {
214
214
 
215
215
  fragment SimpleAnswer on Answer {
216
216
  id
217
+ meta
217
218
  question {
218
219
  id
219
220
  slug
@@ -0,0 +1,18 @@
1
+ #import * from '../fragments/field.graphql'
2
+
3
+ query RefreshAnswer($document: ID!, $question: ID!) {
4
+ allDocuments(filter: [{ id: $document }]) {
5
+ edges {
6
+ node {
7
+ id
8
+ answers(filter: [{ questions: [$question] }]) {
9
+ edges {
10
+ node {
11
+ ...FieldAnswer
12
+ }
13
+ }
14
+ }
15
+ }
16
+ }
17
+ }
18
+ }
@@ -2,6 +2,7 @@ import { setOwner } from "@ember/application";
2
2
  import { inject as service } from "@ember/service";
3
3
 
4
4
  import HiddenComponent from "@projectcaluma/ember-form/components/cf-field/input/hidden";
5
+ import NumberSeparatorComponent from "@projectcaluma/ember-form/components/cf-field/input/number-separator";
5
6
  import PowerSelectComponent from "@projectcaluma/ember-form/components/cf-field/input/powerselect";
6
7
 
7
8
  class HiddenOverride {
@@ -34,17 +35,30 @@ class PowerSelectOverride {
34
35
  ];
35
36
  }
36
37
 
37
- export function initialize(appInstance) {
38
- const options = appInstance.lookup("service:caluma-options");
38
+ class NumberSeparatorOverride {
39
+ @service intl;
39
40
 
40
- const hiddenOverride = new HiddenOverride();
41
- const powerSelectOverride = new PowerSelectOverride();
41
+ get label() {
42
+ return this.intl.t(
43
+ "caluma.form-builder.question.widgetOverrides.number-separator",
44
+ );
45
+ }
46
+
47
+ component = "cf-field/input/number-separator";
48
+ componentClass = NumberSeparatorComponent;
49
+ types = ["IntegerQuestion", "FloatQuestion", "CalculatedFloatQuestion"];
50
+ }
42
51
 
43
- setOwner(hiddenOverride, appInstance);
44
- setOwner(powerSelectOverride, appInstance);
52
+ export function initialize(appInstance) {
53
+ const options = appInstance.lookup("service:caluma-options");
45
54
 
46
- options.registerComponentOverride(hiddenOverride);
47
- options.registerComponentOverride(powerSelectOverride);
55
+ [HiddenOverride, PowerSelectOverride, NumberSeparatorOverride].forEach(
56
+ (cls) => {
57
+ const override = new cls();
58
+ setOwner(override, appInstance);
59
+ options.registerComponentOverride(override);
60
+ },
61
+ );
48
62
  }
49
63
 
50
64
  export default {
@@ -20,6 +20,7 @@ import saveDocumentListAnswerMutation from "@projectcaluma/ember-form/gql/mutati
20
20
  import saveDocumentStringAnswerMutation from "@projectcaluma/ember-form/gql/mutations/save-document-string-answer.graphql";
21
21
  import saveDocumentTableAnswerMutation from "@projectcaluma/ember-form/gql/mutations/save-document-table-answer.graphql";
22
22
  import getDocumentUsedDynamicOptionsQuery from "@projectcaluma/ember-form/gql/queries/document-used-dynamic-options.graphql";
23
+ import refreshAnswerQuery from "@projectcaluma/ember-form/gql/queries/refresh-answer.graphql";
23
24
  import Base from "@projectcaluma/ember-form/lib/base";
24
25
  import dependencies from "@projectcaluma/ember-form/lib/dependencies";
25
26
 
@@ -634,6 +635,29 @@ export default class Field extends Base {
634
635
  this._errors = errors;
635
636
  }
636
637
 
638
+ @dropTask
639
+ *refreshAnswer() {
640
+ const response = yield this.apollo.query(
641
+ {
642
+ query: refreshAnswerQuery,
643
+ fetchPolicy: "network-only",
644
+ variables: {
645
+ document: this.document.uuid,
646
+ question: this.question.slug,
647
+ },
648
+ },
649
+ "allDocuments.edges",
650
+ );
651
+
652
+ const rawAnswer = response[0].node.answers.edges[0]?.node;
653
+
654
+ if (rawAnswer) {
655
+ Object.entries(rawAnswer).forEach(([key, value]) => {
656
+ this.answer.raw[key] = value;
657
+ });
658
+ }
659
+ }
660
+
637
661
  /**
638
662
  * Validate the value against the regexes of the given format validators.
639
663
  *
@@ -1,7 +1,7 @@
1
1
  import { assert } from "@ember/debug";
2
2
  import { camelize } from "@ember/string";
3
3
  import { queryManager } from "ember-apollo-client";
4
- import { trackedFunction } from "ember-resources/util/function";
4
+ import { trackedFunction } from "reactiveweb/function";
5
5
  import { cached } from "tracked-toolbox";
6
6
 
7
7
  import getDynamicOptions from "@projectcaluma/ember-form/gql/queries/dynamic-options.graphql";
@@ -0,0 +1 @@
1
+ export { default } from "@projectcaluma/ember-form/components/cf-field/input/number-separator";
package/index.js CHANGED
@@ -2,4 +2,12 @@
2
2
 
3
3
  module.exports = {
4
4
  name: require("./package").name,
5
+
6
+ options: {
7
+ babel: {
8
+ plugins: [
9
+ require.resolve("ember-concurrency/async-arrow-task-transform"),
10
+ ],
11
+ },
12
+ },
5
13
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectcaluma/ember-form",
3
- "version": "12.9.0",
3
+ "version": "12.10.1",
4
4
  "description": "Ember addon for rendering Caluma forms.",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -9,10 +9,10 @@
9
9
  "homepage": "https://docs.caluma.io/ember-caluma",
10
10
  "repository": "github:projectcaluma/ember-caluma",
11
11
  "dependencies": {
12
- "@babel/core": "^7.23.7",
12
+ "@babel/core": "^7.24.0",
13
13
  "@ember/string": "^3.1.1",
14
- "@embroider/macros": "^1.13.4",
15
- "@embroider/util": "^1.12.1",
14
+ "@embroider/macros": "^1.15.0",
15
+ "@embroider/util": "^1.13.0",
16
16
  "@glimmer/component": "^1.1.2",
17
17
  "@glimmer/tracking": "^1.1.2",
18
18
  "ember-apollo-client": "~4.0.2",
@@ -20,60 +20,60 @@
20
20
  "ember-autoresize-modifier": "^0.7.0",
21
21
  "ember-cli-babel": "^8.2.0",
22
22
  "ember-cli-htmlbars": "^6.3.0",
23
- "ember-cli-showdown": "^8.0.0",
23
+ "ember-cli-showdown": "^9.0.1",
24
24
  "ember-composable-helpers": "^5.0.0",
25
- "ember-concurrency": "^3.1.1",
25
+ "ember-concurrency": "^4.0.1",
26
26
  "ember-fetch": "^8.1.2",
27
- "ember-flatpickr": "^6.0.0",
27
+ "ember-flatpickr": "^7.1.0",
28
28
  "ember-in-viewport": "^4.1.0",
29
- "ember-intl": "^6.4.0",
29
+ "ember-intl": "^6.5.3",
30
30
  "ember-math-helpers": "^4.0.0",
31
31
  "ember-power-select": "^7.2.0",
32
- "ember-resources": "^6.4.2",
33
32
  "ember-truth-helpers": "^4.0.3",
34
- "ember-uikit": "^9.0.0",
33
+ "ember-uikit": "^9.0.1",
35
34
  "ember-validators": "^4.1.2",
36
35
  "flatpickr": "^4.6.13",
37
36
  "graphql": "^15.8.0",
38
37
  "jexl": "^2.3.0",
39
38
  "lodash.isequal": "^4.5.0",
40
39
  "luxon": "^3.4.4",
40
+ "reactiveweb": "^1.2.2",
41
41
  "tracked-toolbox": "^2.0.0",
42
- "@projectcaluma/ember-core": "^12.9.0"
42
+ "@projectcaluma/ember-core": "^12.10.1"
43
43
  },
44
44
  "devDependencies": {
45
- "@ember/optional-features": "2.0.0",
46
- "@ember/test-helpers": "3.2.1",
45
+ "@ember/optional-features": "2.1.0",
46
+ "@ember/test-helpers": "3.3.0",
47
47
  "@embroider/test-setup": "3.0.3",
48
- "@faker-js/faker": "8.3.1",
48
+ "@faker-js/faker": "8.4.1",
49
49
  "broccoli-asset-rev": "3.0.0",
50
- "ember-cli": "5.5.0",
50
+ "ember-cli": "5.7.0",
51
51
  "ember-cli-clean-css": "3.0.0",
52
- "ember-cli-code-coverage": "2.0.3",
52
+ "ember-cli-code-coverage": "2.1.1",
53
53
  "ember-cli-dependency-checker": "3.3.2",
54
54
  "ember-cli-inject-live-reload": "2.1.0",
55
- "ember-cli-mirage": "3.0.2",
55
+ "ember-cli-mirage": "3.0.3",
56
56
  "ember-cli-sri": "2.1.1",
57
57
  "ember-cli-terser": "4.0.2",
58
58
  "ember-load-initializers": "2.1.2",
59
59
  "ember-qunit": "8.0.2",
60
60
  "ember-resolver": "11.0.1",
61
- "ember-source": "5.6.0",
61
+ "ember-source": "5.7.0",
62
62
  "ember-source-channel-url": "3.0.0",
63
63
  "ember-try": "3.0.0",
64
64
  "loader.js": "4.7.0",
65
65
  "miragejs": "0.1.48",
66
- "qunit": "2.20.0",
66
+ "qunit": "2.20.1",
67
67
  "qunit-dom": "3.0.0",
68
- "uikit": "3.17.11",
68
+ "uikit": "3.19.2",
69
69
  "uuid": "9.0.1",
70
- "webpack": "5.89.0",
71
- "@projectcaluma/ember-testing": "12.9.0",
72
- "@projectcaluma/ember-workflow": "12.9.0"
70
+ "webpack": "5.90.3",
71
+ "@projectcaluma/ember-testing": "12.10.1",
72
+ "@projectcaluma/ember-workflow": "12.10.1"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "ember-source": "^4.0.0",
76
- "@projectcaluma/ember-workflow": "^12.9.0"
76
+ "@projectcaluma/ember-workflow": "^12.10.1"
77
77
  },
78
78
  "dependenciesMeta": {
79
79
  "@projectcaluma/ember-core": {