@projectcaluma/ember-form 9.1.2 → 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/components/cf-field/input/action-button.hbs +19 -0
- package/addon/components/cf-field/input/action-button.js +75 -0
- package/addon/components/cf-field/input/file.hbs +24 -13
- package/addon/components/cf-field/input/file.js +19 -9
- package/addon/components/cf-field/input/table.hbs +94 -95
- package/addon/components/cf-field/input/table.js +97 -80
- package/addon/components/cf-field/input.hbs +1 -0
- package/addon/components/cf-field/input.js +2 -1
- package/addon/components/cf-field.hbs +14 -12
- package/addon/components/cf-field.js +9 -1
- package/addon/components/document-validity.js +3 -5
- package/addon/gql/fragments/{field-question.graphql → field.graphql} +61 -0
- package/addon/gql/mutations/remove-answer.graphql +7 -0
- package/addon/gql/mutations/save-document-date-answer.graphql +2 -2
- package/addon/gql/mutations/save-document-file-answer.graphql +2 -2
- package/addon/gql/mutations/save-document-float-answer.graphql +2 -2
- package/addon/gql/mutations/save-document-integer-answer.graphql +2 -2
- package/addon/gql/mutations/save-document-list-answer.graphql +2 -2
- package/addon/gql/mutations/save-document-string-answer.graphql +2 -2
- package/addon/gql/mutations/save-document-table-answer.graphql +2 -2
- package/addon/gql/mutations/save-document.graphql +2 -2
- package/addon/gql/queries/get-document-answers.graphql +18 -2
- package/addon/gql/queries/get-document-forms.graphql +2 -2
- package/addon/gql/queries/get-dynamic-options.graphql +1 -1
- package/addon/gql/queries/get-fileanswer-info.graphql +1 -1
- package/addon/lib/document.js +17 -1
- package/addon/lib/field.js +12 -1
- package/app/components/cf-field/input/action-button.js +1 -0
- package/package.json +11 -10
- package/translations/de.yaml +3 -15
- package/translations/en.yaml +3 -15
- package/translations/fr.yaml +3 -16
- package/addon/gql/fragments/field-answer.graphql +0 -57
@@ -0,0 +1,19 @@
|
|
1
|
+
{{#unless @disabled}}
|
2
|
+
<DocumentValidity
|
3
|
+
@document={{@field.document}}
|
4
|
+
@validateOnEnter={{this.validateOnEnter}}
|
5
|
+
as |isValid validate|
|
6
|
+
>
|
7
|
+
<WorkItemButton
|
8
|
+
@workItemId={{this.workItem}}
|
9
|
+
@mutation={{this.action}}
|
10
|
+
@label={{@field.question.label}}
|
11
|
+
@disabled={{and (not-eq isValid null) (not isValid)}}
|
12
|
+
@color={{this.color}}
|
13
|
+
@beforeMutate={{fn this.beforeMutate validate}}
|
14
|
+
@onSuccess={{this.onSuccess}}
|
15
|
+
@onError={{this.onError}}
|
16
|
+
@type={{this.type}}
|
17
|
+
/>
|
18
|
+
</DocumentValidity>
|
19
|
+
{{/unless}}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import { assert } from "@ember/debug";
|
2
|
+
import { action } from "@ember/object";
|
3
|
+
import Component from "@glimmer/component";
|
4
|
+
import UIkit from "uikit";
|
5
|
+
|
6
|
+
async function confirm(text) {
|
7
|
+
try {
|
8
|
+
await UIkit.modal.confirm(text);
|
9
|
+
|
10
|
+
return true;
|
11
|
+
} catch (error) {
|
12
|
+
return false;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
export default class CfFieldInputActionButtonComponent extends Component {
|
17
|
+
constructor(...args) {
|
18
|
+
super(...args);
|
19
|
+
|
20
|
+
assert(
|
21
|
+
"The document must have a `workItemUuid` for `<CfField::Input::ActionButton />` to work.",
|
22
|
+
this.args.field.document.workItemUuid
|
23
|
+
);
|
24
|
+
}
|
25
|
+
|
26
|
+
get workItem() {
|
27
|
+
return (
|
28
|
+
this.args.context?.actionButtonWorkItemId ||
|
29
|
+
this.args.field.document.workItemUuid
|
30
|
+
);
|
31
|
+
}
|
32
|
+
|
33
|
+
get action() {
|
34
|
+
return this.args.field.question.action.toLowerCase();
|
35
|
+
}
|
36
|
+
|
37
|
+
get color() {
|
38
|
+
return this.args.field.question.color.toLowerCase();
|
39
|
+
}
|
40
|
+
|
41
|
+
get type() {
|
42
|
+
return this.args.field.question.action === "COMPLETE" ? "submit" : "button";
|
43
|
+
}
|
44
|
+
|
45
|
+
get validateOnEnter() {
|
46
|
+
return (
|
47
|
+
this.args.field.question.action === "COMPLETE" &&
|
48
|
+
this.args.field.question.validateOnEnter
|
49
|
+
);
|
50
|
+
}
|
51
|
+
|
52
|
+
@action
|
53
|
+
async beforeMutate(validateFn) {
|
54
|
+
if (
|
55
|
+
this.args.field.question.action === "COMPLETE" &&
|
56
|
+
!(await validateFn())
|
57
|
+
) {
|
58
|
+
return false;
|
59
|
+
}
|
60
|
+
|
61
|
+
const confirmText = this.args.field.question.infoText;
|
62
|
+
|
63
|
+
return !confirmText || confirm(confirmText);
|
64
|
+
}
|
65
|
+
|
66
|
+
@action
|
67
|
+
onSuccess() {
|
68
|
+
return this.args.context?.actionButtonOnSuccess?.();
|
69
|
+
}
|
70
|
+
|
71
|
+
@action
|
72
|
+
onError(error) {
|
73
|
+
return this.args.context?.actionButtonOnError?.(error);
|
74
|
+
}
|
75
|
+
}
|
@@ -1,21 +1,32 @@
|
|
1
|
-
|
2
|
-
<div
|
1
|
+
<div class="uk-flex-middle uk-grid-divider uk-grid-column-small" uk-grid>
|
2
|
+
<div uk-form-custom="target: true">
|
3
3
|
|
4
4
|
<input
|
5
5
|
type="file"
|
6
6
|
name={{@field.pk}}
|
7
7
|
id={{@field.pk}}
|
8
|
+
disabled={{@disabled}}
|
8
9
|
{{on "change" this.save}}
|
9
10
|
/>
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
<input class="uk-input" type="text" placeholder={{@placeholder}} readonly />
|
11
|
+
<UkButton @color="primary" @disabled={{@disabled}}>
|
12
|
+
{{t "caluma.form.selectFile"}}
|
13
|
+
</UkButton>
|
14
14
|
</div>
|
15
|
-
{{
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
{{#if (and this.downloadUrl this.downloadName)}}
|
16
|
+
<div>
|
17
|
+
<UkButton
|
18
|
+
data-test-download-link
|
19
|
+
@color="link"
|
20
|
+
@on-click={{this.download}}
|
21
|
+
>
|
22
|
+
{{this.downloadName}}
|
23
|
+
</UkButton>
|
24
|
+
<UkIcon
|
25
|
+
class="uk-icon-button uk-margin-small-left"
|
26
|
+
role="button"
|
27
|
+
@icon="trash"
|
28
|
+
{{on "click" this.delete}}
|
29
|
+
/>
|
30
|
+
</div>
|
31
|
+
{{/if}}
|
32
|
+
</div>
|
@@ -3,6 +3,7 @@ import { inject as service } from "@ember/service";
|
|
3
3
|
import Component from "@glimmer/component";
|
4
4
|
import { queryManager } from "ember-apollo-client";
|
5
5
|
|
6
|
+
import removeAnswerMutation from "@projectcaluma/ember-form/gql/mutations/remove-answer.graphql";
|
6
7
|
import getFileAnswerInfoQuery from "@projectcaluma/ember-form/gql/queries/get-fileanswer-info.graphql";
|
7
8
|
|
8
9
|
export default class CfFieldInputFileComponent extends Component {
|
@@ -18,14 +19,6 @@ export default class CfFieldInputFileComponent extends Component {
|
|
18
19
|
return this.args.field?.answer?.value?.name;
|
19
20
|
}
|
20
21
|
|
21
|
-
get placeholder() {
|
22
|
-
return this.intl.t(
|
23
|
-
this.args.field?.answer.value
|
24
|
-
? "caluma.form.changeFile"
|
25
|
-
: "caluma.form.selectFile"
|
26
|
-
);
|
27
|
-
}
|
28
|
-
|
29
22
|
@action
|
30
23
|
async download() {
|
31
24
|
const { downloadUrl } = await this.apollo.watchQuery(
|
@@ -74,7 +67,24 @@ export default class CfFieldInputFileComponent extends Component {
|
|
74
67
|
} finally {
|
75
68
|
// eslint-disable-next-line require-atomic-updates
|
76
69
|
target.value = "";
|
77
|
-
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
@action
|
74
|
+
async delete() {
|
75
|
+
try {
|
76
|
+
await this.apollo.mutate({
|
77
|
+
mutation: removeAnswerMutation,
|
78
|
+
variables: {
|
79
|
+
input: {
|
80
|
+
answer: this.args.field.answer.uuid,
|
81
|
+
},
|
82
|
+
},
|
83
|
+
});
|
84
|
+
|
85
|
+
await this.args.onSave(null);
|
86
|
+
} catch (error) {
|
87
|
+
set(this.args.field, "_errors", [{ type: "deleteFailed" }]);
|
78
88
|
}
|
79
89
|
}
|
80
90
|
}
|
@@ -1,125 +1,124 @@
|
|
1
|
-
|
2
|
-
<
|
3
|
-
<
|
1
|
+
<table class="uk-table uk-table-divider">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
{{#each this.columns as |column|}}
|
5
|
+
<th>{{column.label}}</th>
|
6
|
+
{{/each}}
|
7
|
+
<th></th>
|
8
|
+
</tr>
|
9
|
+
</thead>
|
10
|
+
<tbody>
|
11
|
+
{{#each @field.answer.value as |document|}}
|
4
12
|
<tr>
|
5
|
-
{{#each
|
6
|
-
<
|
13
|
+
{{#each this.columns as |column|}}
|
14
|
+
<td>
|
15
|
+
<CfFieldValue
|
16
|
+
@field={{find-by "question.slug" column.slug document.fields}}
|
17
|
+
/>
|
18
|
+
</td>
|
7
19
|
{{/each}}
|
8
|
-
<
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
{{
|
16
|
-
{{#if
|
17
|
-
(includes
|
18
|
-
answerField.answer.question.slug
|
19
|
-
field.question.meta.columnsToDisplay
|
20
|
-
)
|
21
|
-
}}
|
22
|
-
<td>{{cf-field-value field=answerField}}</td>
|
23
|
-
{{/if}}
|
24
|
-
{{/each}}
|
25
|
-
{{else}}
|
26
|
-
{{#each (take 4 document.fields) as |field|}}
|
27
|
-
<td>{{cf-field-value field=field}}</td>
|
28
|
-
{{/each}}
|
29
|
-
{{/if}}
|
30
|
-
<td class="uk-text-right">
|
20
|
+
<td class="uk-table-middle">
|
21
|
+
<div class="uk-flex uk-flex-middle uk-flex-right">
|
22
|
+
{{#if (includes false (map-by "isValid" document.fields))}}
|
23
|
+
<UkIcon
|
24
|
+
@icon="warning"
|
25
|
+
class="uk-animation-fade uk-text-danger"
|
26
|
+
/>
|
27
|
+
{{/if}}
|
31
28
|
<button
|
32
29
|
data-test-edit-row
|
33
30
|
type="button"
|
34
|
-
class="uk-
|
35
|
-
uk-icon="pencil"
|
31
|
+
class="uk-button-link uk-flex-inline uk-margin-small-left"
|
36
32
|
title={{t "caluma.form.edit"}}
|
37
|
-
{{
|
33
|
+
{{on "click" (fn this.edit document)}}
|
38
34
|
>
|
35
|
+
<UkIcon @icon="pencil" />
|
39
36
|
<span class="uk-hidden">{{t "caluma.form.edit"}}</span>
|
40
37
|
</button>
|
41
|
-
{{#unless disabled}}
|
38
|
+
{{#unless @disabled}}
|
42
39
|
<button
|
43
40
|
data-test-delete-row
|
44
41
|
type="button"
|
45
|
-
class="uk-
|
46
|
-
uk-icon="trash"
|
42
|
+
class="uk-button-link uk-flex-inline uk-margin-small-left"
|
47
43
|
title={{t "caluma.form.delete"}}
|
48
|
-
{{
|
44
|
+
{{on "click" (fn (perform this.delete) document)}}
|
49
45
|
>
|
46
|
+
<UkIcon @icon="trash" />
|
50
47
|
<span class="uk-hidden">{{t "caluma.form.delete"}}</span>
|
51
48
|
</button>
|
52
49
|
{{/unless}}
|
53
|
-
</
|
54
|
-
</
|
55
|
-
|
56
|
-
|
50
|
+
</div>
|
51
|
+
</td>
|
52
|
+
</tr>
|
53
|
+
{{/each}}
|
54
|
+
</tbody>
|
55
|
+
{{#unless @disabled}}
|
57
56
|
<tfoot>
|
58
|
-
|
59
|
-
<
|
60
|
-
<
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
</tr>
|
72
|
-
{{/unless}}
|
57
|
+
<tr>
|
58
|
+
<td colspan={{add this.columns.length 1}} class="uk-text-center">
|
59
|
+
<UkButton
|
60
|
+
@size="small"
|
61
|
+
@color="default"
|
62
|
+
@on-click={{perform this.add}}
|
63
|
+
data-test-add-row
|
64
|
+
>
|
65
|
+
<UkIcon @icon="plus" />
|
66
|
+
<span class="uk-hidden">{{t "caluma.form.addRow"}}</span>
|
67
|
+
</UkButton>
|
68
|
+
</td>
|
69
|
+
</tr>
|
73
70
|
</tfoot>
|
74
|
-
|
75
|
-
|
76
|
-
<UkModal
|
77
|
-
@visible={{and showAddModal documentToEdit}}
|
78
|
-
@on-hide={{action "closeModal" "showAddModal"}}
|
79
|
-
@btnClose={{true}}
|
80
|
-
@bgClose={{false}}
|
81
|
-
as |modal|
|
82
|
-
>
|
83
|
-
<modal.body>
|
84
|
-
{{#if documentToEdit}}
|
85
|
-
{{cf-form-wrapper
|
86
|
-
document=documentToEdit
|
87
|
-
fieldset=(object-at 0 documentToEdit.fieldsets)
|
88
|
-
disabled=disabled
|
89
|
-
}}
|
90
|
-
{{/if}}
|
91
|
-
</modal.body>
|
92
|
-
|
93
|
-
{{#unless disabled}}
|
94
|
-
<modal.footer @class="uk-text-right">
|
95
|
-
{{uk-button
|
96
|
-
label=(t "caluma.form.save")
|
97
|
-
disabled=save.isRunning
|
98
|
-
loading=save.isRunning
|
99
|
-
on-click=(perform save)
|
100
|
-
}}
|
101
|
-
</modal.footer>
|
102
|
-
{{/unless}}
|
103
|
-
</UkModal>
|
71
|
+
{{/unless}}
|
72
|
+
</table>
|
104
73
|
|
74
|
+
{{#if this.documentToEdit}}
|
105
75
|
<UkModal
|
106
|
-
@visible={{
|
107
|
-
@on-hide={{
|
108
|
-
@btnClose={{true}}
|
76
|
+
@visible={{this.showAddModal}}
|
77
|
+
@on-hide={{perform this.closeModal}}
|
109
78
|
@bgClose={{false}}
|
110
79
|
as |modal|
|
111
80
|
>
|
112
81
|
<modal.body>
|
113
|
-
|
82
|
+
<CfFormWrapper
|
83
|
+
@document={{this.documentToEdit}}
|
84
|
+
@fieldset={{object-at 0 this.documentToEdit.fieldsets}}
|
85
|
+
@disabled={{@disabled}}
|
86
|
+
/>
|
114
87
|
</modal.body>
|
115
88
|
|
116
89
|
<modal.footer @class="uk-text-right">
|
117
|
-
{{
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
90
|
+
{{#if @disabled}}
|
91
|
+
<UkButton
|
92
|
+
@label={{t "caluma.form.close"}}
|
93
|
+
@color="primary"
|
94
|
+
@on-click={{perform this.close}}
|
95
|
+
@disabled={{this.close.isRunning}}
|
96
|
+
@loading={{this.close.isRunning}}
|
97
|
+
data-test-close
|
98
|
+
/>
|
99
|
+
{{else}}
|
100
|
+
<UkButton
|
101
|
+
@label={{t "caluma.form.cancel"}}
|
102
|
+
@on-click={{perform this.close}}
|
103
|
+
@disabled={{this.close.isRunning}}
|
104
|
+
@loading={{this.close.isRunning}}
|
105
|
+
data-test-cancel
|
106
|
+
/>
|
107
|
+
<DocumentValidity
|
108
|
+
@document={{this.documentToEdit}}
|
109
|
+
as |isValid validate|
|
110
|
+
>
|
111
|
+
<UkButton
|
112
|
+
@label={{t "caluma.form.save"}}
|
113
|
+
@color="primary"
|
114
|
+
@type="submit"
|
115
|
+
@disabled={{or this.save.isRunning (not isValid)}}
|
116
|
+
@loading={{this.save.isRunning}}
|
117
|
+
@on-click={{fn (perform this.save) validate}}
|
118
|
+
data-test-save
|
119
|
+
/>
|
120
|
+
</DocumentValidity>
|
121
|
+
{{/if}}
|
123
122
|
</modal.footer>
|
124
123
|
</UkModal>
|
125
|
-
{{/
|
124
|
+
{{/if}}
|
@@ -1,49 +1,65 @@
|
|
1
1
|
import { getOwner } from "@ember/application";
|
2
|
-
import
|
3
|
-
import { computed } from "@ember/object";
|
2
|
+
import { action } from "@ember/object";
|
4
3
|
import { inject as service } from "@ember/service";
|
4
|
+
import Component from "@glimmer/component";
|
5
|
+
import { tracked } from "@glimmer/tracking";
|
5
6
|
import { queryManager } from "ember-apollo-client";
|
6
|
-
import {
|
7
|
+
import { dropTask } from "ember-concurrency-decorators";
|
8
|
+
import UIkit from "uikit";
|
7
9
|
|
8
10
|
import removeDocumentMutation from "@projectcaluma/ember-form/gql/mutations/remove-document.graphql";
|
9
11
|
import saveDocumentMutation from "@projectcaluma/ember-form/gql/mutations/save-document.graphql";
|
10
12
|
import { parseDocument } from "@projectcaluma/ember-form/lib/parsers";
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
calumaStore: service(),
|
14
|
+
async function confirm(text) {
|
15
|
+
try {
|
16
|
+
await UIkit.modal.confirm(text);
|
16
17
|
|
17
|
-
|
18
|
+
return true;
|
19
|
+
} catch (error) {
|
20
|
+
return false;
|
21
|
+
}
|
22
|
+
}
|
18
23
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
24
|
+
export default class CfFieldInputTableComponent extends Component {
|
25
|
+
@service notification;
|
26
|
+
@service intl;
|
27
|
+
@service calumaStore;
|
28
|
+
|
29
|
+
@queryManager apollo;
|
30
|
+
|
31
|
+
@tracked showAddModal = false;
|
32
|
+
@tracked documentToEdit = null;
|
33
|
+
@tracked documentToEditIsNew = false;
|
23
34
|
|
24
35
|
parseDocument(raw) {
|
25
36
|
return parseDocument(raw);
|
26
|
-
}
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
}
|
38
|
+
|
39
|
+
get questions() {
|
40
|
+
return this.args.field.question.rowForm.questions.edges.map(
|
41
|
+
(edge) => edge.node
|
42
|
+
);
|
43
|
+
}
|
44
|
+
|
45
|
+
get columns() {
|
46
|
+
const config = this.args.field.question.meta.columnsToDisplay;
|
47
|
+
|
48
|
+
if (config?.length) {
|
49
|
+
return this.questions.filter((question) =>
|
50
|
+
config.includes(question.slug)
|
51
|
+
);
|
37
52
|
}
|
38
|
-
),
|
39
53
|
|
40
|
-
|
54
|
+
return this.questions.slice(0, 4);
|
55
|
+
}
|
56
|
+
|
57
|
+
@dropTask
|
58
|
+
*add() {
|
41
59
|
const raw = yield this.apollo.mutate(
|
42
60
|
{
|
43
61
|
mutation: saveDocumentMutation,
|
44
|
-
variables: {
|
45
|
-
input: { form: this.get("field.question.rowForm.slug") },
|
46
|
-
},
|
62
|
+
variables: { input: { form: this.args.field.question.rowForm.slug } },
|
47
63
|
},
|
48
64
|
"saveDocument.document"
|
49
65
|
);
|
@@ -52,89 +68,90 @@ export default Component.extend({
|
|
52
68
|
.factoryFor("caluma-model:document")
|
53
69
|
.create({
|
54
70
|
raw: this.parseDocument(raw),
|
55
|
-
parentDocument: this.field.document,
|
71
|
+
parentDocument: this.args.field.document,
|
56
72
|
});
|
57
73
|
|
58
|
-
this.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
}).drop(),
|
74
|
+
this.documentToEditIsNew = true;
|
75
|
+
this.documentToEdit = newDocument;
|
76
|
+
this.showAddModal = true;
|
77
|
+
}
|
63
78
|
|
64
|
-
|
65
|
-
|
79
|
+
@dropTask
|
80
|
+
*delete(document) {
|
81
|
+
if (!(yield confirm(this.intl.t("caluma.form.deleteRow")))) {
|
82
|
+
return;
|
83
|
+
}
|
66
84
|
|
67
|
-
const remainingDocuments = this.field.answer.value.filter(
|
85
|
+
const remainingDocuments = this.args.field.answer.value.filter(
|
68
86
|
(doc) => doc.pk !== document.pk
|
69
87
|
);
|
70
88
|
|
71
|
-
yield this.onSave(remainingDocuments);
|
72
|
-
|
73
|
-
|
74
|
-
yield this.apollo.mutate({
|
75
|
-
mutation: removeDocumentMutation,
|
76
|
-
variables: { input: { document: document.uuid } },
|
77
|
-
});
|
78
|
-
|
79
|
-
// Remove orphand document from Caluma store.
|
80
|
-
this.calumaStore.delete(document.pk);
|
89
|
+
yield this.args.onSave(remainingDocuments);
|
90
|
+
yield this.removeOrphan(document);
|
91
|
+
}
|
81
92
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
save: task(function* () {
|
93
|
+
@dropTask
|
94
|
+
*save(validate) {
|
86
95
|
try {
|
96
|
+
if (!(yield validate())) {
|
97
|
+
return;
|
98
|
+
}
|
99
|
+
|
87
100
|
const newDocument = this.documentToEdit;
|
88
|
-
|
101
|
+
|
102
|
+
yield Promise.all(newDocument.fields.map((f) => f.validate.perform()));
|
89
103
|
|
90
104
|
if (newDocument.fields.some((field) => field.isInvalid)) {
|
91
105
|
return;
|
92
106
|
}
|
93
107
|
|
94
|
-
const rows = this.
|
108
|
+
const rows = this.args.field.answer.value ?? [];
|
95
109
|
|
96
110
|
if (!rows.find((doc) => doc.pk === newDocument.pk)) {
|
97
111
|
// add document to table
|
98
|
-
yield this.onSave([...rows, newDocument]);
|
112
|
+
yield this.args.onSave([...rows, newDocument]);
|
99
113
|
|
100
114
|
this.notification.success(
|
101
115
|
this.intl.t("caluma.form.notification.table.add.success")
|
102
116
|
);
|
103
117
|
}
|
104
118
|
|
105
|
-
this.
|
119
|
+
this.documentToEditIsNew = false;
|
120
|
+
|
121
|
+
yield this.close.perform();
|
106
122
|
} catch (e) {
|
107
|
-
// eslint-disable-next-line no-console
|
108
|
-
console.error(e);
|
109
123
|
this.notification.danger(
|
110
124
|
this.intl.t("caluma.form.notification.table.add.error")
|
111
125
|
);
|
112
126
|
}
|
113
|
-
}
|
127
|
+
}
|
114
128
|
|
115
|
-
|
116
|
-
|
129
|
+
@dropTask
|
130
|
+
*close() {
|
131
|
+
if (this.documentToEditIsNew) {
|
132
|
+
yield this.removeOrphan(this.documentToEdit);
|
117
133
|
|
118
|
-
|
119
|
-
|
134
|
+
this.documentToEditIsNew = false;
|
135
|
+
}
|
120
136
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
},
|
137
|
+
this.showAddModal = false;
|
138
|
+
this.documentToEdit = null;
|
139
|
+
}
|
125
140
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
}
|
131
|
-
}
|
141
|
+
async removeOrphan(calumaDocument) {
|
142
|
+
// Remove orphaned document from database.
|
143
|
+
await this.apollo.mutate({
|
144
|
+
mutation: removeDocumentMutation,
|
145
|
+
variables: { input: { document: calumaDocument.uuid } },
|
146
|
+
});
|
132
147
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
148
|
+
// Remove orphaned document from Caluma store.
|
149
|
+
this.calumaStore.delete(calumaDocument.pk);
|
150
|
+
}
|
151
|
+
|
152
|
+
@action
|
153
|
+
edit(document) {
|
154
|
+
this.documentToEdit = document;
|
155
|
+
this.showAddModal = true;
|
156
|
+
}
|
157
|
+
}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { dasherize } from "@ember/string";
|
1
2
|
import Component from "@glimmer/component";
|
2
3
|
|
3
4
|
const mapping = {
|
@@ -25,7 +26,7 @@ export default class CfFieldInputComponent extends Component {
|
|
25
26
|
|
26
27
|
return (
|
27
28
|
typename &&
|
28
|
-
(mapping[typename] || typename.replace(/Question$/, "")
|
29
|
+
(mapping[typename] || dasherize(typename.replace(/Question$/, "")))
|
29
30
|
);
|
30
31
|
}
|
31
32
|
}
|
@@ -16,21 +16,23 @@
|
|
16
16
|
{{/let}}
|
17
17
|
</div>
|
18
18
|
|
19
|
-
{{#if @field.question.infoText}}
|
19
|
+
{{#if (and @field.question.infoText this.infoTextVisible)}}
|
20
20
|
<CfField::info @text={{@field.question.infoText}} />
|
21
21
|
{{/if}}
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
{{#if this.saveIndicatorVisible}}
|
24
|
+
<div
|
25
|
+
class="cf-field__icon uk-padding-remove-vertical uk-flex uk-flex-middle uk-flex-center"
|
26
|
+
>
|
27
|
+
{{#if @field.save.isRunning}}
|
28
|
+
<UkSpinner class="uk-animation-fade" />
|
29
|
+
{{else if (or @field.save.last.isError @field.isInvalid)}}
|
30
|
+
<UkIcon @icon="warning" class="uk-animation-fade uk-text-danger" />
|
31
|
+
{{else if @field.save.last.isSuccessful}}
|
32
|
+
<UkIcon @icon="check" class="uk-animation-fade uk-text-success" />
|
33
|
+
{{/if}}
|
34
|
+
</div>
|
35
|
+
{{/if}}
|
34
36
|
</div>
|
35
37
|
|
36
38
|
{{#if @field.errors.length}}
|
@@ -29,10 +29,18 @@ export default class CfFieldComponent extends Component {
|
|
29
29
|
get labelVisible() {
|
30
30
|
return (
|
31
31
|
!this.args.field?.question.meta.hideLabel &&
|
32
|
-
!hasQuestionType(this.args.field?.question, "static")
|
32
|
+
!hasQuestionType(this.args.field?.question, "static", "action-button")
|
33
33
|
);
|
34
34
|
}
|
35
35
|
|
36
|
+
get infoTextVisible() {
|
37
|
+
return !hasQuestionType(this.args.field?.question, "action-button");
|
38
|
+
}
|
39
|
+
|
40
|
+
get saveIndicatorVisible() {
|
41
|
+
return !hasQuestionType(this.args.field?.question, "action-button");
|
42
|
+
}
|
43
|
+
|
36
44
|
/**
|
37
45
|
* Task to save a field. This will set the passed value to the answer and
|
38
46
|
* save the field to the API after a timeout off 500 milliseconds.
|
@@ -37,11 +37,9 @@ export default class DocumentValidity extends Component {
|
|
37
37
|
|
38
38
|
@restartableTask
|
39
39
|
*_validate() {
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
)
|
44
|
-
);
|
40
|
+
for (const field of this.args.document.fields) {
|
41
|
+
yield field.validate.linked().perform();
|
42
|
+
}
|
45
43
|
|
46
44
|
if (this.isValid) {
|
47
45
|
this.args.onValid?.();
|
@@ -76,6 +76,11 @@ fragment SimpleQuestion on Question {
|
|
76
76
|
... on CalculatedFloatQuestion {
|
77
77
|
calcExpression
|
78
78
|
}
|
79
|
+
... on ActionButtonQuestion {
|
80
|
+
action
|
81
|
+
color
|
82
|
+
validateOnEnter
|
83
|
+
}
|
79
84
|
}
|
80
85
|
|
81
86
|
fragment FieldTableQuestion on Question {
|
@@ -157,3 +162,59 @@ fragment FieldQuestion on Question {
|
|
157
162
|
}
|
158
163
|
}
|
159
164
|
}
|
165
|
+
|
166
|
+
fragment SimpleAnswer on Answer {
|
167
|
+
id
|
168
|
+
question {
|
169
|
+
slug
|
170
|
+
}
|
171
|
+
... on StringAnswer {
|
172
|
+
stringValue: value
|
173
|
+
}
|
174
|
+
... on IntegerAnswer {
|
175
|
+
integerValue: value
|
176
|
+
}
|
177
|
+
... on FloatAnswer {
|
178
|
+
floatValue: value
|
179
|
+
}
|
180
|
+
... on ListAnswer {
|
181
|
+
listValue: value
|
182
|
+
}
|
183
|
+
... on FileAnswer {
|
184
|
+
fileValue: value {
|
185
|
+
uploadUrl
|
186
|
+
downloadUrl
|
187
|
+
metadata
|
188
|
+
name
|
189
|
+
}
|
190
|
+
}
|
191
|
+
... on DateAnswer {
|
192
|
+
dateValue: value
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
fragment FieldAnswer on Answer {
|
197
|
+
...SimpleAnswer
|
198
|
+
... on TableAnswer {
|
199
|
+
tableValue: value {
|
200
|
+
id
|
201
|
+
form {
|
202
|
+
slug
|
203
|
+
questions {
|
204
|
+
edges {
|
205
|
+
node {
|
206
|
+
...FieldQuestion
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
210
|
+
}
|
211
|
+
answers {
|
212
|
+
edges {
|
213
|
+
node {
|
214
|
+
...SimpleAnswer
|
215
|
+
}
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
219
|
+
}
|
220
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
mutation ($input: SaveDocumentDateAnswerInput!) {
|
3
|
+
mutation SaveDocumentDateAnswer($input: SaveDocumentDateAnswerInput!) {
|
4
4
|
saveDocumentDateAnswer(input: $input) {
|
5
5
|
answer {
|
6
6
|
...FieldAnswer
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
mutation ($input: SaveDocumentFileAnswerInput!) {
|
3
|
+
mutation SaveDocumentFileAnswer($input: SaveDocumentFileAnswerInput!) {
|
4
4
|
saveDocumentFileAnswer(input: $input) {
|
5
5
|
answer {
|
6
6
|
...FieldAnswer
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
mutation ($input: SaveDocumentFloatAnswerInput!) {
|
3
|
+
mutation SaveDocumentFloatAnswer($input: SaveDocumentFloatAnswerInput!) {
|
4
4
|
saveDocumentFloatAnswer(input: $input) {
|
5
5
|
answer {
|
6
6
|
...FieldAnswer
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
mutation ($input: SaveDocumentIntegerAnswerInput!) {
|
3
|
+
mutation SaveDocumentIntegerAnswer($input: SaveDocumentIntegerAnswerInput!) {
|
4
4
|
saveDocumentIntegerAnswer(input: $input) {
|
5
5
|
answer {
|
6
6
|
...FieldAnswer
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
mutation ($input: SaveDocumentListAnswerInput!) {
|
3
|
+
mutation SaveDocumentListAnswer($input: SaveDocumentListAnswerInput!) {
|
4
4
|
saveDocumentListAnswer(input: $input) {
|
5
5
|
answer {
|
6
6
|
...FieldAnswer
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
mutation ($input: SaveDocumentStringAnswerInput!) {
|
3
|
+
mutation SaveDocumentStringAnswer($input: SaveDocumentStringAnswerInput!) {
|
4
4
|
saveDocumentStringAnswer(input: $input) {
|
5
5
|
answer {
|
6
6
|
...FieldAnswer
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
mutation ($input: SaveDocumentTableAnswerInput!) {
|
3
|
+
mutation saveDocumentTableAnswer($input: SaveDocumentTableAnswerInput!) {
|
4
4
|
saveDocumentTableAnswer(input: $input) {
|
5
5
|
answer {
|
6
6
|
...FieldAnswer
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
mutation ($input: SaveDocumentInput!) {
|
3
|
+
mutation SaveDocument($input: SaveDocumentInput!) {
|
4
4
|
saveDocument(input: $input) {
|
5
5
|
document {
|
6
6
|
id
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import * from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
query ($id: ID!) {
|
3
|
+
query GetDocumentAnswers($id: ID!) {
|
4
4
|
allDocuments(filter: [{ id: $id }]) {
|
5
5
|
edges {
|
6
6
|
node {
|
@@ -8,6 +8,22 @@ query ($id: ID!) {
|
|
8
8
|
form {
|
9
9
|
slug
|
10
10
|
}
|
11
|
+
workItem {
|
12
|
+
id
|
13
|
+
}
|
14
|
+
case {
|
15
|
+
id
|
16
|
+
workItems {
|
17
|
+
edges {
|
18
|
+
node {
|
19
|
+
id
|
20
|
+
task {
|
21
|
+
id
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
11
27
|
answers {
|
12
28
|
edges {
|
13
29
|
node {
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#import FieldQuestion, FieldTableQuestion, SimpleQuestion from '../fragments/field.graphql'
|
2
2
|
|
3
|
-
query ($slug: String!) {
|
3
|
+
query GetDocumentForms($slug: String!) {
|
4
4
|
allForms(filter: [{ slug: $slug }]) {
|
5
5
|
edges {
|
6
6
|
node {
|
package/addon/lib/document.js
CHANGED
@@ -83,6 +83,22 @@ export default Base.extend({
|
|
83
83
|
return decodeId(this.raw.id);
|
84
84
|
}),
|
85
85
|
|
86
|
+
workItemUuid: computed(
|
87
|
+
"raw.{workItem.id,case.workItems.edges.[]}",
|
88
|
+
function () {
|
89
|
+
// The document is either directly attached to a work item (via
|
90
|
+
// CompleteTaskFormTask) or it's the case document and therefore
|
91
|
+
// indirectly attached to a work item (via CompleteWorkflowFormTask)
|
92
|
+
const rawId =
|
93
|
+
this.raw.workItem?.id ||
|
94
|
+
this.raw.case?.workItems.edges.find(
|
95
|
+
(edge) => edge.node.task.__typename === "CompleteWorkflowFormTask"
|
96
|
+
)?.node.id;
|
97
|
+
|
98
|
+
return rawId ? decodeId(rawId) : null;
|
99
|
+
}
|
100
|
+
),
|
101
|
+
|
86
102
|
/**
|
87
103
|
* The root form of this document
|
88
104
|
*
|
@@ -230,7 +246,7 @@ export default Base.extend({
|
|
230
246
|
}
|
231
247
|
|
232
248
|
if (field.hidden || [undefined, null].includes(field.value)) {
|
233
|
-
return field.question.isMultipleChoice ? [] : null;
|
249
|
+
return defaultValue ?? field.question.isMultipleChoice ? [] : null;
|
234
250
|
}
|
235
251
|
|
236
252
|
if (field.question.__typename === "TableQuestion") {
|
package/addon/lib/field.js
CHANGED
@@ -564,7 +564,7 @@ export default Base.extend({
|
|
564
564
|
"fieldset.field.hidden",
|
565
565
|
"jexlContext",
|
566
566
|
"optionalDependencies.@each.{hidden,value}",
|
567
|
-
"question.isRequired",
|
567
|
+
"question.{__typename,isRequired}",
|
568
568
|
"pk",
|
569
569
|
function () {
|
570
570
|
if (
|
@@ -936,4 +936,15 @@ export default Base.extend({
|
|
936
936
|
_validateCalculatedFloatQuestion() {
|
937
937
|
return resolve(true);
|
938
938
|
},
|
939
|
+
|
940
|
+
/**
|
941
|
+
* Dummy method for the validation of work item button fields
|
942
|
+
*
|
943
|
+
* @method _validateActionButtonQuestion
|
944
|
+
* @return {RSVP.Promise}
|
945
|
+
* @private
|
946
|
+
*/
|
947
|
+
_validateActionButtonQuestion() {
|
948
|
+
return resolve(true);
|
949
|
+
},
|
939
950
|
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from "@projectcaluma/ember-form/components/cf-field/input/action-button";
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@projectcaluma/ember-form",
|
3
|
-
"version": "
|
3
|
+
"version": "10.0.1",
|
4
4
|
"description": "Ember addon for rendering Caluma forms.",
|
5
5
|
"keywords": [
|
6
6
|
"ember-addon"
|
@@ -16,7 +16,7 @@
|
|
16
16
|
"dependencies": {
|
17
17
|
"@glimmer/component": "^1.0.4",
|
18
18
|
"@glimmer/tracking": "^1.0.4",
|
19
|
-
"@projectcaluma/ember-core": "
|
19
|
+
"@projectcaluma/ember-core": "^10.0.1",
|
20
20
|
"ember-apollo-client": "^3.2.0",
|
21
21
|
"ember-auto-import": "^2.2.3",
|
22
22
|
"ember-cli-babel": "^7.26.6",
|
@@ -26,9 +26,9 @@
|
|
26
26
|
"ember-fetch": "^8.0.4",
|
27
27
|
"ember-in-viewport": "^3.10.3",
|
28
28
|
"ember-intl": "^5.7.0",
|
29
|
-
"ember-math-helpers": "^2.
|
29
|
+
"ember-math-helpers": "^2.18.0",
|
30
30
|
"ember-pikaday": "^3.0.0",
|
31
|
-
"ember-power-select": "^4.1.
|
31
|
+
"ember-power-select": "^4.1.7",
|
32
32
|
"ember-uikit": "^4.0.0",
|
33
33
|
"graphql": "^15.6.1",
|
34
34
|
"jexl": "^2.3.0",
|
@@ -39,10 +39,11 @@
|
|
39
39
|
"devDependencies": {
|
40
40
|
"@ember/optional-features": "2.0.0",
|
41
41
|
"@ember/test-helpers": "2.6.0",
|
42
|
-
"@embroider/test-setup": "0.47.
|
43
|
-
"@projectcaluma/ember-testing": "9.
|
42
|
+
"@embroider/test-setup": "0.47.2",
|
43
|
+
"@projectcaluma/ember-testing": "9.1.0",
|
44
|
+
"@projectcaluma/ember-workflow": "10.0.0",
|
44
45
|
"broccoli-asset-rev": "3.0.0",
|
45
|
-
"ember-cli": "3.28.
|
46
|
+
"ember-cli": "3.28.4",
|
46
47
|
"ember-cli-code-coverage": "1.0.3",
|
47
48
|
"ember-cli-dependency-checker": "3.2.0",
|
48
49
|
"ember-cli-inject-live-reload": "2.1.0",
|
@@ -57,17 +58,17 @@
|
|
57
58
|
"ember-resolver": "8.0.3",
|
58
59
|
"ember-source": "3.28.6",
|
59
60
|
"ember-source-channel-url": "3.0.0",
|
60
|
-
"ember-try": "
|
61
|
+
"ember-try": "2.0.0",
|
61
62
|
"faker": "5.5.3",
|
62
63
|
"loader.js": "4.7.0",
|
63
64
|
"npm-run-all": "4.1.5",
|
64
65
|
"qunit": "2.17.2",
|
65
66
|
"qunit-dom": "2.0.0",
|
66
67
|
"uuid": "8.3.2",
|
67
|
-
"webpack": "5.
|
68
|
+
"webpack": "5.64.1"
|
68
69
|
},
|
69
70
|
"engines": {
|
70
|
-
"node": "
|
71
|
+
"node": "12.* || 14.* || >= 16"
|
71
72
|
},
|
72
73
|
"ember": {
|
73
74
|
"edition": "octane"
|
package/translations/de.yaml
CHANGED
@@ -1,24 +1,12 @@
|
|
1
1
|
caluma:
|
2
|
-
caluma-query:
|
3
|
-
work-item:
|
4
|
-
status:
|
5
|
-
READY: "Offen"
|
6
|
-
COMPLETED: "Erledigt"
|
7
|
-
CANCELED: "Abgebrochen"
|
8
|
-
SKIPPED: "Übersprungen"
|
9
|
-
|
10
|
-
case:
|
11
|
-
status:
|
12
|
-
RUNNING: "In Bearbeitung"
|
13
|
-
COMPLETED: "Abgeschlossen"
|
14
|
-
CANCELED: "Abgebrochen"
|
15
2
|
form:
|
16
3
|
optional: "Optional"
|
17
4
|
save: "Speichern"
|
18
5
|
delete: "Löschen"
|
19
6
|
edit: "Bearbeiten"
|
20
|
-
|
21
|
-
|
7
|
+
cancel: "Abbrechen"
|
8
|
+
close: "Schliessen"
|
9
|
+
selectFile: "Durchsuchen..."
|
22
10
|
deleteRow: "Möchten Sie diese Zeile wirklich löschen?"
|
23
11
|
addRow: "Zeile hinzufügen"
|
24
12
|
optionNotAvailable: "Diese Option ist nicht mehr verfügbar"
|
package/translations/en.yaml
CHANGED
@@ -1,24 +1,12 @@
|
|
1
1
|
caluma:
|
2
|
-
caluma-query:
|
3
|
-
work-item:
|
4
|
-
status:
|
5
|
-
READY: "Pending"
|
6
|
-
COMPLETED: "Completed"
|
7
|
-
CANCELED: "Canceled"
|
8
|
-
SKIPPED: "Skipped"
|
9
|
-
case:
|
10
|
-
status:
|
11
|
-
RUNNING: "Pending"
|
12
|
-
COMPLETED: "Completed"
|
13
|
-
CANCELED: "Canceled"
|
14
|
-
|
15
2
|
form:
|
16
3
|
optional: "Optional"
|
17
4
|
save: "Save"
|
18
5
|
delete: "Delete"
|
19
6
|
edit: "Edit"
|
20
|
-
|
21
|
-
|
7
|
+
cancel: "Cancel"
|
8
|
+
close: "Close"
|
9
|
+
selectFile: "Browse..."
|
22
10
|
deleteRow: "Do you really want to delete this row?"
|
23
11
|
addRow: "Add row"
|
24
12
|
optionNotAvailable: "This option is not available anymore"
|
package/translations/fr.yaml
CHANGED
@@ -1,25 +1,12 @@
|
|
1
1
|
caluma:
|
2
|
-
caluma-query:
|
3
|
-
work-item:
|
4
|
-
status:
|
5
|
-
READY: "En attente"
|
6
|
-
COMPLETED: "Terminé"
|
7
|
-
CANCELED: "Annulé"
|
8
|
-
SKIPPED: "Sauté"
|
9
|
-
|
10
|
-
case:
|
11
|
-
status:
|
12
|
-
RUNNING: "En cours"
|
13
|
-
COMPLETED: "Terminé"
|
14
|
-
CANCELED: "Annulé"
|
15
|
-
|
16
2
|
form:
|
17
3
|
optional: "optional"
|
18
4
|
save: "sauvegarder"
|
19
5
|
delete: "supprimer"
|
20
6
|
edit: "modifier"
|
21
|
-
|
22
|
-
|
7
|
+
cancel: "annuler"
|
8
|
+
close: "fermer"
|
9
|
+
selectFile: "Sélectionner..."
|
23
10
|
deleteRow: "Voulez-vous supprimer cette ligne?"
|
24
11
|
addRow: "Ajouter une ligne"
|
25
12
|
optionNotAvailable: "Cette option n'est plus disponible"
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# import * from '@projectcaluma/ember-form/gql/fragments/field-question.graphql'
|
2
|
-
|
3
|
-
fragment SimpleAnswer on Answer {
|
4
|
-
id
|
5
|
-
question {
|
6
|
-
slug
|
7
|
-
}
|
8
|
-
... on StringAnswer {
|
9
|
-
stringValue: value
|
10
|
-
}
|
11
|
-
... on IntegerAnswer {
|
12
|
-
integerValue: value
|
13
|
-
}
|
14
|
-
... on FloatAnswer {
|
15
|
-
floatValue: value
|
16
|
-
}
|
17
|
-
... on ListAnswer {
|
18
|
-
listValue: value
|
19
|
-
}
|
20
|
-
... on FileAnswer {
|
21
|
-
fileValue: value {
|
22
|
-
uploadUrl
|
23
|
-
downloadUrl
|
24
|
-
metadata
|
25
|
-
name
|
26
|
-
}
|
27
|
-
}
|
28
|
-
... on DateAnswer {
|
29
|
-
dateValue: value
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|
33
|
-
fragment FieldAnswer on Answer {
|
34
|
-
...SimpleAnswer
|
35
|
-
... on TableAnswer {
|
36
|
-
tableValue: value {
|
37
|
-
id
|
38
|
-
form {
|
39
|
-
slug
|
40
|
-
questions {
|
41
|
-
edges {
|
42
|
-
node {
|
43
|
-
...FieldQuestion
|
44
|
-
}
|
45
|
-
}
|
46
|
-
}
|
47
|
-
}
|
48
|
-
answers {
|
49
|
-
edges {
|
50
|
-
node {
|
51
|
-
...SimpleAnswer
|
52
|
-
}
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}
|
57
|
-
}
|