@projectcaluma/ember-core 9.0.3 → 10.0.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.
- package/addon/-private/possible-types.js +5 -2
- package/addon/caluma-query/queries/base.js +73 -52
- package/addon/helpers/-resolver.js +64 -0
- package/addon/helpers/group-name.js +5 -0
- package/addon/helpers/user-name.js +5 -0
- package/addon/services/-scheduler.js +79 -0
- package/addon/services/caluma-options.js +18 -0
- package/app/helpers/group-name.js +1 -0
- package/app/helpers/user-name.js +1 -0
- package/app/services/-scheduler.js +1 -0
- package/package.json +19 -16
- package/translations/de.yaml +2 -1
- package/translations/en.yaml +2 -0
- package/translations/fr.yaml +2 -1
|
@@ -7,7 +7,6 @@ export default {
|
|
|
7
7
|
"WorkItem",
|
|
8
8
|
"Flow",
|
|
9
9
|
"DynamicOption",
|
|
10
|
-
"CalculatedFloatQuestion",
|
|
11
10
|
"Option",
|
|
12
11
|
"TextQuestion",
|
|
13
12
|
"StringAnswer",
|
|
@@ -30,13 +29,14 @@ export default {
|
|
|
30
29
|
"StaticQuestion",
|
|
31
30
|
"FileAnswer",
|
|
32
31
|
"File",
|
|
32
|
+
"CalculatedFloatQuestion",
|
|
33
|
+
"ActionButtonQuestion",
|
|
33
34
|
"SimpleTask",
|
|
34
35
|
"CompleteWorkflowFormTask",
|
|
35
36
|
"CompleteTaskFormTask",
|
|
36
37
|
],
|
|
37
38
|
Task: ["SimpleTask", "CompleteWorkflowFormTask", "CompleteTaskFormTask"],
|
|
38
39
|
Question: [
|
|
39
|
-
"CalculatedFloatQuestion",
|
|
40
40
|
"TextQuestion",
|
|
41
41
|
"ChoiceQuestion",
|
|
42
42
|
"MultipleChoiceQuestion",
|
|
@@ -50,6 +50,8 @@ export default {
|
|
|
50
50
|
"FormQuestion",
|
|
51
51
|
"FileQuestion",
|
|
52
52
|
"StaticQuestion",
|
|
53
|
+
"CalculatedFloatQuestion",
|
|
54
|
+
"ActionButtonQuestion",
|
|
53
55
|
],
|
|
54
56
|
Answer: [
|
|
55
57
|
"StringAnswer",
|
|
@@ -60,4 +62,5 @@ export default {
|
|
|
60
62
|
"TableAnswer",
|
|
61
63
|
"FileAnswer",
|
|
62
64
|
],
|
|
65
|
+
DynamicQuestion: ["DynamicChoiceQuestion", "DynamicMultipleChoiceQuestion"],
|
|
63
66
|
};
|
|
@@ -2,18 +2,19 @@ import { getOwner, setOwner } from "@ember/application";
|
|
|
2
2
|
import { assert } from "@ember/debug";
|
|
3
3
|
import { tracked } from "@glimmer/tracking";
|
|
4
4
|
import { queryManager } from "ember-apollo-client";
|
|
5
|
-
import
|
|
5
|
+
import {
|
|
6
|
+
enqueueTask,
|
|
7
|
+
lastValue,
|
|
8
|
+
restartableTask,
|
|
9
|
+
task,
|
|
10
|
+
} from "ember-concurrency-decorators";
|
|
11
|
+
import { gql } from "graphql-tag";
|
|
6
12
|
|
|
7
13
|
export default class BaseQuery {
|
|
8
14
|
@queryManager apollo;
|
|
9
15
|
|
|
10
16
|
@tracked items = [];
|
|
11
17
|
|
|
12
|
-
@tracked totalCount = 0;
|
|
13
|
-
@tracked hasNextPage = true;
|
|
14
|
-
|
|
15
|
-
@tracked isLoading = true;
|
|
16
|
-
|
|
17
18
|
constructor({
|
|
18
19
|
pageSize = null,
|
|
19
20
|
processNew = async (items) => items,
|
|
@@ -21,17 +22,13 @@ export default class BaseQuery {
|
|
|
21
22
|
queryOptions = {},
|
|
22
23
|
}) {
|
|
23
24
|
this.pageSize = pageSize;
|
|
24
|
-
this.cursor = null;
|
|
25
|
-
|
|
26
25
|
this.processNew = processNew;
|
|
27
26
|
this.processAll = processAll;
|
|
28
27
|
this.queryOptions = queryOptions;
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
get query() {
|
|
32
|
-
assert("`query` must be implemented on the model");
|
|
33
|
-
|
|
34
|
-
return "";
|
|
31
|
+
return assert("`query` must be implemented on the model");
|
|
35
32
|
}
|
|
36
33
|
|
|
37
34
|
get pagination() {
|
|
@@ -52,51 +49,20 @@ export default class BaseQuery {
|
|
|
52
49
|
return factory.class;
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
this.
|
|
57
|
-
|
|
58
|
-
this.hasNextPage = true;
|
|
59
|
-
this.cursor = null;
|
|
52
|
+
get isLoading() {
|
|
53
|
+
return this._fetch.isRunning || this._fetchMore.isRunning;
|
|
54
|
+
}
|
|
60
55
|
|
|
61
|
-
|
|
62
|
-
this.
|
|
63
|
-
|
|
56
|
+
get totalCount() {
|
|
57
|
+
return this._data?.[this.dataKey].totalCount;
|
|
58
|
+
}
|
|
64
59
|
|
|
65
|
-
|
|
60
|
+
get hasNextPage() {
|
|
61
|
+
return this._data?.[this.dataKey].pageInfo.hasNextPage;
|
|
66
62
|
}
|
|
67
63
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
this.isLoading = true;
|
|
71
|
-
|
|
72
|
-
const data = await this.apollo.query({
|
|
73
|
-
query: gql`
|
|
74
|
-
${this.query}
|
|
75
|
-
`,
|
|
76
|
-
variables: {
|
|
77
|
-
filter: this.filter,
|
|
78
|
-
order: this.order,
|
|
79
|
-
pageSize: this.pageSize,
|
|
80
|
-
cursor: this.cursor,
|
|
81
|
-
},
|
|
82
|
-
fetchPolicy: "network-only",
|
|
83
|
-
...this.queryOptions,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
this.cursor = data[this.dataKey].pageInfo.endCursor;
|
|
87
|
-
|
|
88
|
-
this.hasNextPage = data[this.dataKey].pageInfo.hasNextPage;
|
|
89
|
-
this.totalCount = data[this.dataKey].totalCount;
|
|
90
|
-
|
|
91
|
-
const rawItems = data[this.dataKey].edges.map(({ node }) => node);
|
|
92
|
-
|
|
93
|
-
this.items = await this.processAll([
|
|
94
|
-
...this.items,
|
|
95
|
-
...(await this.processNew(rawItems)),
|
|
96
|
-
]);
|
|
97
|
-
|
|
98
|
-
this.isLoading = false;
|
|
99
|
-
}
|
|
64
|
+
get cursor() {
|
|
65
|
+
return this._data?.[this.dataKey].pageInfo.endCursor;
|
|
100
66
|
}
|
|
101
67
|
|
|
102
68
|
get value() {
|
|
@@ -112,4 +78,59 @@ export default class BaseQuery {
|
|
|
112
78
|
return instance;
|
|
113
79
|
});
|
|
114
80
|
}
|
|
81
|
+
|
|
82
|
+
fetch(...args) {
|
|
83
|
+
return this._fetch.perform(...args);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
fetchMore(...args) {
|
|
87
|
+
return this._fetchMore.perform(...args);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@restartableTask
|
|
91
|
+
*_fetch({ filter = [], order = [], queryOptions = {} } = {}) {
|
|
92
|
+
yield this._fetchPage.cancelAll({ resetState: true });
|
|
93
|
+
|
|
94
|
+
this.items = [];
|
|
95
|
+
|
|
96
|
+
this.filter = filter;
|
|
97
|
+
this.order = order;
|
|
98
|
+
this.queryOptions = { ...(this.queryOptions ?? {}), ...queryOptions };
|
|
99
|
+
|
|
100
|
+
return yield this._fetchPage.linked().perform();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@enqueueTask
|
|
104
|
+
*_fetchMore() {
|
|
105
|
+
if (!this._data) return;
|
|
106
|
+
|
|
107
|
+
return yield this._fetchPage.linked().perform();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@lastValue("_fetchPage") _data;
|
|
111
|
+
@task
|
|
112
|
+
*_fetchPage() {
|
|
113
|
+
const data = yield this.apollo.query({
|
|
114
|
+
query: gql`
|
|
115
|
+
${this.query}
|
|
116
|
+
`,
|
|
117
|
+
variables: {
|
|
118
|
+
filter: this.filter,
|
|
119
|
+
order: this.order,
|
|
120
|
+
pageSize: this.pageSize,
|
|
121
|
+
cursor: this.cursor,
|
|
122
|
+
},
|
|
123
|
+
fetchPolicy: "network-only",
|
|
124
|
+
...this.queryOptions,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
this.items = yield this.processAll([
|
|
128
|
+
...this.items,
|
|
129
|
+
...(yield this.processNew(
|
|
130
|
+
data[this.dataKey].edges.map(({ node }) => node)
|
|
131
|
+
)),
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
return data;
|
|
135
|
+
}
|
|
115
136
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import Helper from "@ember/component/helper";
|
|
2
|
+
import { assert } from "@ember/debug";
|
|
3
|
+
import { run } from "@ember/runloop";
|
|
4
|
+
import { inject as service } from "@ember/service";
|
|
5
|
+
|
|
6
|
+
export default class PrivateResolver extends Helper {
|
|
7
|
+
@service("-scheduler") scheduler;
|
|
8
|
+
@service calumaOptions;
|
|
9
|
+
|
|
10
|
+
get resolverType() {
|
|
11
|
+
return assert("`resolverType` needs to be defined");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
_identifier = null;
|
|
15
|
+
_value = null;
|
|
16
|
+
_settled = false;
|
|
17
|
+
|
|
18
|
+
compute([identifiers]) {
|
|
19
|
+
const identifier = Array.isArray(identifiers)
|
|
20
|
+
? identifiers[0]
|
|
21
|
+
: identifiers;
|
|
22
|
+
|
|
23
|
+
if (!identifier) return null;
|
|
24
|
+
|
|
25
|
+
// The parameter for the helper changed so we need to recompute and store
|
|
26
|
+
// the new parameter to remember it at the next computation
|
|
27
|
+
if (identifier !== this._identifier) {
|
|
28
|
+
this._settled = false;
|
|
29
|
+
this._identifier = identifier;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// The value is resolved, return the passed property (default is defined as
|
|
33
|
+
// `{type}NameProperty` on the caluma options service) of the value. This
|
|
34
|
+
// happens after the `this.recompute()` call in `resolve`
|
|
35
|
+
if (this._settled) {
|
|
36
|
+
return this._value?.[
|
|
37
|
+
this.calumaOptions[`${this.resolverType}NameProperty`]
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Schedule a resolve batch to only trigger the resolve method in the caluma
|
|
42
|
+
// options service once. We pass a resolve function to run after the
|
|
43
|
+
// possibly asynchronous resolve method.
|
|
44
|
+
this.scheduler.resolveOnce(identifier, this.resolverType, (value) =>
|
|
45
|
+
run(this, "resolve", value)
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// Return the default value (`null`) if the value is not computed yet
|
|
49
|
+
return this._value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Resolver method to set the value to the resolved value and mark the helper
|
|
54
|
+
* as settled and then recompute it to display that value.
|
|
55
|
+
*
|
|
56
|
+
* @method resolve
|
|
57
|
+
* @param {*} value The resolved group value
|
|
58
|
+
*/
|
|
59
|
+
resolve(value) {
|
|
60
|
+
this._value = value;
|
|
61
|
+
this._settled = true;
|
|
62
|
+
this.recompute();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { assert } from "@ember/debug";
|
|
2
|
+
import { once } from "@ember/runloop";
|
|
3
|
+
import Service, { inject as service } from "@ember/service";
|
|
4
|
+
import { camelize } from "@ember/string";
|
|
5
|
+
import { task } from "ember-concurrency";
|
|
6
|
+
import { pluralize } from "ember-inflector";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Decorator to define a type resolver in the scheduler service.
|
|
10
|
+
*
|
|
11
|
+
* @function typeResolver
|
|
12
|
+
* @param {"group"|"user"} type The type of the objects to resolve
|
|
13
|
+
* @returns {Function} The decorator function that returns an enqueued task to resolve the requested objects
|
|
14
|
+
*/
|
|
15
|
+
function typeResolver(type) {
|
|
16
|
+
return task(function* () {
|
|
17
|
+
const identifiers = [...this[type].identifiers];
|
|
18
|
+
const callbacks = [...this[type].callbacks];
|
|
19
|
+
|
|
20
|
+
this[type] = undefined;
|
|
21
|
+
|
|
22
|
+
if (!identifiers.length) return;
|
|
23
|
+
|
|
24
|
+
const methodName = camelize(`resolve-${pluralize(type)}`);
|
|
25
|
+
const result = yield this.calumaOptions[methodName]?.(identifiers);
|
|
26
|
+
|
|
27
|
+
yield Promise.all(callbacks.map((callback) => callback(result)));
|
|
28
|
+
|
|
29
|
+
return result;
|
|
30
|
+
}).enqueue();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default class PrivateSchedulerService extends Service {
|
|
34
|
+
@service calumaOptions;
|
|
35
|
+
|
|
36
|
+
@typeResolver("group") resolveGroup;
|
|
37
|
+
@typeResolver("user") resolveUser;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a certain object of a type only once in the runloop.
|
|
41
|
+
*
|
|
42
|
+
* This method adds the given identifier to a set of already requested
|
|
43
|
+
* identifiers of a type and calls the resolve method of that type once in a
|
|
44
|
+
* single render loop and then passes the resolved object to a passed
|
|
45
|
+
* callback.
|
|
46
|
+
*
|
|
47
|
+
* @method resolveOnce
|
|
48
|
+
* @param {String} identifier The identifier used to find the resolved object
|
|
49
|
+
* @param {"group"|"user"} type The type of the object to resolve
|
|
50
|
+
* @param {Function} callback The callback function to call after the object is resolved
|
|
51
|
+
*/
|
|
52
|
+
resolveOnce(identifier, type, callback) {
|
|
53
|
+
const _callback = (result) => {
|
|
54
|
+
callback(
|
|
55
|
+
result.find(
|
|
56
|
+
(obj) =>
|
|
57
|
+
String(obj[this.calumaOptions[`${type}IdentifierProperty`]]) ===
|
|
58
|
+
String(identifier)
|
|
59
|
+
)
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (!this[type]) {
|
|
64
|
+
this[type] = { identifiers: new Set(), callbacks: new Set() };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this[type].identifiers.add(identifier);
|
|
68
|
+
this[type].callbacks.add(_callback);
|
|
69
|
+
|
|
70
|
+
const typeResolverName = camelize(`resolve-${type}`);
|
|
71
|
+
|
|
72
|
+
assert(
|
|
73
|
+
`${typeResolverName} needs to be defined on the scheduler service`,
|
|
74
|
+
typeResolverName in this
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
once(this[typeResolverName], "perform");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -88,4 +88,22 @@ export default class CalumaOptionsService extends Service {
|
|
|
88
88
|
getComponentOverrides() {
|
|
89
89
|
return Object.values(this._overrides);
|
|
90
90
|
}
|
|
91
|
+
|
|
92
|
+
groupIdentifierProperty = "id";
|
|
93
|
+
groupNameProperty = "name";
|
|
94
|
+
resolveGroups(identifiers) {
|
|
95
|
+
return identifiers.map((identifier) => ({
|
|
96
|
+
[this.groupIdentifierProperty]: identifier,
|
|
97
|
+
[this.groupNameProperty]: identifier,
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
userIdentifierProperty = "username";
|
|
102
|
+
userNameProperty = "fullName";
|
|
103
|
+
resolveUsers(identifiers) {
|
|
104
|
+
return identifiers.map((identifier) => ({
|
|
105
|
+
[this.userIdentifierProperty]: identifier,
|
|
106
|
+
[this.userNameProperty]: identifier,
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
91
109
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "@projectcaluma/ember-core/helpers/group-name";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "@projectcaluma/ember-core/helpers/user-name";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "@projectcaluma/ember-core/services/-scheduler";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@projectcaluma/ember-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.1",
|
|
4
4
|
"description": "Ember core addon for working with Caluma.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -15,31 +15,34 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@apollo/client": "^3.4.16",
|
|
18
|
+
"@glimmer/tracking": "^1.0.4",
|
|
18
19
|
"ember-apollo-client": "^3.2.0",
|
|
19
|
-
"ember-auto-import": "^2.2.
|
|
20
|
+
"ember-auto-import": "^2.2.3",
|
|
20
21
|
"ember-changeset-validations": "^3.16.0",
|
|
21
22
|
"ember-cli-babel": "^7.26.6",
|
|
22
|
-
"ember-cli-htmlbars": "^
|
|
23
|
-
"ember-concurrency": "^2.
|
|
23
|
+
"ember-cli-htmlbars": "^6.0.0",
|
|
24
|
+
"ember-concurrency": "^2.2.0",
|
|
24
25
|
"ember-concurrency-decorators": "^2.0.3",
|
|
25
26
|
"ember-fetch": "^8.0.4",
|
|
26
27
|
"ember-intl": "^5.7.0",
|
|
27
|
-
"graphql": "^15.6.
|
|
28
|
-
"graphql-tag": "^2.12.
|
|
28
|
+
"graphql": "^15.6.1",
|
|
29
|
+
"graphql-tag": "^2.12.6",
|
|
29
30
|
"intersection-observer": "^0.12.0",
|
|
30
31
|
"jexl": "^2.3.0",
|
|
31
32
|
"lodash.clonedeep": "^4.5.0",
|
|
32
33
|
"moment": "^2.29.1",
|
|
33
34
|
"proxy-polyfill": "^0.3.2",
|
|
34
|
-
"slugify": "^1.6.
|
|
35
|
+
"slugify": "^1.6.2"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@ember/optional-features": "2.0.0",
|
|
38
|
-
"@ember/
|
|
39
|
-
"@
|
|
40
|
-
"@
|
|
39
|
+
"@ember/render-modifiers": "2.0.0",
|
|
40
|
+
"@ember/test-helpers": "2.6.0",
|
|
41
|
+
"@embroider/test-setup": "0.47.2",
|
|
42
|
+
"@glimmer/component": "1.0.4",
|
|
43
|
+
"@projectcaluma/ember-testing": "9.1.0",
|
|
41
44
|
"broccoli-asset-rev": "3.0.0",
|
|
42
|
-
"ember-cli": "3.28.
|
|
45
|
+
"ember-cli": "3.28.4",
|
|
43
46
|
"ember-cli-code-coverage": "1.0.3",
|
|
44
47
|
"ember-cli-dependency-checker": "3.2.0",
|
|
45
48
|
"ember-cli-inject-live-reload": "2.1.0",
|
|
@@ -50,20 +53,20 @@
|
|
|
50
53
|
"ember-export-application-global": "2.0.1",
|
|
51
54
|
"ember-load-initializers": "2.1.2",
|
|
52
55
|
"ember-maybe-import-regenerator": "1.0.0",
|
|
53
|
-
"ember-qunit": "5.1.
|
|
56
|
+
"ember-qunit": "5.1.5",
|
|
54
57
|
"ember-resolver": "8.0.3",
|
|
55
|
-
"ember-source": "3.28.
|
|
58
|
+
"ember-source": "3.28.6",
|
|
56
59
|
"ember-source-channel-url": "3.0.0",
|
|
57
|
-
"ember-try": "
|
|
60
|
+
"ember-try": "2.0.0",
|
|
58
61
|
"faker": "5.5.3",
|
|
59
62
|
"loader.js": "4.7.0",
|
|
60
63
|
"npm-run-all": "4.1.5",
|
|
61
64
|
"qunit": "2.17.2",
|
|
62
65
|
"qunit-dom": "2.0.0",
|
|
63
|
-
"webpack": "5.
|
|
66
|
+
"webpack": "5.64.1"
|
|
64
67
|
},
|
|
65
68
|
"engines": {
|
|
66
|
-
"node": "
|
|
69
|
+
"node": "12.* || 14.* || >= 16"
|
|
67
70
|
},
|
|
68
71
|
"ember": {
|
|
69
72
|
"edition": "octane"
|
package/translations/de.yaml
CHANGED
package/translations/en.yaml
CHANGED