@projectcaluma/ember-form 10.0.0 → 11.0.0-beta.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.
Files changed (41) hide show
  1. package/addon/components/cf-content.hbs +36 -39
  2. package/addon/components/cf-content.js +47 -20
  3. package/addon/components/cf-field/input/action-button.hbs +1 -1
  4. package/addon/components/cf-field/input/action-button.js +9 -7
  5. package/addon/components/cf-field/input/checkbox.hbs +2 -2
  6. package/addon/components/cf-field/input/checkbox.js +9 -29
  7. package/addon/components/cf-field/input/file.js +8 -9
  8. package/addon/components/cf-field/input/float.hbs +4 -4
  9. package/addon/components/cf-field/input/integer.hbs +5 -5
  10. package/addon/components/cf-field/input/table.js +12 -10
  11. package/addon/components/cf-field/input/text.hbs +5 -5
  12. package/addon/components/cf-field/input/textarea.hbs +5 -5
  13. package/addon/components/cf-field/input.js +1 -1
  14. package/addon/components/cf-field/label.hbs +1 -1
  15. package/addon/components/cf-field-value.js +8 -13
  16. package/addon/components/cf-field.hbs +2 -2
  17. package/addon/components/cf-field.js +2 -3
  18. package/addon/components/cf-navigation-item.hbs +2 -2
  19. package/addon/components/document-validity.js +1 -1
  20. package/addon/gql/fragments/field.graphql +27 -0
  21. package/addon/gql/mutations/save-document-table-answer.graphql +1 -1
  22. package/addon/gql/mutations/save-document.graphql +1 -0
  23. package/addon/gql/queries/{get-document-answers.graphql → document-answers.graphql} +2 -1
  24. package/addon/gql/queries/{get-document-forms.graphql → document-forms.graphql} +2 -1
  25. package/addon/gql/queries/{get-document-used-dynamic-options.graphql → document-used-dynamic-options.graphql} +2 -1
  26. package/addon/gql/queries/{get-dynamic-options.graphql → dynamic-options.graphql} +2 -1
  27. package/addon/gql/queries/{get-fileanswer-info.graphql → fileanswer-info.graphql} +2 -1
  28. package/addon/helpers/get-widget.js +50 -0
  29. package/addon/lib/answer.js +108 -72
  30. package/addon/lib/base.js +32 -23
  31. package/addon/lib/dependencies.js +36 -71
  32. package/addon/lib/document.js +92 -96
  33. package/addon/lib/field.js +334 -401
  34. package/addon/lib/fieldset.js +46 -47
  35. package/addon/lib/form.js +27 -15
  36. package/addon/lib/navigation.js +187 -181
  37. package/addon/lib/question.js +103 -94
  38. package/addon/services/caluma-store.js +10 -6
  39. package/app/helpers/get-widget.js +4 -0
  40. package/package.json +19 -18
  41. package/CHANGELOG.md +0 -21
@@ -1,11 +1,10 @@
1
1
  import { assert } from "@ember/debug";
2
- import { defineProperty, computed } from "@ember/object";
3
- import { reads, equal } from "@ember/object/computed";
4
2
  import { camelize } from "@ember/string";
5
3
  import { queryManager } from "ember-apollo-client";
6
- import { task } from "ember-concurrency";
4
+ import { dropTask, lastValue } from "ember-concurrency";
5
+ import { cached } from "tracked-toolbox";
7
6
 
8
- import getDynamicOptions from "@projectcaluma/ember-form/gql/queries/get-dynamic-options.graphql";
7
+ import getDynamicOptions from "@projectcaluma/ember-form/gql/queries/dynamic-options.graphql";
9
8
  import Base from "@projectcaluma/ember-form/lib/base";
10
9
 
11
10
  const getValue = (answer) => {
@@ -17,24 +16,39 @@ const getValue = (answer) => {
17
16
  *
18
17
  * @class Question
19
18
  */
20
- export default Base.extend({
21
- apollo: queryManager(),
19
+ export default class Question extends Base {
20
+ @queryManager apollo;
22
21
 
23
- init(...args) {
22
+ constructor({ raw, ...args }) {
24
23
  assert(
25
24
  "A graphql question `raw` must be passed",
26
- this.raw && /Question$/.test(this.raw.__typename)
25
+ /Question$/.test(raw?.__typename)
27
26
  );
28
27
 
29
- defineProperty(this, "pk", {
30
- writable: false,
31
- value: `Question:${this.raw.slug}`,
32
- });
28
+ super({ raw, ...args });
33
29
 
34
- this._super(...args);
30
+ this.pushIntoStore();
31
+ }
35
32
 
36
- this.setProperties(this.raw);
37
- },
33
+ /**
34
+ * The primary key of the question.
35
+ *
36
+ * @property {String} pk
37
+ */
38
+ @cached
39
+ get pk() {
40
+ return `Question:${this.slug}`;
41
+ }
42
+
43
+ /**
44
+ * The slug of the question.
45
+ *
46
+ * @property {String} slug
47
+ */
48
+ @cached
49
+ get slug() {
50
+ return this.raw.slug;
51
+ }
38
52
 
39
53
  /**
40
54
  * Load all dynamic options for this question
@@ -43,7 +57,8 @@ export default Base.extend({
43
57
  * @return {Object[]} The dynamic options
44
58
  * @public
45
59
  */
46
- loadDynamicOptions: task(function* () {
60
+ @dropTask
61
+ *loadDynamicOptions() {
47
62
  if (!this.isDynamic) return;
48
63
 
49
64
  const [question] = yield this.apollo.query(
@@ -59,108 +74,102 @@ export default Base.extend({
59
74
  question.node.dynamicChoiceOptions ||
60
75
  question.node.dynamicMultipleChoiceOptions
61
76
  );
62
- }),
77
+ }
63
78
 
64
- dynamicChoiceOptions: reads("loadDynamicOptions.lastSuccessful.value"),
65
- dynamicMultipleChoiceOptions: reads(
66
- "loadDynamicOptions.lastSuccessful.value"
67
- ),
79
+ @lastValue("loadDynamicOptions") dynamicChoiceOptions;
80
+ @lastValue("loadDynamicOptions") dynamicMultipleChoiceOptions;
68
81
 
69
82
  /**
70
83
  * Whether the question is a single choice question
71
84
  *
72
85
  * @property {Boolean} isChoice
73
- * @accessor
74
86
  */
75
- isChoice: computed("__typename", function () {
76
- return /(Dynamic)?ChoiceQuestion/.test(this.__typename);
77
- }),
87
+ get isChoice() {
88
+ return /(Dynamic)?ChoiceQuestion/.test(this.raw.__typename);
89
+ }
78
90
 
79
91
  /**
80
92
  * Whether the question is a multiple choice question
81
93
  *
82
94
  * @property {Boolean} isMultipleChoice
83
- * @accessor
84
95
  */
85
- isMultipleChoice: computed("__typename", function () {
86
- return /(Dynamic)?MultipleChoiceQuestion/.test(this.__typename);
87
- }),
96
+ get isMultipleChoice() {
97
+ return /(Dynamic)?MultipleChoiceQuestion/.test(this.raw.__typename);
98
+ }
88
99
 
89
100
  /**
90
101
  * Whether the question is a dynamic single or multiple choice question
91
102
  *
92
103
  * @property {Boolean} isDynamic
93
- * @accessor
94
104
  */
95
- isDynamic: computed("__typename", function () {
96
- return /Dynamic(Multiple)?ChoiceQuestion/.test(this.__typename);
97
- }),
105
+ get isDynamic() {
106
+ return /Dynamic(Multiple)?ChoiceQuestion/.test(this.raw.__typename);
107
+ }
108
+
109
+ /**
110
+ * Whether the question is a table question
111
+ *
112
+ * @property {Boolean} isTable
113
+ */
114
+ get isTable() {
115
+ return this.raw.__typename === "TableQuestion";
116
+ }
98
117
 
99
- isTable: equal("__typename", "TableQuestion"),
100
- isCalculated: equal("__typename", "CalculatedFloatQuestion"),
118
+ /**
119
+ * Whether the question is a calculated question
120
+ *
121
+ * @property {Boolean} isCalculated
122
+ */
123
+ get isCalculated() {
124
+ return this.raw.__typename === "CalculatedFloatQuestion";
125
+ }
101
126
 
102
127
  /**
103
128
  * All valid options for this question
104
129
  *
105
130
  * @property {Object[]} options
106
- * @accessor
107
131
  */
108
- options: computed(
109
- "__typename",
110
- "choiceOptions.edges.[]",
111
- "dynamicChoiceOptions.edges.[]",
112
- "dynamicMultipleChoiceOptions.edges.[]",
113
- "isChoice",
114
- "isMultipleChoice",
115
- "multipleChoiceOptions.edges.[]",
116
- function () {
117
- if (!this.isChoice && !this.isMultipleChoice) return null;
118
-
119
- const key = camelize(this.__typename.replace(/Question$/, "Options"));
120
-
121
- return (this.get(`${key}.edges`) || []).map(
122
- ({ node: { label, slug, isArchived } }) => ({
123
- label,
124
- slug,
125
- disabled: isArchived || false,
126
- })
127
- );
128
- }
129
- ),
130
-
131
- defaultValue: computed(
132
- "__typename",
133
- "isTable",
134
- "textDefaultAnswer",
135
- "textareaDefaultAnswer",
136
- "integerDefaultAnswer",
137
- "floatDefaultAnswer",
138
- "choiceDefaultAnswer",
139
- "multipleChoiceDefaultAnswer.[]",
140
- "dateDefaultAnswer",
141
- "tableDefaultAnswer.[]",
142
- function () {
143
- const key = camelize(
144
- this.__typename.replace(/Question$/, "DefaultAnswer")
145
- );
146
-
147
- const value = this[key] && this[key].value;
148
-
149
- if (this.isTable && value) {
150
- return value.map((defaultDocument) => {
151
- return defaultDocument.answers.edges.reduce(
152
- (defaultMap, { node: answer }) => {
153
- return {
154
- ...defaultMap,
155
- [answer.question.slug]: getValue(answer),
156
- };
157
- },
158
- {}
159
- );
160
- });
161
- }
162
-
163
- return value;
132
+ @cached
133
+ get options() {
134
+ if (!this.isChoice && !this.isMultipleChoice) return null;
135
+
136
+ const key = camelize(this.raw.__typename.replace(/Question$/, "Options"));
137
+ const raw = this.isDynamic ? this[key] : this.raw[key];
138
+
139
+ return (raw?.edges || []).map(({ node: { label, slug, isArchived } }) => ({
140
+ label,
141
+ slug,
142
+ disabled: isArchived || false,
143
+ }));
144
+ }
145
+
146
+ /**
147
+ * The default value of the question
148
+ *
149
+ * @property {String|Number|String[]|Object[]} defaultValue
150
+ */
151
+ @cached
152
+ get defaultValue() {
153
+ const key = camelize(
154
+ this.raw.__typename.replace(/Question$/, "DefaultAnswer")
155
+ );
156
+
157
+ const value = this.raw[key]?.value;
158
+
159
+ if (this.isTable && value) {
160
+ return value.map((defaultDocument) => {
161
+ return defaultDocument.answers.edges.reduce(
162
+ (defaultMap, { node: answer }) => {
163
+ return {
164
+ ...defaultMap,
165
+ [answer.question.slug]: getValue(answer),
166
+ };
167
+ },
168
+ {}
169
+ );
170
+ });
164
171
  }
165
- ),
166
- });
172
+
173
+ return value;
174
+ }
175
+ }
@@ -3,7 +3,11 @@ import { set } from "@ember/object";
3
3
  import Service from "@ember/service";
4
4
 
5
5
  export default class CalumaStoreService extends Service {
6
- _store = [];
6
+ constructor(...args) {
7
+ super(...args);
8
+
9
+ this._store = new Map();
10
+ }
7
11
 
8
12
  push(obj) {
9
13
  assert(
@@ -11,7 +15,7 @@ export default class CalumaStoreService extends Service {
11
15
  obj.pk
12
16
  );
13
17
 
14
- const existing = this._store.find((i) => i.pk === obj.pk);
18
+ const existing = this._store.get(obj.pk);
15
19
 
16
20
  if (existing) {
17
21
  debug(
@@ -23,22 +27,22 @@ export default class CalumaStoreService extends Service {
23
27
  return existing;
24
28
  }
25
29
 
26
- this._store = [...this._store.filter((i) => i.pk !== obj.pk), obj];
30
+ this._store.set(obj.pk, obj);
27
31
 
28
32
  return obj;
29
33
  }
30
34
 
31
35
  find(pk) {
32
- return this._store.find((i) => i.pk === pk) || null;
36
+ return this._store.get(pk) || null;
33
37
  }
34
38
 
35
39
  delete(pk) {
36
- this._store = this._store.filter((i) => i.pk !== pk);
40
+ this._store.delete(pk);
37
41
  }
38
42
 
39
43
  clear() {
40
44
  this._store.forEach((obj) => obj.destroy());
41
45
 
42
- this._store = [];
46
+ this._store.clear();
43
47
  }
44
48
  }
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ getWidget,
4
+ } from "@projectcaluma/ember-form/helpers/get-widget";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectcaluma/ember-form",
3
- "version": "10.0.0",
3
+ "version": "11.0.0-beta.1",
4
4
  "description": "Ember addon for rendering Caluma forms.",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -16,34 +16,35 @@
16
16
  "dependencies": {
17
17
  "@glimmer/component": "^1.0.4",
18
18
  "@glimmer/tracking": "^1.0.4",
19
- "@projectcaluma/ember-core": "^10.0.0",
19
+ "@projectcaluma/ember-core": "^11.0.0-beta.1",
20
20
  "ember-apollo-client": "^3.2.0",
21
21
  "ember-auto-import": "^2.2.3",
22
- "ember-cli-babel": "^7.26.6",
23
- "ember-cli-htmlbars": "^6.0.0",
24
- "ember-cli-showdown": "^6.0.0",
25
- "ember-composable-helpers": "^4.5.0",
22
+ "ember-cli-babel": "^7.26.11",
23
+ "ember-cli-htmlbars": "^6.0.1",
24
+ "ember-cli-showdown": "^6.0.1",
25
+ "ember-composable-helpers": "^5.0.0",
26
26
  "ember-fetch": "^8.0.4",
27
- "ember-in-viewport": "^3.10.3",
28
- "ember-intl": "^5.7.0",
27
+ "ember-in-viewport": "^4.0.0",
28
+ "ember-intl": "^5.7.2",
29
29
  "ember-math-helpers": "^2.18.0",
30
30
  "ember-pikaday": "^3.0.0",
31
- "ember-power-select": "^4.1.7",
31
+ "ember-power-select": "^5.0.3",
32
+ "ember-resources": "^4.1.3",
32
33
  "ember-uikit": "^4.0.0",
33
- "graphql": "^15.6.1",
34
+ "graphql": "^15.8.0",
34
35
  "jexl": "^2.3.0",
35
- "lodash.clonedeep": "^4.5.0",
36
36
  "lodash.isequal": "^4.5.0",
37
- "moment": "^2.29.1"
37
+ "moment": "^2.29.1",
38
+ "tracked-toolbox": "^1.2.3"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@ember/optional-features": "2.0.0",
41
42
  "@ember/test-helpers": "2.6.0",
42
- "@embroider/test-setup": "0.47.2",
43
- "@projectcaluma/ember-testing": "9.1.0",
44
- "@projectcaluma/ember-workflow": "9.0.3",
43
+ "@embroider/test-setup": "0.49.0",
44
+ "@projectcaluma/ember-testing": "10.1.0",
45
+ "@projectcaluma/ember-workflow": "10.0.3",
45
46
  "broccoli-asset-rev": "3.0.0",
46
- "ember-cli": "3.28.4",
47
+ "ember-cli": "3.28.5",
47
48
  "ember-cli-code-coverage": "1.0.3",
48
49
  "ember-cli-dependency-checker": "3.2.0",
49
50
  "ember-cli-inject-live-reload": "2.1.0",
@@ -56,7 +57,7 @@
56
57
  "ember-maybe-import-regenerator": "1.0.0",
57
58
  "ember-qunit": "5.1.5",
58
59
  "ember-resolver": "8.0.3",
59
- "ember-source": "3.28.6",
60
+ "ember-source": "3.28.8",
60
61
  "ember-source-channel-url": "3.0.0",
61
62
  "ember-try": "2.0.0",
62
63
  "faker": "5.5.3",
@@ -65,7 +66,7 @@
65
66
  "qunit": "2.17.2",
66
67
  "qunit-dom": "2.0.0",
67
68
  "uuid": "8.3.2",
68
- "webpack": "5.64.1"
69
+ "webpack": "5.65.0"
69
70
  },
70
71
  "engines": {
71
72
  "node": "12.* || 14.* || >= 16"
package/CHANGELOG.md DELETED
@@ -1,21 +0,0 @@
1
- # [@projectcaluma/ember-form-v10.0.0](https://github.com/projectcaluma/ember-caluma/compare/@projectcaluma/ember-form-v9.3.0...@projectcaluma/ember-form-v10.0.0) (2021-11-25)
2
-
3
-
4
- ### Bug Fixes
5
-
6
- * **form:** return default value for answer transform if empty ([ed703bc](https://github.com/projectcaluma/ember-caluma/commit/ed703bc2505e0ec59ec5b5ed6df4e0bb4f93db12))
7
-
8
-
9
- ### chore
10
-
11
- * **deps:** update dependencies and drop support for node 10 ([51d6dee](https://github.com/projectcaluma/ember-caluma/commit/51d6deeda9811518622ba0cefd8d3876651dab4f))
12
-
13
-
14
- ### Features
15
-
16
- * **action-button:** improve detection of work item for action button ([f00b7b0](https://github.com/projectcaluma/ember-caluma/commit/f00b7b06ac114c5bee2267132518c13ee1502ad0))
17
-
18
-
19
- ### BREAKING CHANGES
20
-
21
- * **deps:** Remove support for node v10