@projectcaluma/ember-form 14.8.3 → 14.9.0
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-content.hbs +44 -39
- package/addon/components/cf-content.js +50 -14
- package/addon/components/cf-field/input/checkbox.hbs +3 -1
- package/addon/components/cf-field/input/checkbox.js +15 -0
- package/addon/components/cf-field/input/date.hbs +38 -31
- package/addon/components/cf-field/input/float.hbs +22 -15
- package/addon/components/cf-field/input/integer.hbs +22 -15
- package/addon/components/cf-field/input/number-separator.hbs +19 -12
- package/addon/components/cf-field/input/number-separator.js +10 -2
- package/addon/components/cf-field/input/powerselect.hbs +2 -2
- package/addon/components/cf-field/input/powerselect.js +12 -0
- package/addon/components/cf-field/input/radio.hbs +3 -1
- package/addon/components/cf-field/input/radio.js +15 -0
- package/addon/components/cf-field/input/table.hbs +31 -1
- package/addon/components/cf-field/input/table.js +10 -0
- package/addon/components/cf-field/input/text.hbs +21 -14
- package/addon/components/cf-field/input/textarea.hbs +21 -14
- package/addon/components/cf-field/input-compare/changes-note.hbs +9 -0
- package/addon/components/cf-field/input-compare/text-diff.hbs +6 -0
- package/addon/components/cf-field/input-compare/textarea-diff.hbs +6 -0
- package/addon/components/cf-field/input-compare.hbs +50 -0
- package/addon/components/cf-field/input-compare.js +60 -0
- package/addon/components/cf-field/input.hbs +1 -0
- package/addon/components/cf-field.hbs +17 -8
- package/addon/components/cf-field.js +15 -3
- package/addon/components/cf-form-wrapper.hbs +1 -0
- package/addon/components/cf-form.hbs +1 -0
- package/addon/components/cf-navigation-item.hbs +14 -4
- package/addon/components/cf-navigation.hbs +1 -0
- package/addon/components/timeline-select.hbs +20 -0
- package/addon/gql/queries/document-answers-compare.graphql +157 -0
- package/addon/helpers/get-widget.js +17 -31
- package/addon/instance-initializers/form-widget-overrides.js +6 -0
- package/addon/lib/answer.js +38 -3
- package/addon/lib/compare.js +161 -0
- package/addon/lib/document.js +10 -2
- package/addon/lib/field.js +81 -1
- package/addon/lib/fieldset.js +11 -0
- package/addon/lib/navigation.js +51 -1
- package/addon/lib/parsers.js +57 -5
- package/addon/services/caluma-store.js +12 -0
- package/app/components/cf-field/input-compare/changes-note.js +1 -0
- package/app/components/cf-field/input-compare/text-diff.js +1 -0
- package/app/components/cf-field/input-compare/textarea-diff.js +1 -0
- package/app/components/cf-field/input-compare.js +1 -0
- package/app/components/timeline-select.js +1 -0
- package/app/styles/@projectcaluma/ember-form.scss +1 -0
- package/app/styles/_cf-content-compare.scss +214 -0
- package/app/styles/_cf-navigation.scss +1 -0
- package/package.json +5 -5
- package/translations/de.yaml +9 -0
- package/translations/en.yaml +9 -0
- package/translations/fr.yaml +9 -0
- package/translations/it.yaml +9 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{{#let
|
|
2
|
+
(component
|
|
3
|
+
(ensure-safe-component (get-widget @field.question))
|
|
4
|
+
field=@field
|
|
5
|
+
disabled=true
|
|
6
|
+
context=@context
|
|
7
|
+
onSave=(perform this.save)
|
|
8
|
+
)
|
|
9
|
+
as |FieldComponent|
|
|
10
|
+
}}
|
|
11
|
+
{{#if @field.isModified}}
|
|
12
|
+
<div
|
|
13
|
+
class="cf-compare cf-compare-{{@field.question.raw.__typename}}
|
|
14
|
+
{{if (eq @field.answer.raw.historyType '-') 'cf-compare-removed' ''}}
|
|
15
|
+
{{if (eq @field.answer.raw.historyType '+') 'cf-compare-added' ''}}
|
|
16
|
+
{{if (eq @field.answer.raw.historyType '~') 'cf-compare-modified' ''}}
|
|
17
|
+
"
|
|
18
|
+
>
|
|
19
|
+
{{#if this.compareOptions.combined}}
|
|
20
|
+
<div class="combined-diff">
|
|
21
|
+
<div hidden>
|
|
22
|
+
<FieldComponent @compare={{false}} />
|
|
23
|
+
</div>
|
|
24
|
+
<div class="diff-version">
|
|
25
|
+
<FieldComponent @compare={{@compare}} />
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
{{#unless this.compareOptions.disableChangesNote}}
|
|
29
|
+
<div class="changes-note">
|
|
30
|
+
<CfField::InputCompare::ChangesNote @field={{@field}} />
|
|
31
|
+
</div>
|
|
32
|
+
{{/unless}}
|
|
33
|
+
{{else}}
|
|
34
|
+
<div class="from-version">
|
|
35
|
+
<FieldComponent @compare={{@compare}} />
|
|
36
|
+
</div>
|
|
37
|
+
<div class="to-version">
|
|
38
|
+
<FieldComponent @compare={{false}} />
|
|
39
|
+
</div>
|
|
40
|
+
{{#unless this.compareOptions.disableChangesNote}}
|
|
41
|
+
<div class="changes-note">
|
|
42
|
+
<CfField::InputCompare::ChangesNote @field={{@field}} />
|
|
43
|
+
</div>
|
|
44
|
+
{{/unless}}
|
|
45
|
+
{{/if}}
|
|
46
|
+
</div>
|
|
47
|
+
{{else}}
|
|
48
|
+
<FieldComponent @compare={{false}} />
|
|
49
|
+
{{/if}}
|
|
50
|
+
{{/let}}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { service } from "@ember/service";
|
|
2
|
+
import Component from "@glimmer/component";
|
|
3
|
+
import { task } from "ember-concurrency";
|
|
4
|
+
|
|
5
|
+
import { parseWidgetType } from "@projectcaluma/ember-form/lib/parsers";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Component for wrapping the compare input components
|
|
9
|
+
*
|
|
10
|
+
* @class CfFieldInputCompareComponent
|
|
11
|
+
*/
|
|
12
|
+
export default class CfFieldInputCompareComponent extends Component {
|
|
13
|
+
@service calumaOptions;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The compare input options.
|
|
17
|
+
*
|
|
18
|
+
* @property {} compareOptions
|
|
19
|
+
* @accessor
|
|
20
|
+
*/
|
|
21
|
+
get compareOptions() {
|
|
22
|
+
const { widget } = parseWidgetType(this.calumaOptions, [
|
|
23
|
+
this.args.field.question,
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
const override = this.calumaOptions
|
|
27
|
+
.getComponentOverrides()
|
|
28
|
+
.find(({ component }) => component === widget);
|
|
29
|
+
|
|
30
|
+
if (widget === "cf-field/input") {
|
|
31
|
+
const typeName = this.args.field?.question?.raw?.__typename;
|
|
32
|
+
const compareOptions = {
|
|
33
|
+
TextQuestion: { combined: true },
|
|
34
|
+
IntegerQuestion: { combined: true },
|
|
35
|
+
MultipleChoiceQuestion: { combined: true },
|
|
36
|
+
ChoiceQuestion: { combined: true },
|
|
37
|
+
DateQuestion: { combined: true },
|
|
38
|
+
TextareaQuestion: { combined: true },
|
|
39
|
+
TableQuestion: { combined: true, disableChangesNote: true },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
if (typeName in compareOptions) {
|
|
43
|
+
return compareOptions[typeName];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return override?.compareOptions;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* In comparison mode, never perform a save, but keep a method
|
|
52
|
+
* to bind to the components.
|
|
53
|
+
*
|
|
54
|
+
* @method save
|
|
55
|
+
* @param {String|Number|String[]} value The new value to save to the field
|
|
56
|
+
*/
|
|
57
|
+
save = task({ restartable: true }, async (value) => {
|
|
58
|
+
return value;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
@@ -18,17 +18,26 @@
|
|
|
18
18
|
|
|
19
19
|
<div class="uk-flex">
|
|
20
20
|
<div class="uk-width-expand">
|
|
21
|
-
{{#
|
|
22
|
-
|
|
23
|
-
as |FieldComponent|
|
|
24
|
-
}}
|
|
25
|
-
<FieldComponent
|
|
21
|
+
{{#if @compare}}
|
|
22
|
+
<CfField::InputCompare
|
|
26
23
|
@field={{@field}}
|
|
27
|
-
@disabled={{
|
|
24
|
+
@disabled={{true}}
|
|
28
25
|
@context={{@context}}
|
|
29
|
-
@
|
|
26
|
+
@compare={{@compare}}
|
|
30
27
|
/>
|
|
31
|
-
{{
|
|
28
|
+
{{else}}
|
|
29
|
+
{{#let
|
|
30
|
+
(component (ensure-safe-component (get-widget @field.question)))
|
|
31
|
+
as |FieldComponent|
|
|
32
|
+
}}
|
|
33
|
+
<FieldComponent
|
|
34
|
+
@field={{@field}}
|
|
35
|
+
@disabled={{or @disabled @field.refreshAnswer.isRunning}}
|
|
36
|
+
@context={{@context}}
|
|
37
|
+
@onSave={{perform this.save}}
|
|
38
|
+
/>
|
|
39
|
+
{{/let}}
|
|
40
|
+
{{/if}}
|
|
32
41
|
</div>
|
|
33
42
|
|
|
34
43
|
{{#if (and @field.question.raw.infoText this.infoTextVisible)}}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { action } from "@ember/object";
|
|
2
2
|
import { service } from "@ember/service";
|
|
3
|
-
import {
|
|
3
|
+
import { isTesting, macroCondition } from "@embroider/macros";
|
|
4
4
|
import Component from "@glimmer/component";
|
|
5
|
-
import {
|
|
5
|
+
import { task, timeout } from "ember-concurrency";
|
|
6
6
|
|
|
7
7
|
import { hasQuestionType } from "@projectcaluma/ember-core/helpers/has-question-type";
|
|
8
8
|
|
|
@@ -31,6 +31,10 @@ export default class CfFieldComponent extends Component {
|
|
|
31
31
|
this.args.field._components.delete(this);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
get compare() {
|
|
35
|
+
return this.args.compare;
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
get hasHiddenWidget() {
|
|
35
39
|
return (
|
|
36
40
|
this.args.field?.question.raw.meta.widgetOverride ===
|
|
@@ -77,7 +81,10 @@ export default class CfFieldComponent extends Component {
|
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
get saveIndicatorVisible() {
|
|
80
|
-
return
|
|
84
|
+
return (
|
|
85
|
+
!this.compare &&
|
|
86
|
+
!hasQuestionType(this.args.field?.question, "action-button")
|
|
87
|
+
);
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
/**
|
|
@@ -89,6 +96,11 @@ export default class CfFieldComponent extends Component {
|
|
|
89
96
|
* @param {String|Number|String[]} value The new value to save to the field
|
|
90
97
|
*/
|
|
91
98
|
save = task({ restartable: true }, async (value) => {
|
|
99
|
+
// Do not save when in comparison mode.
|
|
100
|
+
if (this.compare) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
92
104
|
if (typeof this.args.onSave === "function") {
|
|
93
105
|
return await this.args.onSave(this.args.field, value);
|
|
94
106
|
}
|
|
@@ -17,10 +17,19 @@
|
|
|
17
17
|
{{@item.label}}
|
|
18
18
|
</span>
|
|
19
19
|
{{/if}}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
{{#if @compare}}
|
|
21
|
+
{{#if (eq @item.compareState "modified")}}
|
|
22
|
+
<UkIcon
|
|
23
|
+
@icon="pencil"
|
|
24
|
+
class="cf-navigation__item__icon cf-navigation__item__icon--compare-{{@item.compareState}}"
|
|
25
|
+
/>
|
|
26
|
+
{{/if}}
|
|
27
|
+
{{else}}
|
|
28
|
+
<span
|
|
29
|
+
class="cf-navigation__item__icon cf-navigation__item__icon--{{@item.state}}
|
|
30
|
+
{{if @item.dirty 'cf-navigation__item__icon--dirty'}}"
|
|
31
|
+
></span>
|
|
32
|
+
{{/if}}
|
|
24
33
|
</LinkTo>
|
|
25
34
|
|
|
26
35
|
{{#if @item.visibleChildren}}
|
|
@@ -29,6 +38,7 @@
|
|
|
29
38
|
<CfNavigationItem
|
|
30
39
|
@item={{child}}
|
|
31
40
|
@headingLevel={{add @headingLevel 1}}
|
|
41
|
+
@compare={{@compare}}
|
|
32
42
|
/>
|
|
33
43
|
{{/each}}
|
|
34
44
|
</ul>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<PowerSelect
|
|
2
|
+
class="uk-margin-bottom"
|
|
3
|
+
@selected={{@selected}}
|
|
4
|
+
@options={{@options}}
|
|
5
|
+
@searchEnabled={{false}}
|
|
6
|
+
@searchField="label"
|
|
7
|
+
@allowClear={{true}}
|
|
8
|
+
@onChange={{@onChange}}
|
|
9
|
+
as |option|
|
|
10
|
+
>
|
|
11
|
+
{{#if (eq option.id "current")}}
|
|
12
|
+
{{t "caluma.form.compare.timeline.current"}}
|
|
13
|
+
{{else}}
|
|
14
|
+
{{option.label}}:
|
|
15
|
+
{{format-date option.startDate}}
|
|
16
|
+
{{#if option.endDate}}
|
|
17
|
+
-
|
|
18
|
+
{{format-date option.endDate}}{{/if}}
|
|
19
|
+
{{/if}}
|
|
20
|
+
</PowerSelect>
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#import FieldQuestion, SimpleQuestion, FieldTableQuestion from '../fragments/field.graphql'
|
|
2
|
+
|
|
3
|
+
fragment SimpleRevisionAnswer on HistoricalAnswer {
|
|
4
|
+
id
|
|
5
|
+
historyDate
|
|
6
|
+
historyUserId
|
|
7
|
+
historyType
|
|
8
|
+
question {
|
|
9
|
+
slug
|
|
10
|
+
label
|
|
11
|
+
... on ChoiceQuestion {
|
|
12
|
+
choiceOptions: options {
|
|
13
|
+
edges {
|
|
14
|
+
node {
|
|
15
|
+
slug
|
|
16
|
+
label
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
... on DynamicChoiceQuestion {
|
|
22
|
+
dynamicChoiceOptions: options(context: $context) {
|
|
23
|
+
edges {
|
|
24
|
+
node {
|
|
25
|
+
slug
|
|
26
|
+
label
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
... on MultipleChoiceQuestion {
|
|
32
|
+
multipleChoiceOptions: options {
|
|
33
|
+
edges {
|
|
34
|
+
node {
|
|
35
|
+
slug
|
|
36
|
+
label
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
... on DynamicMultipleChoiceQuestion {
|
|
42
|
+
dynamicMultipleChoiceOptions: options(context: $context) {
|
|
43
|
+
edges {
|
|
44
|
+
node {
|
|
45
|
+
slug
|
|
46
|
+
label
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
__typename
|
|
52
|
+
}
|
|
53
|
+
... on HistoricalStringAnswer {
|
|
54
|
+
historyId
|
|
55
|
+
stringValue: value
|
|
56
|
+
}
|
|
57
|
+
... on HistoricalListAnswer {
|
|
58
|
+
historyId
|
|
59
|
+
listValue: value
|
|
60
|
+
}
|
|
61
|
+
... on HistoricalIntegerAnswer {
|
|
62
|
+
historyId
|
|
63
|
+
integerValue: value
|
|
64
|
+
}
|
|
65
|
+
... on HistoricalFloatAnswer {
|
|
66
|
+
historyId
|
|
67
|
+
floatValue: value
|
|
68
|
+
}
|
|
69
|
+
... on HistoricalDateAnswer {
|
|
70
|
+
historyId
|
|
71
|
+
dateValue: value
|
|
72
|
+
}
|
|
73
|
+
__typename
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fragment HistoricalTableValue on HistoricalDocument {
|
|
77
|
+
id: documentId
|
|
78
|
+
documentId: id
|
|
79
|
+
historyDate
|
|
80
|
+
historyType
|
|
81
|
+
historyUserId
|
|
82
|
+
form {
|
|
83
|
+
id
|
|
84
|
+
slug
|
|
85
|
+
questions {
|
|
86
|
+
edges {
|
|
87
|
+
node {
|
|
88
|
+
...FieldQuestion
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
__typename
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
fragment RevisionDocument on HistoricalDocument {
|
|
97
|
+
historicalDocumentId: id
|
|
98
|
+
id: documentId
|
|
99
|
+
form {
|
|
100
|
+
id
|
|
101
|
+
slug
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
query (
|
|
106
|
+
$documentId: ID!
|
|
107
|
+
$from: DateTime!
|
|
108
|
+
$to: DateTime!
|
|
109
|
+
$context: JSONString
|
|
110
|
+
) {
|
|
111
|
+
fromRevision: documentAsOf(id: $documentId, asOf: $from) {
|
|
112
|
+
...RevisionDocument
|
|
113
|
+
answers: historicalAnswers(asOf: $from, excludeDeleted: true) {
|
|
114
|
+
edges {
|
|
115
|
+
node {
|
|
116
|
+
...SimpleRevisionAnswer
|
|
117
|
+
... on HistoricalTableAnswer {
|
|
118
|
+
tableValue: value(asOf: $from, excludeDeleted: true) {
|
|
119
|
+
...HistoricalTableValue
|
|
120
|
+
|
|
121
|
+
answers: historicalAnswers(asOf: $from, excludeDeleted: true) {
|
|
122
|
+
edges {
|
|
123
|
+
node {
|
|
124
|
+
...SimpleRevisionAnswer
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
toRevision: documentAsOf(id: $documentId, asOf: $to) {
|
|
135
|
+
...RevisionDocument
|
|
136
|
+
answers: historicalAnswers(asOf: $to) {
|
|
137
|
+
edges {
|
|
138
|
+
node {
|
|
139
|
+
...SimpleRevisionAnswer
|
|
140
|
+
... on HistoricalTableAnswer {
|
|
141
|
+
tableValue: value(asOf: $to) {
|
|
142
|
+
...HistoricalTableValue
|
|
143
|
+
|
|
144
|
+
answers: historicalAnswers(asOf: $to) {
|
|
145
|
+
edges {
|
|
146
|
+
node {
|
|
147
|
+
...SimpleRevisionAnswer
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import Helper from "@ember/component/helper";
|
|
2
|
-
import { warn } from "@ember/debug";
|
|
3
2
|
import { inject as service } from "@ember/service";
|
|
4
3
|
import { ensureSafeComponent } from "@embroider/util";
|
|
5
4
|
|
|
6
5
|
import InputComponent from "@projectcaluma/ember-form/components/cf-field/input";
|
|
7
6
|
import FormComponent from "@projectcaluma/ember-form/components/cf-form";
|
|
7
|
+
import { parseWidgetType } from "@projectcaluma/ember-form/lib/parsers";
|
|
8
8
|
|
|
9
9
|
const DEFAULT_WIDGETS = {
|
|
10
10
|
"cf-field/input": InputComponent,
|
|
@@ -33,38 +33,24 @@ const DEFAULT_WIDGETS = {
|
|
|
33
33
|
export default class GetWidgetHelper extends Helper {
|
|
34
34
|
@service calumaOptions;
|
|
35
35
|
|
|
36
|
-
compute(params,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this
|
|
51
|
-
.getComponentOverrides()
|
|
52
|
-
.find(({ component }) => component === widget);
|
|
53
|
-
|
|
54
|
-
warn(
|
|
55
|
-
`Widget override "${widget}" is not registered. Please register it by calling \`calumaOptions.registerComponentOverride\``,
|
|
56
|
-
override,
|
|
57
|
-
{ id: "ember-caluma.unregistered-override" },
|
|
36
|
+
compute(params, options = {}) {
|
|
37
|
+
const { widget, override } = parseWidgetType(
|
|
38
|
+
this.calumaOptions,
|
|
39
|
+
params,
|
|
40
|
+
options,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if (override) {
|
|
44
|
+
const overrideWidget = this.calumaOptions
|
|
45
|
+
.getComponentOverrides()
|
|
46
|
+
.find(({ component }) => component === widget);
|
|
47
|
+
|
|
48
|
+
return ensureSafeComponent(
|
|
49
|
+
overrideWidget.componentClass ?? overrideWidget.component,
|
|
50
|
+
this,
|
|
58
51
|
);
|
|
59
|
-
|
|
60
|
-
if (override) {
|
|
61
|
-
return ensureSafeComponent(
|
|
62
|
-
override.componentClass ?? override.component,
|
|
63
|
-
this,
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
52
|
}
|
|
67
53
|
|
|
68
|
-
return ensureSafeComponent(DEFAULT_WIDGETS[
|
|
54
|
+
return ensureSafeComponent(DEFAULT_WIDGETS[widget], this);
|
|
69
55
|
}
|
|
70
56
|
}
|
|
@@ -33,6 +33,9 @@ class PowerSelectOverride {
|
|
|
33
33
|
"DynamicChoiceQuestion",
|
|
34
34
|
"DynamicMultipleChoiceQuestion",
|
|
35
35
|
];
|
|
36
|
+
compareOptions = {
|
|
37
|
+
combined: false,
|
|
38
|
+
};
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
class NumberSeparatorOverride {
|
|
@@ -47,6 +50,9 @@ class NumberSeparatorOverride {
|
|
|
47
50
|
component = "cf-field/input/number-separator";
|
|
48
51
|
componentClass = NumberSeparatorComponent;
|
|
49
52
|
types = ["IntegerQuestion", "FloatQuestion", "CalculatedFloatQuestion"];
|
|
53
|
+
compareOptions = {
|
|
54
|
+
combined: true,
|
|
55
|
+
};
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
export function initialize(appInstance) {
|
package/addon/lib/answer.js
CHANGED
|
@@ -2,10 +2,11 @@ import { getOwner } from "@ember/application";
|
|
|
2
2
|
import { assert } from "@ember/debug";
|
|
3
3
|
import { camelize } from "@ember/string";
|
|
4
4
|
import { isEmpty } from "@ember/utils";
|
|
5
|
-
import {
|
|
5
|
+
import { cached, dedupeTracked } from "tracked-toolbox";
|
|
6
6
|
|
|
7
7
|
import { decodeId } from "@projectcaluma/ember-core/helpers/decode-id";
|
|
8
8
|
import Base from "@projectcaluma/ember-form/lib/base";
|
|
9
|
+
import { historicalTableValue } from "@projectcaluma/ember-form/lib/compare";
|
|
9
10
|
import { parseDocument } from "@projectcaluma/ember-form/lib/parsers";
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -33,7 +34,7 @@ class DedupedTrackedObject {
|
|
|
33
34
|
* @class Answer
|
|
34
35
|
*/
|
|
35
36
|
export default class Answer extends Base {
|
|
36
|
-
constructor({ raw, field, ...args }) {
|
|
37
|
+
constructor({ raw, field, historical, ...args }) {
|
|
37
38
|
assert("`field` must be passed as an argument", field);
|
|
38
39
|
|
|
39
40
|
assert(
|
|
@@ -45,6 +46,7 @@ export default class Answer extends Base {
|
|
|
45
46
|
|
|
46
47
|
this.field = field;
|
|
47
48
|
this.raw = new DedupedTrackedObject(raw);
|
|
49
|
+
this.historical = historical ? new DedupedTrackedObject(historical) : null;
|
|
48
50
|
|
|
49
51
|
this.pushIntoStore();
|
|
50
52
|
}
|
|
@@ -64,6 +66,14 @@ export default class Answer extends Base {
|
|
|
64
66
|
*/
|
|
65
67
|
raw = {};
|
|
66
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Get the compare context via the field.
|
|
71
|
+
* @property {Object} compare
|
|
72
|
+
*/
|
|
73
|
+
get compare() {
|
|
74
|
+
return this.field.compare;
|
|
75
|
+
}
|
|
76
|
+
|
|
67
77
|
/**
|
|
68
78
|
* The primary key of the answer.
|
|
69
79
|
*
|
|
@@ -106,7 +116,11 @@ export default class Answer extends Base {
|
|
|
106
116
|
get _valueKey() {
|
|
107
117
|
return (
|
|
108
118
|
this.raw.__typename &&
|
|
109
|
-
camelize(
|
|
119
|
+
camelize(
|
|
120
|
+
this.raw.__typename
|
|
121
|
+
.replace(/^Historical/, "")
|
|
122
|
+
.replace(/Answer$/, "Value"),
|
|
123
|
+
)
|
|
110
124
|
);
|
|
111
125
|
}
|
|
112
126
|
|
|
@@ -121,6 +135,15 @@ export default class Answer extends Base {
|
|
|
121
135
|
const value = this.raw[this._valueKey];
|
|
122
136
|
|
|
123
137
|
if (this._valueKey === "tableValue" && value) {
|
|
138
|
+
// For a historical view for table values we map it differently to be able to
|
|
139
|
+
// show the diff.
|
|
140
|
+
if (this.compare) {
|
|
141
|
+
const owner = getOwner(this);
|
|
142
|
+
const historicalValue = this.historical?.[this._valueKey] || [];
|
|
143
|
+
|
|
144
|
+
return historicalTableValue(owner, this.field, value, historicalValue);
|
|
145
|
+
}
|
|
146
|
+
|
|
124
147
|
const owner = getOwner(this);
|
|
125
148
|
const Document = owner.factoryFor("caluma-model:document").class;
|
|
126
149
|
|
|
@@ -146,6 +169,18 @@ export default class Answer extends Base {
|
|
|
146
169
|
return value;
|
|
147
170
|
}
|
|
148
171
|
|
|
172
|
+
get historicalValue() {
|
|
173
|
+
return this.historical?.[this._valueKey];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
get historicalDate() {
|
|
177
|
+
return this.historical?.historyDate;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
get historicalUser() {
|
|
181
|
+
return this.historical?.historyUserId;
|
|
182
|
+
}
|
|
183
|
+
|
|
149
184
|
set value(value) {
|
|
150
185
|
if (this._valueKey) {
|
|
151
186
|
this.raw[this._valueKey] = [undefined, ""].includes(value) ? null : value;
|