@projectcaluma/ember-form 11.0.0-beta.21 → 11.0.0-beta.22
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/CHANGELOG.md +11 -0
- package/addon/components/cf-field/input/files.hbs +35 -0
- package/addon/components/cf-field/input/files.js +113 -0
- package/addon/components/cf-field/input.js +2 -2
- package/addon/components/cf-field-value.hbs +5 -5
- package/addon/components/cf-field-value.js +6 -5
- package/addon/gql/fragments/field.graphql +3 -3
- package/addon/gql/mutations/save-document-files-answer.graphql +9 -0
- package/addon/gql/queries/{fileanswer-info.graphql → filesanswer-info.graphql} +4 -4
- package/addon/lib/field.js +5 -5
- package/app/components/cf-field/input/{file.js → files.js} +1 -1
- package/package.json +12 -12
- package/addon/components/cf-field/input/file.hbs +0 -32
- package/addon/components/cf-field/input/file.js +0 -89
- package/addon/gql/mutations/remove-answer.graphql +0 -7
- package/addon/gql/mutations/save-document-file-answer.graphql +0 -9
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# [@projectcaluma/ember-form-v11.0.0-beta.22](https://github.com/projectcaluma/ember-caluma/compare/@projectcaluma/ember-form-v11.0.0-beta.21...@projectcaluma/ember-form-v11.0.0-beta.22) (2022-08-05)
|
2
|
+
|
3
|
+
|
4
|
+
* feat!: add multi file upload (#2040) ([c4fd004](https://github.com/projectcaluma/ember-caluma/commit/c4fd0049654b2d2e5ea62e5909a45d89cb888b40)), closes [#2040](https://github.com/projectcaluma/ember-caluma/issues/2040)
|
5
|
+
|
6
|
+
|
7
|
+
### BREAKING CHANGES
|
8
|
+
|
9
|
+
* This requires the caluma backend version v8.0.0-beta.12
|
10
|
+
or later.
|
11
|
+
|
1
12
|
# [@projectcaluma/ember-form-v11.0.0-beta.21](https://github.com/projectcaluma/ember-caluma/compare/@projectcaluma/ember-form-v11.0.0-beta.20...@projectcaluma/ember-form-v11.0.0-beta.21) (2022-06-09)
|
2
13
|
|
3
14
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<div class="uk-flex-middle uk-grid-divider uk-grid-column-small" uk-grid>
|
2
|
+
<div uk-form-custom="target: true">
|
3
|
+
|
4
|
+
<input
|
5
|
+
type="file"
|
6
|
+
name={{@field.pk}}
|
7
|
+
id={{@field.pk}}
|
8
|
+
disabled={{@disabled}}
|
9
|
+
multiple
|
10
|
+
{{on "change" this.save}}
|
11
|
+
/>
|
12
|
+
<UkButton disabled={{@disabled}}>
|
13
|
+
{{t "caluma.form.selectFile"}}
|
14
|
+
</UkButton>
|
15
|
+
</div>
|
16
|
+
<ul class="uk-list uk-list-collapse" data-test-file-list={{@field.pk}}>
|
17
|
+
{{#each this.files as |file|}}
|
18
|
+
<li class="uk-text-justify uk-text-middle">
|
19
|
+
<UkButton
|
20
|
+
data-test-download-link={{file.id}}
|
21
|
+
@color="link"
|
22
|
+
@onClick={{fn this.download file.id}}
|
23
|
+
>
|
24
|
+
{{file.name}}
|
25
|
+
</UkButton>
|
26
|
+
<UkIcon
|
27
|
+
class="uk-icon-button uk-margin-small-left"
|
28
|
+
role="button"
|
29
|
+
@icon="trash"
|
30
|
+
{{on "click" (fn this.delete file.id)}}
|
31
|
+
/>
|
32
|
+
</li>
|
33
|
+
{{/each}}
|
34
|
+
</ul>
|
35
|
+
</div>
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import { action } from "@ember/object";
|
2
|
+
import { inject as service } from "@ember/service";
|
3
|
+
import { macroCondition, isTesting } from "@embroider/macros";
|
4
|
+
import Component from "@glimmer/component";
|
5
|
+
import { queryManager } from "ember-apollo-client";
|
6
|
+
import fetch from "fetch";
|
7
|
+
|
8
|
+
import getFilesAnswerInfoQuery from "@projectcaluma/ember-form/gql/queries/filesanswer-info.graphql";
|
9
|
+
|
10
|
+
export default class CfFieldInputFilesComponent extends Component {
|
11
|
+
@service intl;
|
12
|
+
|
13
|
+
@queryManager apollo;
|
14
|
+
|
15
|
+
get files() {
|
16
|
+
return this.args.field?.answer?.value;
|
17
|
+
}
|
18
|
+
|
19
|
+
@action
|
20
|
+
async download(fileId) {
|
21
|
+
if (!fileId) {
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
const answers = await this.apollo.query(
|
25
|
+
{
|
26
|
+
query: getFilesAnswerInfoQuery,
|
27
|
+
variables: { id: this.args.field.answer.raw.id },
|
28
|
+
fetchPolicy: "network-only",
|
29
|
+
},
|
30
|
+
"node.value"
|
31
|
+
);
|
32
|
+
const { downloadUrl } =
|
33
|
+
answers.find((file) =>
|
34
|
+
// the testing graph-ql setup does a base64 encoding of `__typename: fileID`
|
35
|
+
macroCondition(isTesting())
|
36
|
+
? file.id === fileId ||
|
37
|
+
atob(file.id).substring(file.__typename.length + 1) === fileId
|
38
|
+
: file.id === fileId
|
39
|
+
) ?? {};
|
40
|
+
if (downloadUrl) {
|
41
|
+
window.open(downloadUrl, "_blank");
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
@action
|
46
|
+
async save({ target }) {
|
47
|
+
// store the old list of files
|
48
|
+
// unwrap files from FileList construct
|
49
|
+
let newFiles = Array.from(target.files).map((file) => ({
|
50
|
+
name: file.name,
|
51
|
+
value: file,
|
52
|
+
}));
|
53
|
+
|
54
|
+
const fileList = [...(this.files || []), ...newFiles];
|
55
|
+
|
56
|
+
if (newFiles.length === 0) {
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
|
60
|
+
// trigger save action for file list of old and new files with
|
61
|
+
// reduces properties to match gql format
|
62
|
+
const { filesValue: savedAnswerValue } = await this.args.onSave(
|
63
|
+
fileList.map(({ name, id }) => ({ name, id }))
|
64
|
+
);
|
65
|
+
|
66
|
+
try {
|
67
|
+
// iterate over list of new files and enrich with graphql answer values
|
68
|
+
newFiles = newFiles.map((file) => ({
|
69
|
+
...savedAnswerValue.find(
|
70
|
+
(value) =>
|
71
|
+
file.name === value.name &&
|
72
|
+
!fileList.find((file) => file.id === value.id)
|
73
|
+
),
|
74
|
+
value: file.value,
|
75
|
+
}));
|
76
|
+
|
77
|
+
const uploadFunction = async (file) => {
|
78
|
+
const response = await fetch(file.uploadUrl, {
|
79
|
+
method: "PUT",
|
80
|
+
body: file.value,
|
81
|
+
});
|
82
|
+
if (!response.ok) {
|
83
|
+
throw new Error();
|
84
|
+
}
|
85
|
+
return response;
|
86
|
+
};
|
87
|
+
|
88
|
+
// upload the actual file to data storage
|
89
|
+
await Promise.all(newFiles.map((file) => uploadFunction(file)));
|
90
|
+
|
91
|
+
this.args.field.answer.value = savedAnswerValue;
|
92
|
+
} catch (error) {
|
93
|
+
await this.args.onSave([]);
|
94
|
+
this.args.field._errors = [{ type: "uploadFailed" }];
|
95
|
+
} finally {
|
96
|
+
// eslint-disable-next-line require-atomic-updates
|
97
|
+
target.value = "";
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
@action
|
102
|
+
async delete(fileId) {
|
103
|
+
const remainingFiles = this.files
|
104
|
+
.filter((file) => file.id !== fileId)
|
105
|
+
.map(({ name, id }) => ({ name, id }));
|
106
|
+
|
107
|
+
try {
|
108
|
+
await this.args.onSave(remainingFiles);
|
109
|
+
} catch (error) {
|
110
|
+
this.args.field._errors = [{ type: "deleteFailed" }];
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
@@ -4,7 +4,7 @@ import Component from "@glimmer/component";
|
|
4
4
|
import ActionButtonComponent from "@projectcaluma/ember-form/components/cf-field/input/action-button";
|
5
5
|
import CheckboxComponent from "@projectcaluma/ember-form/components/cf-field/input/checkbox";
|
6
6
|
import DateComponent from "@projectcaluma/ember-form/components/cf-field/input/date";
|
7
|
-
import
|
7
|
+
import FilesComponent from "@projectcaluma/ember-form/components/cf-field/input/files";
|
8
8
|
import FloatComponent from "@projectcaluma/ember-form/components/cf-field/input/float";
|
9
9
|
import IntegerComponent from "@projectcaluma/ember-form/components/cf-field/input/integer";
|
10
10
|
import RadioComponent from "@projectcaluma/ember-form/components/cf-field/input/radio";
|
@@ -20,7 +20,7 @@ const COMPONENT_MAPPING = {
|
|
20
20
|
DateQuestion: DateComponent,
|
21
21
|
DynamicChoiceQuestion: RadioComponent,
|
22
22
|
DynamicMultipleChoiceQuestion: CheckboxComponent,
|
23
|
-
|
23
|
+
FilesQuestion: FilesComponent,
|
24
24
|
FloatQuestion: FloatComponent,
|
25
25
|
IntegerQuestion: IntegerComponent,
|
26
26
|
MultipleChoiceQuestion: CheckboxComponent,
|
@@ -11,14 +11,14 @@
|
|
11
11
|
month="2-digit"
|
12
12
|
year="numeric"
|
13
13
|
}}
|
14
|
-
{{else if (has-question-type @field.question "
|
15
|
-
{{#
|
14
|
+
{{else if (has-question-type @field.question "files")}}
|
15
|
+
{{#each @field.answer.value as |file|}}
|
16
16
|
<UkButton
|
17
17
|
@color="link"
|
18
|
-
@label={{
|
19
|
-
@onClick={{fn this.download
|
18
|
+
@label={{file.name}}
|
19
|
+
@onClick={{fn this.download file.id}}
|
20
20
|
/>
|
21
|
-
{{/
|
21
|
+
{{/each}}
|
22
22
|
{{else}}
|
23
23
|
{{@field.answer.value}}
|
24
24
|
{{/if}}
|
@@ -2,22 +2,23 @@ import { action } from "@ember/object";
|
|
2
2
|
import Component from "@glimmer/component";
|
3
3
|
import { queryManager } from "ember-apollo-client";
|
4
4
|
|
5
|
-
import
|
5
|
+
import getFilesAnswerInfoQuery from "@projectcaluma/ember-form/gql/queries/filesanswer-info.graphql";
|
6
6
|
|
7
7
|
export default class CfFieldValueComponent extends Component {
|
8
8
|
@queryManager apollo;
|
9
9
|
|
10
10
|
@action
|
11
11
|
async download(id) {
|
12
|
-
const
|
12
|
+
const files = await this.apollo.query(
|
13
13
|
{
|
14
|
-
query:
|
15
|
-
variables: { id },
|
14
|
+
query: getFilesAnswerInfoQuery,
|
15
|
+
variables: { id: this.args.field.answer.raw.id },
|
16
16
|
fetchPolicy: "network-only",
|
17
17
|
},
|
18
|
-
"node.
|
18
|
+
"node.value"
|
19
19
|
);
|
20
20
|
|
21
|
+
const { downloadUrl } = files?.find((file) => file.id === id);
|
21
22
|
if (downloadUrl) {
|
22
23
|
window.open(downloadUrl, "_blank");
|
23
24
|
}
|
@@ -117,7 +117,7 @@ fragment SimpleQuestion on Question {
|
|
117
117
|
calcExpression
|
118
118
|
hintText
|
119
119
|
}
|
120
|
-
... on
|
120
|
+
... on FilesQuestion {
|
121
121
|
hintText
|
122
122
|
}
|
123
123
|
... on ActionButtonQuestion {
|
@@ -234,8 +234,8 @@ fragment SimpleAnswer on Answer {
|
|
234
234
|
... on ListAnswer {
|
235
235
|
listValue: value
|
236
236
|
}
|
237
|
-
... on
|
238
|
-
|
237
|
+
... on FilesAnswer {
|
238
|
+
filesValue: value {
|
239
239
|
id
|
240
240
|
uploadUrl
|
241
241
|
downloadUrl
|
package/addon/lib/field.js
CHANGED
@@ -13,7 +13,7 @@ import { cached } from "tracked-toolbox";
|
|
13
13
|
|
14
14
|
import { decodeId } from "@projectcaluma/ember-core/helpers/decode-id";
|
15
15
|
import saveDocumentDateAnswerMutation from "@projectcaluma/ember-form/gql/mutations/save-document-date-answer.graphql";
|
16
|
-
import
|
16
|
+
import saveDocumentFilesAnswerMutation from "@projectcaluma/ember-form/gql/mutations/save-document-files-answer.graphql";
|
17
17
|
import saveDocumentFloatAnswerMutation from "@projectcaluma/ember-form/gql/mutations/save-document-float-answer.graphql";
|
18
18
|
import saveDocumentIntegerAnswerMutation from "@projectcaluma/ember-form/gql/mutations/save-document-integer-answer.graphql";
|
19
19
|
import saveDocumentListAnswerMutation from "@projectcaluma/ember-form/gql/mutations/save-document-list-answer.graphql";
|
@@ -34,7 +34,7 @@ export const TYPE_MAP = {
|
|
34
34
|
DynamicChoiceQuestion: "StringAnswer",
|
35
35
|
TableQuestion: "TableAnswer",
|
36
36
|
FormQuestion: null,
|
37
|
-
|
37
|
+
FilesQuestion: "FilesAnswer",
|
38
38
|
StaticQuestion: null,
|
39
39
|
DateQuestion: "DateAnswer",
|
40
40
|
};
|
@@ -44,7 +44,7 @@ const MUTATION_MAP = {
|
|
44
44
|
IntegerAnswer: saveDocumentIntegerAnswerMutation,
|
45
45
|
StringAnswer: saveDocumentStringAnswerMutation,
|
46
46
|
ListAnswer: saveDocumentListAnswerMutation,
|
47
|
-
|
47
|
+
FilesAnswer: saveDocumentFilesAnswerMutation,
|
48
48
|
DateAnswer: saveDocumentDateAnswerMutation,
|
49
49
|
TableAnswer: saveDocumentTableAnswerMutation,
|
50
50
|
};
|
@@ -810,11 +810,11 @@ export default class Field extends Base {
|
|
810
810
|
/**
|
811
811
|
* Dummy method for the validation of file uploads.
|
812
812
|
*
|
813
|
-
* @method
|
813
|
+
* @method _validateFilesQuestion
|
814
814
|
* @return {Boolean} Always returns true
|
815
815
|
* @private
|
816
816
|
*/
|
817
|
-
|
817
|
+
_validateFilesQuestion() {
|
818
818
|
return true;
|
819
819
|
}
|
820
820
|
|
@@ -1 +1 @@
|
|
1
|
-
export { default } from "@projectcaluma/ember-form/components/cf-field/input/
|
1
|
+
export { default } from "@projectcaluma/ember-form/components/cf-field/input/files";
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@projectcaluma/ember-form",
|
3
|
-
"version": "11.0.0-beta.
|
3
|
+
"version": "11.0.0-beta.22",
|
4
4
|
"description": "Ember addon for rendering Caluma forms.",
|
5
5
|
"keywords": [
|
6
6
|
"ember-addon"
|
@@ -15,16 +15,16 @@
|
|
15
15
|
},
|
16
16
|
"dependencies": {
|
17
17
|
"@ember/string": "^3.0.0",
|
18
|
-
"@embroider/macros": "^1.
|
19
|
-
"@embroider/util": "^1.
|
18
|
+
"@embroider/macros": "^1.8.3",
|
19
|
+
"@embroider/util": "^1.8.3",
|
20
20
|
"@glimmer/component": "^1.1.2",
|
21
21
|
"@glimmer/tracking": "^1.1.2",
|
22
|
-
"@projectcaluma/ember-core": "^11.0.0-beta.
|
23
|
-
"ember-apollo-client": "
|
22
|
+
"@projectcaluma/ember-core": "^11.0.0-beta.9",
|
23
|
+
"ember-apollo-client": "~4.0.2",
|
24
24
|
"ember-auto-import": "^2.4.2",
|
25
25
|
"ember-autoresize-modifier": "^0.5.0",
|
26
26
|
"ember-cli-babel": "^7.26.11",
|
27
|
-
"ember-cli-htmlbars": "^6.0
|
27
|
+
"ember-cli-htmlbars": "^6.1.0",
|
28
28
|
"ember-cli-showdown": "^6.0.1",
|
29
29
|
"ember-composable-helpers": "^5.0.0",
|
30
30
|
"ember-concurrency": "^2.2.1",
|
@@ -34,21 +34,21 @@
|
|
34
34
|
"ember-math-helpers": "^2.18.2",
|
35
35
|
"ember-pikaday": "^4.0.0",
|
36
36
|
"ember-power-select": "^5.0.4",
|
37
|
-
"ember-resources": "^
|
37
|
+
"ember-resources": "^5.1.1",
|
38
38
|
"ember-uikit": "^5.1.3",
|
39
39
|
"ember-validators": "^4.1.2",
|
40
40
|
"graphql": "^15.8.0",
|
41
41
|
"jexl": "^2.3.0",
|
42
42
|
"lodash.isequal": "^4.5.0",
|
43
|
-
"luxon": "^
|
43
|
+
"luxon": "^3.0.1",
|
44
44
|
"tracked-toolbox": "^1.2.3"
|
45
45
|
},
|
46
46
|
"devDependencies": {
|
47
47
|
"@ember/optional-features": "2.0.0",
|
48
48
|
"@ember/test-helpers": "2.8.1",
|
49
|
-
"@embroider/test-setup": "1.
|
50
|
-
"@faker-js/faker": "7.
|
51
|
-
"@projectcaluma/ember-testing": "11.0.0-beta.
|
49
|
+
"@embroider/test-setup": "1.8.3",
|
50
|
+
"@faker-js/faker": "7.3.0",
|
51
|
+
"@projectcaluma/ember-testing": "11.0.0-beta.10",
|
52
52
|
"@projectcaluma/ember-workflow": "^11.0.0-beta.7",
|
53
53
|
"broccoli-asset-rev": "3.0.0",
|
54
54
|
"ember-cli": "3.28.5",
|
@@ -73,7 +73,7 @@
|
|
73
73
|
"qunit": "2.19.1",
|
74
74
|
"qunit-dom": "2.0.0",
|
75
75
|
"uuid": "8.3.2",
|
76
|
-
"webpack": "5.
|
76
|
+
"webpack": "5.74.0"
|
77
77
|
},
|
78
78
|
"peerDependencies": {
|
79
79
|
"@projectcaluma/ember-workflow": "^11.0.0-beta.7"
|
@@ -1,32 +0,0 @@
|
|
1
|
-
<div class="uk-flex-middle uk-grid-divider uk-grid-column-small" uk-grid>
|
2
|
-
<div uk-form-custom="target: true">
|
3
|
-
|
4
|
-
<input
|
5
|
-
type="file"
|
6
|
-
name={{@field.pk}}
|
7
|
-
id={{@field.pk}}
|
8
|
-
disabled={{@disabled}}
|
9
|
-
{{on "change" this.save}}
|
10
|
-
/>
|
11
|
-
<UkButton disabled={{@disabled}}>
|
12
|
-
{{t "caluma.form.selectFile"}}
|
13
|
-
</UkButton>
|
14
|
-
</div>
|
15
|
-
{{#if (and this.downloadUrl this.downloadName)}}
|
16
|
-
<div>
|
17
|
-
<UkButton
|
18
|
-
data-test-download-link
|
19
|
-
@color="link"
|
20
|
-
@onClick={{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>
|
@@ -1,89 +0,0 @@
|
|
1
|
-
import { action } from "@ember/object";
|
2
|
-
import { inject as service } from "@ember/service";
|
3
|
-
import Component from "@glimmer/component";
|
4
|
-
import { queryManager } from "ember-apollo-client";
|
5
|
-
import fetch from "fetch";
|
6
|
-
|
7
|
-
import removeAnswerMutation from "@projectcaluma/ember-form/gql/mutations/remove-answer.graphql";
|
8
|
-
import getFileAnswerInfoQuery from "@projectcaluma/ember-form/gql/queries/fileanswer-info.graphql";
|
9
|
-
|
10
|
-
export default class CfFieldInputFileComponent extends Component {
|
11
|
-
@service intl;
|
12
|
-
|
13
|
-
@queryManager apollo;
|
14
|
-
|
15
|
-
get downloadUrl() {
|
16
|
-
return this.args.field?.answer?.value?.downloadUrl;
|
17
|
-
}
|
18
|
-
|
19
|
-
get downloadName() {
|
20
|
-
return this.args.field?.answer?.value?.name;
|
21
|
-
}
|
22
|
-
|
23
|
-
@action
|
24
|
-
async download() {
|
25
|
-
const { downloadUrl } = await this.apollo.query(
|
26
|
-
{
|
27
|
-
query: getFileAnswerInfoQuery,
|
28
|
-
variables: { id: this.args.field.answer.raw.id },
|
29
|
-
fetchPolicy: "network-only",
|
30
|
-
},
|
31
|
-
"node.fileValue"
|
32
|
-
);
|
33
|
-
|
34
|
-
if (downloadUrl) {
|
35
|
-
window.open(downloadUrl, "_blank");
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
@action
|
40
|
-
async save({ target }) {
|
41
|
-
const file = target.files[0];
|
42
|
-
|
43
|
-
if (!file) {
|
44
|
-
return;
|
45
|
-
}
|
46
|
-
|
47
|
-
const { fileValue } = await this.args.onSave(file.name);
|
48
|
-
|
49
|
-
try {
|
50
|
-
const response = await fetch(fileValue.uploadUrl, {
|
51
|
-
method: "PUT",
|
52
|
-
body: file,
|
53
|
-
});
|
54
|
-
|
55
|
-
if (!response.ok) {
|
56
|
-
throw new Error();
|
57
|
-
}
|
58
|
-
|
59
|
-
this.args.field.answer.value = {
|
60
|
-
name: file.name,
|
61
|
-
downloadUrl: fileValue.downloadUrl,
|
62
|
-
};
|
63
|
-
} catch (error) {
|
64
|
-
await this.args.onSave(null);
|
65
|
-
this.args.field._errors = [{ type: "uploadFailed" }];
|
66
|
-
} finally {
|
67
|
-
// eslint-disable-next-line require-atomic-updates
|
68
|
-
target.value = "";
|
69
|
-
}
|
70
|
-
}
|
71
|
-
|
72
|
-
@action
|
73
|
-
async delete() {
|
74
|
-
try {
|
75
|
-
await this.apollo.mutate({
|
76
|
-
mutation: removeAnswerMutation,
|
77
|
-
variables: {
|
78
|
-
input: {
|
79
|
-
answer: this.args.field.answer.uuid,
|
80
|
-
},
|
81
|
-
},
|
82
|
-
});
|
83
|
-
|
84
|
-
await this.args.onSave(null);
|
85
|
-
} catch (error) {
|
86
|
-
this.args.field._errors = [{ type: "deleteFailed" }];
|
87
|
-
}
|
88
|
-
}
|
89
|
-
}
|