@projectcaluma/ember-form 11.0.0-beta.1 → 11.0.0-beta.12
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +1201 -0
- package/addon/components/cf-content.hbs +37 -37
- package/addon/components/cf-content.js +1 -9
- package/addon/components/cf-field/info.hbs +2 -2
- package/addon/components/cf-field/info.js +0 -15
- package/addon/components/cf-field/input/action-button.hbs +17 -19
- package/addon/components/cf-field/input/action-button.js +0 -6
- package/addon/components/cf-field/input/checkbox.hbs +5 -1
- package/addon/components/cf-field/input/date.hbs +9 -5
- package/addon/components/cf-field/input/date.js +31 -10
- package/addon/components/cf-field/input/file.hbs +2 -2
- package/addon/components/cf-field/input/file.js +2 -2
- package/addon/components/cf-field/input/radio.hbs +4 -1
- package/addon/components/cf-field/input/static.hbs +1 -1
- package/addon/components/cf-field/input/table.hbs +24 -24
- package/addon/components/cf-field/input/textarea.hbs +1 -0
- package/addon/components/cf-field/input.hbs +10 -1
- package/addon/components/cf-field-value.hbs +22 -7
- package/addon/components/cf-field-value.js +8 -33
- package/addon/components/cf-field.hbs +12 -4
- package/addon/components/cf-field.js +20 -5
- package/addon/components/cf-navigation.hbs +4 -1
- package/addon/components/document-validity.js +16 -1
- package/addon/gql/fragments/field.graphql +18 -0
- package/addon/lib/field.js +47 -13
- package/addon/lib/navigation.js +28 -15
- package/addon/modifiers/autoresize.js +16 -0
- package/app/modifiers/autoresize.js +1 -0
- package/blueprints/@projectcaluma/ember-form/index.js +1 -0
- package/package.json +21 -17
- package/addon/components/cf-navigation.js +0 -9
- package/addon/instance-initializers/setup-pikaday-i18n.js +0 -35
@@ -1,41 +1,41 @@
|
|
1
|
-
{{#if
|
2
|
-
{{
|
3
|
-
|
4
|
-
{{
|
5
|
-
|
6
|
-
|
1
|
+
{{#if this.loading}}
|
2
|
+
<div class="uk-text-center"><UkSpinner @ratio={{2}} /></div>
|
3
|
+
{{else if this.document}}
|
4
|
+
{{#let
|
5
|
+
(hash
|
6
|
+
document=this.document
|
7
|
+
navigation=(component
|
8
|
+
"cf-navigation"
|
9
|
+
navigation=this.navigation
|
10
|
+
useAsHeading=(or @useAsHeading false)
|
11
|
+
headingBaseLevel=(or @headingBaseLevel 1)
|
12
|
+
)
|
13
|
+
pagination=(component "cf-pagination" navigation=this.navigation)
|
14
|
+
form=(component
|
15
|
+
"cf-form-wrapper"
|
7
16
|
document=this.document
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
useAsHeading=(or @useAsHeading false)
|
12
|
-
headingBaseLevel=(or @headingBaseLevel 1)
|
13
|
-
)
|
14
|
-
pagination=(component "cf-pagination" navigation=this.navigation)
|
15
|
-
form=(component
|
16
|
-
"cf-form-wrapper"
|
17
|
-
document=this.document
|
18
|
-
fieldset=this.fieldset
|
19
|
-
context=@context
|
20
|
-
disabled=@disabled
|
21
|
-
)
|
17
|
+
fieldset=this.fieldset
|
18
|
+
context=@context
|
19
|
+
disabled=@disabled
|
22
20
|
)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
{{
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
21
|
+
)
|
22
|
+
as |content|
|
23
|
+
}}
|
24
|
+
{{#if (has-block)}}
|
25
|
+
{{yield content}}
|
26
|
+
{{else if (gt this.document.fieldsets.length 1)}}
|
27
|
+
<div uk-grid>
|
28
|
+
<div class="uk-width-1-1 uk-width-1-3@m"><content.navigation /></div>
|
29
|
+
<div class="uk-width-1-1 uk-width-2-3@m">
|
30
|
+
<content.form />
|
31
|
+
<hr />
|
32
|
+
<content.pagination />
|
35
33
|
</div>
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
{{/
|
40
|
-
{{/
|
34
|
+
</div>
|
35
|
+
{{else}}
|
36
|
+
<content.form />
|
37
|
+
{{/if}}
|
38
|
+
{{/let}}
|
39
|
+
{{else}}
|
40
|
+
{{yield to="notfound"}}
|
41
41
|
{{/if}}
|
@@ -120,17 +120,9 @@ export default class CfContentComponent extends Component {
|
|
120
120
|
this.router.currentRoute?.queryParams.displayedForm ||
|
121
121
|
this.document?.raw.form.slug;
|
122
122
|
|
123
|
-
|
123
|
+
return this.document.fieldsets.find(
|
124
124
|
(fieldset) => fieldset.form.slug === slug
|
125
125
|
);
|
126
|
-
|
127
|
-
if (!fieldset) {
|
128
|
-
this.router.replaceWith({
|
129
|
-
queryParams: { displayedForm: "" },
|
130
|
-
});
|
131
|
-
}
|
132
|
-
|
133
|
-
return fieldset;
|
134
126
|
}
|
135
127
|
|
136
128
|
data = useTask(this, this.fetchData, () => [this.args.documentId]);
|
@@ -4,7 +4,7 @@
|
|
4
4
|
class="uk-icon-button"
|
5
5
|
uk-icon="info"
|
6
6
|
title={{t "caluma.form.info"}}
|
7
|
-
{{on "click" this.
|
7
|
+
{{on "click" (fn (mut this.modalVisible) true)}}
|
8
8
|
>
|
9
9
|
<span class="uk-hidden">{{t "caluma.form.info"}}</span>
|
10
10
|
</button>
|
@@ -12,7 +12,7 @@
|
|
12
12
|
<UkModal
|
13
13
|
@visible={{this.modalVisible}}
|
14
14
|
@stack={{true}}
|
15
|
-
@
|
15
|
+
@onHide={{fn (mut this.modalVisible) false}}
|
16
16
|
as |modal|
|
17
17
|
>
|
18
18
|
<modal.body>
|
@@ -1,21 +1,6 @@
|
|
1
|
-
import { action } from "@ember/object";
|
2
1
|
import Component from "@glimmer/component";
|
3
2
|
import { tracked } from "@glimmer/tracking";
|
4
3
|
|
5
4
|
export default class CfFieldInfoComponent extends Component {
|
6
5
|
@tracked modalVisible = false;
|
7
|
-
|
8
|
-
@action
|
9
|
-
showModal(e) {
|
10
|
-
e.preventDefault();
|
11
|
-
|
12
|
-
this.modalVisible = true;
|
13
|
-
}
|
14
|
-
|
15
|
-
@action
|
16
|
-
hideModal(e) {
|
17
|
-
e.preventDefault();
|
18
|
-
|
19
|
-
this.modalVisible = false;
|
20
|
-
}
|
21
6
|
}
|
@@ -1,19 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
</DocumentValidity>
|
19
|
-
{{/unless}}
|
1
|
+
<DocumentValidity
|
2
|
+
@document={{@field.document}}
|
3
|
+
@validateOnEnter={{this.validateOnEnter}}
|
4
|
+
as |isValid validate|
|
5
|
+
>
|
6
|
+
<WorkItemButton
|
7
|
+
@workItemId={{this.workItem}}
|
8
|
+
@mutation={{this.action}}
|
9
|
+
@label={{@field.question.raw.label}}
|
10
|
+
@disabled={{or (and (not-eq isValid null) (not isValid)) @disabled}}
|
11
|
+
@color={{this.color}}
|
12
|
+
@beforeMutate={{fn this.beforeMutate validate}}
|
13
|
+
@onSuccess={{this.onSuccess}}
|
14
|
+
@onError={{this.onError}}
|
15
|
+
class={{if @disabled "uk-hidden"}}
|
16
|
+
/>
|
17
|
+
</DocumentValidity>
|
@@ -38,12 +38,6 @@ export default class CfFieldInputActionButtonComponent extends Component {
|
|
38
38
|
return this.args.field.question.raw.color.toLowerCase();
|
39
39
|
}
|
40
40
|
|
41
|
-
get type() {
|
42
|
-
return this.args.field.question.raw.action === "COMPLETE"
|
43
|
-
? "submit"
|
44
|
-
: "button";
|
45
|
-
}
|
46
|
-
|
47
41
|
get validateOnEnter() {
|
48
42
|
return (
|
49
43
|
this.args.field.question.raw.action === "COMPLETE" &&
|
@@ -1,6 +1,10 @@
|
|
1
1
|
{{#each @field.options as |option i|}}
|
2
2
|
{{#if (gt i 0)}}<br />{{/if}}
|
3
|
-
<label
|
3
|
+
<label
|
4
|
+
class="cf-checkbox_label
|
5
|
+
{{if @field.isInvalid 'uk-form-danger'}}
|
6
|
+
{{if @field.raw.question.meta.vertical 'uk-margin-large-right'}}"
|
7
|
+
>
|
4
8
|
<input
|
5
9
|
class="uk-checkbox uk-margin-small-right"
|
6
10
|
type="checkbox"
|
@@ -13,13 +13,17 @@
|
|
13
13
|
readonly
|
14
14
|
/>
|
15
15
|
{{else}}
|
16
|
-
<
|
16
|
+
<input
|
17
17
|
class="uk-input"
|
18
|
+
type="text"
|
18
19
|
name={{@field.pk}}
|
19
20
|
id={{@field.pk}}
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
{{pikaday
|
22
|
+
firstDay=1
|
23
|
+
toString=this.formatDate
|
24
|
+
i18n=this.pikadayTranslations
|
25
|
+
value=@field.answer.value
|
26
|
+
onSelect=this.onChange
|
27
|
+
}}
|
24
28
|
/>
|
25
29
|
{{/if}}
|
@@ -1,19 +1,40 @@
|
|
1
1
|
import { action } from "@ember/object";
|
2
|
+
import { inject as service } from "@ember/service";
|
2
3
|
import Component from "@glimmer/component";
|
3
|
-
import
|
4
|
+
import { DateTime, Info } from "luxon";
|
5
|
+
import { cached } from "tracked-toolbox";
|
6
|
+
|
7
|
+
// put the last element to the front of the array
|
8
|
+
const shift = (array) => [...array.slice(-1), ...array.slice(0, -1)];
|
4
9
|
|
5
10
|
export default class CfFieldInputDateComponent extends Component {
|
11
|
+
@service intl;
|
12
|
+
|
6
13
|
@action
|
7
14
|
onChange(date) {
|
8
15
|
// Change Javascript date to ISO string if not null.
|
9
|
-
this.args.onSave(
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
this.args.onSave(date ? DateTime.fromJSDate(date).toISODate() : null);
|
17
|
+
}
|
18
|
+
|
19
|
+
@action
|
20
|
+
formatDate(date) {
|
21
|
+
return this.intl.formatDate(date, {
|
22
|
+
day: "2-digit",
|
23
|
+
month: "2-digit",
|
24
|
+
year: "numeric",
|
25
|
+
});
|
26
|
+
}
|
27
|
+
|
28
|
+
@cached
|
29
|
+
get pikadayTranslations() {
|
30
|
+
const locale = this.intl.primaryLocale;
|
31
|
+
|
32
|
+
return {
|
33
|
+
previousMonth: this.intl.t("caluma.form.pikaday.month-previous"),
|
34
|
+
nextMonth: this.intl.t("caluma.form.pikaday.month-next"),
|
35
|
+
months: Info.months("long", { locale }),
|
36
|
+
weekdays: shift(Info.weekdays("long", { locale })),
|
37
|
+
weekdaysShort: shift(Info.weekdays("short", { locale })),
|
38
|
+
};
|
18
39
|
}
|
19
40
|
}
|
@@ -8,7 +8,7 @@
|
|
8
8
|
disabled={{@disabled}}
|
9
9
|
{{on "change" this.save}}
|
10
10
|
/>
|
11
|
-
<UkButton
|
11
|
+
<UkButton disabled={{@disabled}}>
|
12
12
|
{{t "caluma.form.selectFile"}}
|
13
13
|
</UkButton>
|
14
14
|
</div>
|
@@ -17,7 +17,7 @@
|
|
17
17
|
<UkButton
|
18
18
|
data-test-download-link
|
19
19
|
@color="link"
|
20
|
-
@
|
20
|
+
@onClick={{this.download}}
|
21
21
|
>
|
22
22
|
{{this.downloadName}}
|
23
23
|
</UkButton>
|
@@ -22,11 +22,11 @@ export default class CfFieldInputFileComponent extends Component {
|
|
22
22
|
|
23
23
|
@action
|
24
24
|
async download() {
|
25
|
-
const { downloadUrl } = await this.apollo.
|
25
|
+
const { downloadUrl } = await this.apollo.query(
|
26
26
|
{
|
27
27
|
query: getFileAnswerInfoQuery,
|
28
28
|
variables: { id: this.args.field.answer.raw.id },
|
29
|
-
fetchPolicy: "
|
29
|
+
fetchPolicy: "network-only",
|
30
30
|
},
|
31
31
|
"node.fileValue"
|
32
32
|
);
|
@@ -1,6 +1,9 @@
|
|
1
1
|
{{#each @field.options as |option i|}}
|
2
2
|
{{#if (gt i 0)}}<br />{{/if}}
|
3
|
-
<label
|
3
|
+
<label
|
4
|
+
class="{{if @field.isInvalid 'uk-form-danger'}}
|
5
|
+
{{if @field.raw.question.meta.vertical 'uk-margin-large-right'}}"
|
6
|
+
>
|
4
7
|
<input
|
5
8
|
class="uk-radio uk-margin-small-right"
|
6
9
|
type="radio"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<table class="uk-table uk-table-divider">
|
1
|
+
<table class="uk-table uk-table-divider uk-margin-remove-vertical">
|
2
2
|
<thead>
|
3
3
|
<tr>
|
4
4
|
{{#each this.columns as |column|}}
|
@@ -25,27 +25,27 @@
|
|
25
25
|
class="uk-animation-fade uk-text-danger"
|
26
26
|
/>
|
27
27
|
{{/if}}
|
28
|
-
<
|
29
|
-
|
30
|
-
|
31
|
-
class="uk-button-link uk-flex-inline uk-margin-small-left"
|
28
|
+
<UkButton
|
29
|
+
@color="link"
|
30
|
+
@onClick={{fn this.edit document}}
|
32
31
|
title={{t "caluma.form.edit"}}
|
33
|
-
|
32
|
+
class="uk-flex-inline uk-margin-small-left"
|
33
|
+
data-test-edit-row
|
34
34
|
>
|
35
35
|
<UkIcon @icon="pencil" />
|
36
|
-
<span
|
37
|
-
</
|
36
|
+
<span hidden>{{t "caluma.form.edit"}}</span>
|
37
|
+
</UkButton>
|
38
38
|
{{#unless @disabled}}
|
39
|
-
<
|
40
|
-
|
41
|
-
|
42
|
-
class="uk-button-link uk-flex-inline uk-margin-small-left"
|
39
|
+
<UkButton
|
40
|
+
@color="link"
|
41
|
+
@onClick={{fn (perform this.delete) document}}
|
43
42
|
title={{t "caluma.form.delete"}}
|
44
|
-
|
43
|
+
class="uk-flex-inline uk-margin-small-left"
|
44
|
+
data-test-delete-row
|
45
45
|
>
|
46
46
|
<UkIcon @icon="trash" />
|
47
|
-
<span
|
48
|
-
</
|
47
|
+
<span hidden>{{t "caluma.form.delete"}}</span>
|
48
|
+
</UkButton>
|
49
49
|
{{/unless}}
|
50
50
|
</div>
|
51
51
|
</td>
|
@@ -57,13 +57,13 @@
|
|
57
57
|
<tr>
|
58
58
|
<td colspan={{add this.columns.length 1}} class="uk-text-center">
|
59
59
|
<UkButton
|
60
|
-
@
|
61
|
-
@
|
62
|
-
|
60
|
+
@color="link"
|
61
|
+
@onClick={{perform this.add}}
|
62
|
+
title={{t "caluma.form.addRow"}}
|
63
63
|
data-test-add-row
|
64
64
|
>
|
65
65
|
<UkIcon @icon="plus" />
|
66
|
-
<span
|
66
|
+
<span hidden>{{t "caluma.form.addRow"}}</span>
|
67
67
|
</UkButton>
|
68
68
|
</td>
|
69
69
|
</tr>
|
@@ -74,7 +74,7 @@
|
|
74
74
|
{{#if this.documentToEdit}}
|
75
75
|
<UkModal
|
76
76
|
@visible={{this.showAddModal}}
|
77
|
-
@
|
77
|
+
@onHide={{perform this.close}}
|
78
78
|
@bgClose={{false}}
|
79
79
|
as |modal|
|
80
80
|
>
|
@@ -86,12 +86,12 @@
|
|
86
86
|
/>
|
87
87
|
</modal.body>
|
88
88
|
|
89
|
-
<modal.footer
|
89
|
+
<modal.footer class="uk-text-right">
|
90
90
|
{{#if @disabled}}
|
91
91
|
<UkButton
|
92
92
|
@label={{t "caluma.form.close"}}
|
93
93
|
@color="primary"
|
94
|
-
@
|
94
|
+
@onClick={{perform this.close}}
|
95
95
|
@disabled={{this.close.isRunning}}
|
96
96
|
@loading={{this.close.isRunning}}
|
97
97
|
data-test-close
|
@@ -99,7 +99,7 @@
|
|
99
99
|
{{else}}
|
100
100
|
<UkButton
|
101
101
|
@label={{t "caluma.form.cancel"}}
|
102
|
-
@
|
102
|
+
@onClick={{perform this.close}}
|
103
103
|
@disabled={{this.close.isRunning}}
|
104
104
|
@loading={{this.close.isRunning}}
|
105
105
|
data-test-cancel
|
@@ -114,7 +114,7 @@
|
|
114
114
|
@type="submit"
|
115
115
|
@disabled={{or this.save.isRunning (not isValid)}}
|
116
116
|
@loading={{this.save.isRunning}}
|
117
|
-
@
|
117
|
+
@onClick={{fn (perform this.save) validate}}
|
118
118
|
data-test-save
|
119
119
|
/>
|
120
120
|
</DocumentValidity>
|
@@ -1,6 +1,15 @@
|
|
1
1
|
{{#if this.type}}
|
2
2
|
{{#let (component (concat "cf-field/input/" this.type)) as |InputComponent|}}
|
3
|
-
<div
|
3
|
+
<div
|
4
|
+
class="uk-form-controls
|
5
|
+
{{if
|
6
|
+
(and
|
7
|
+
(has-question-type @field.question 'multiple-choice' 'choice')
|
8
|
+
@field.question.raw.meta.vertical
|
9
|
+
)
|
10
|
+
'uk-flex'
|
11
|
+
}}"
|
12
|
+
>
|
4
13
|
<InputComponent
|
5
14
|
@field={{@field}}
|
6
15
|
@disabled={{@disabled}}
|
@@ -1,9 +1,24 @@
|
|
1
|
-
{{#if
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
{{#if (has-question-type @field.question "choice" "dynamic-choice")}}
|
2
|
+
{{@field.selected.label}}
|
3
|
+
{{else if (has-question-type
|
4
|
+
@field.question "multiple-choice" "multiple-dynamic-choice"
|
5
|
+
)}}
|
6
|
+
{{#each @field.selected as |opt i|}}{{if (gt i 0) ", "}}{{opt.label}}{{/each}}
|
7
|
+
{{else if (has-question-type @field.question "date")}}
|
8
|
+
{{format-date
|
9
|
+
@field.answer.value
|
10
|
+
day="2-digit"
|
11
|
+
month="2-digit"
|
12
|
+
year="numeric"
|
13
|
+
}}
|
14
|
+
{{else if (has-question-type @field.question "file")}}
|
15
|
+
{{#if @field.answer.value}}
|
16
|
+
<UkButton
|
17
|
+
@color="link"
|
18
|
+
@label={{@field.answer.value.name}}
|
19
|
+
@onClick={{fn this.download @field.answer.raw.id}}
|
20
|
+
/>
|
21
|
+
{{/if}}
|
7
22
|
{{else}}
|
8
|
-
{{
|
23
|
+
{{@field.answer.value}}
|
9
24
|
{{/if}}
|
@@ -1,50 +1,25 @@
|
|
1
1
|
import { action } from "@ember/object";
|
2
2
|
import Component from "@glimmer/component";
|
3
3
|
import { queryManager } from "ember-apollo-client";
|
4
|
-
import moment from "moment";
|
5
4
|
|
6
5
|
import getFileAnswerInfoQuery from "@projectcaluma/ember-form/gql/queries/fileanswer-info.graphql";
|
7
6
|
|
8
7
|
export default class CfFieldValueComponent extends Component {
|
9
8
|
@queryManager apollo;
|
10
9
|
|
11
|
-
get value() {
|
12
|
-
const field = this.args.field;
|
13
|
-
|
14
|
-
switch (field.questionType) {
|
15
|
-
case "ChoiceQuestion":
|
16
|
-
case "DynamicChoiceQuestion": {
|
17
|
-
return field.selected;
|
18
|
-
}
|
19
|
-
case "MultipleChoiceQuestion":
|
20
|
-
case "DynamicMultipleChoiceQuestion": {
|
21
|
-
return { label: field.selected.map(({ label }) => label).join(", ") };
|
22
|
-
}
|
23
|
-
case "FileQuestion": {
|
24
|
-
const answerValue = field.answer.value;
|
25
|
-
return {
|
26
|
-
fileAnswerId: answerValue && field.answer.raw.id,
|
27
|
-
label: answerValue?.name,
|
28
|
-
};
|
29
|
-
}
|
30
|
-
case "DateQuestion": {
|
31
|
-
return {
|
32
|
-
label: field.answer.value && moment(field.answer.value).format("L"),
|
33
|
-
};
|
34
|
-
}
|
35
|
-
|
36
|
-
default:
|
37
|
-
return { label: field.answer.value };
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
10
|
@action
|
42
11
|
async download(id) {
|
43
12
|
const { downloadUrl } = await this.apollo.query(
|
44
|
-
{
|
13
|
+
{
|
14
|
+
query: getFileAnswerInfoQuery,
|
15
|
+
variables: { id },
|
16
|
+
fetchPolicy: "network-only",
|
17
|
+
},
|
45
18
|
"node.fileValue"
|
46
19
|
);
|
47
20
|
|
48
|
-
|
21
|
+
if (downloadUrl) {
|
22
|
+
window.open(downloadUrl, "_blank");
|
23
|
+
}
|
49
24
|
}
|
50
25
|
}
|
@@ -1,5 +1,13 @@
|
|
1
1
|
{{#if this.visible}}
|
2
|
-
<div
|
2
|
+
<div
|
3
|
+
class="uk-margin
|
4
|
+
{{if
|
5
|
+
(and @disabled (has-question-type @field.question 'action-button'))
|
6
|
+
'uk-hidden'
|
7
|
+
}}"
|
8
|
+
{{did-insert this.registerComponent}}
|
9
|
+
{{will-destroy this.unregisterComponent}}
|
10
|
+
>
|
3
11
|
{{#if this.labelVisible}}
|
4
12
|
<CfField::label @field={{@field}} />
|
5
13
|
{{/if}}
|
@@ -24,11 +32,11 @@
|
|
24
32
|
<div
|
25
33
|
class="cf-field__icon uk-padding-remove-vertical uk-flex uk-flex-middle uk-flex-center"
|
26
34
|
>
|
27
|
-
{{#if
|
35
|
+
{{#if this.save.isRunning}}
|
28
36
|
<UkSpinner class="uk-animation-fade" />
|
29
|
-
{{else if (or
|
37
|
+
{{else if (or this.save.last.isError @field.isInvalid)}}
|
30
38
|
<UkIcon @icon="warning" class="uk-animation-fade uk-text-danger" />
|
31
|
-
{{else if
|
39
|
+
{{else if this.save.last.isSuccessful}}
|
32
40
|
<UkIcon @icon="check" class="uk-animation-fade uk-text-success" />
|
33
41
|
{{/if}}
|
34
42
|
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { getOwner } from "@ember/application";
|
2
|
-
import {
|
2
|
+
import { action } from "@ember/object";
|
3
3
|
import Component from "@glimmer/component";
|
4
4
|
import { timeout, restartableTask } from "ember-concurrency";
|
5
5
|
|
@@ -18,6 +18,16 @@ import { hasQuestionType } from "@projectcaluma/ember-core/helpers/has-question-
|
|
18
18
|
* @argument {Field} field The field data model to render
|
19
19
|
*/
|
20
20
|
export default class CfFieldComponent extends Component {
|
21
|
+
@action
|
22
|
+
registerComponent() {
|
23
|
+
this.args.field._components.add(this);
|
24
|
+
}
|
25
|
+
|
26
|
+
@action
|
27
|
+
unregisterComponent() {
|
28
|
+
this.args.field._components.delete(this);
|
29
|
+
}
|
30
|
+
|
21
31
|
get visible() {
|
22
32
|
return (
|
23
33
|
!this.args.field?.hidden &&
|
@@ -41,8 +51,9 @@ export default class CfFieldComponent extends Component {
|
|
41
51
|
}
|
42
52
|
|
43
53
|
/**
|
44
|
-
* Task to save a field. This will set the passed value to the answer and
|
45
|
-
*
|
54
|
+
* Task to save a field. This will set the passed value to the answer and save
|
55
|
+
* the field to the API after a timeout of 500 milliseconds which intends to
|
56
|
+
* reduce the amount of saved values when changed rapidly.
|
46
57
|
*
|
47
58
|
* @method save
|
48
59
|
* @param {String|Number|String[]} value
|
@@ -57,14 +68,18 @@ export default class CfFieldComponent extends Component {
|
|
57
68
|
yield timeout(500);
|
58
69
|
}
|
59
70
|
|
60
|
-
|
71
|
+
if (this.args.field.answer) {
|
72
|
+
this.args.field.answer.value = value;
|
73
|
+
}
|
61
74
|
|
62
75
|
yield this.args.field.validate.perform();
|
63
76
|
|
64
77
|
try {
|
78
|
+
// Save the new field value unlinked so the fields save task is not
|
79
|
+
// aborted when this component is destroyed
|
65
80
|
return yield this.args.field.save.unlinked().perform();
|
66
81
|
} catch (e) {
|
67
|
-
//
|
82
|
+
// The component was destroyed before the fields save task was finished
|
68
83
|
}
|
69
84
|
}
|
70
85
|
}
|
@@ -1,4 +1,7 @@
|
|
1
|
-
<ul
|
1
|
+
<ul
|
2
|
+
class="uk-tab uk-tab-left uk-width-auto"
|
3
|
+
{{did-insert @navigation.goToNextItemIfNonNavigable}}
|
4
|
+
>
|
2
5
|
{{#each @navigation.rootItems as |item|}}
|
3
6
|
<CfNavigationItem
|
4
7
|
@item={{item}}
|