@umbraco-cms/backoffice 14.0.0--preview004-d0befea1 → 14.0.0--preview004-cc87bfe3

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.
Files changed (18) hide show
  1. package/dist-cms/custom-elements.json +78 -0
  2. package/dist-cms/packages/core/modal/token/import-dictionary-modal.token.d.ts +1 -1
  3. package/dist-cms/packages/core/tree/file-system-tree.store.js +4 -1
  4. package/dist-cms/packages/dictionary/dictionary/components/dictionary-item-input/dictionary-item-input.context.d.ts +6 -0
  5. package/dist-cms/packages/dictionary/dictionary/components/dictionary-item-input/dictionary-item-input.context.js +7 -0
  6. package/dist-cms/packages/dictionary/dictionary/components/dictionary-item-input/dictionary-item-input.element.d.ts +50 -0
  7. package/dist-cms/packages/dictionary/dictionary/components/dictionary-item-input/dictionary-item-input.element.js +134 -0
  8. package/dist-cms/packages/dictionary/dictionary/components/index.d.ts +1 -0
  9. package/dist-cms/packages/dictionary/dictionary/components/index.js +1 -0
  10. package/dist-cms/packages/dictionary/dictionary/entity-actions/export/export.action.js +16 -5
  11. package/dist-cms/packages/dictionary/dictionary/entity-actions/import/import-dictionary-modal.element.d.ts +6 -6
  12. package/dist-cms/packages/dictionary/dictionary/entity-actions/import/import-dictionary-modal.element.js +150 -127
  13. package/dist-cms/packages/dictionary/dictionary/entity-actions/import/import.action.js +3 -9
  14. package/dist-cms/packages/dictionary/dictionary/index.d.ts +1 -0
  15. package/dist-cms/packages/dictionary/dictionary/index.js +1 -0
  16. package/dist-cms/tsconfig.build.tsbuildinfo +1 -1
  17. package/dist-cms/vscode-html-custom-data.json +27 -1
  18. package/package.json +1 -1
@@ -4,159 +4,182 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { UmbDictionaryRepository } from '../../repository/dictionary.repository.js';
7
+ import '../../components/dictionary-item-input/dictionary-item-input.element.js';
8
8
  import { css, html, customElement, query, state, when } from '../../../../../external/lit/index.js';
9
9
  import { UmbTextStyles } from '../../../../../shared/style/index.js';
10
10
  import { UmbModalBaseElement, } from '../../../../core/modal/index.js';
11
+ import { UmbId } from '../../../../core/id/index.js';
11
12
  export let UmbImportDictionaryModalLayout = class UmbImportDictionaryModalLayout extends UmbModalBaseElement {
13
+ #fileReader;
14
+ #fileContent = [];
15
+ #handleClose() {
16
+ this.modalContext?.reject();
17
+ }
18
+ #submit() {
19
+ // TODO: Gotta do a temp file upload before submitting, so that the server can use it
20
+ console.log('submit:', this._temporaryFileId, this._parentId);
21
+ //this.modalContext?.submit({ temporaryFileId: this._temporaryFileId, parentId: this._parentId });
22
+ }
12
23
  constructor() {
13
- super(...arguments);
14
- this._showUploadView = true;
15
- this._showImportView = false;
16
- this._showErrorView = false;
17
- this._selection = [];
18
- this.#detailRepo = new UmbDictionaryRepository(this);
24
+ super();
25
+ this.#fileReader = new FileReader();
26
+ this.#fileReader.onload = (e) => {
27
+ if (typeof e.target?.result === 'string') {
28
+ const fileContent = e.target.result;
29
+ this.#dictionaryItemBuilder(fileContent);
30
+ }
31
+ };
19
32
  }
20
- static { this.styles = [
21
- UmbTextStyles,
22
- css `
23
- uui-input {
24
- width: 100%;
25
- }
26
- `,
27
- ]; }
28
- #detailRepo;
29
- async #importDictionary() {
30
- if (!this._uploadedDictionaryTempId)
31
- return;
32
- this.modalContext?.submit({
33
- temporaryFileId: this._uploadedDictionaryTempId,
34
- parentId: this._selection[0],
35
- });
33
+ connectedCallback() {
34
+ super.connectedCallback();
35
+ this._parentId = this.data?.unique ?? undefined;
36
36
  }
37
- #handleClose() {
38
- this.modalContext?.reject();
37
+ #dictionaryItemBuilder(htmlString) {
38
+ const parser = new DOMParser();
39
+ const doc = parser.parseFromString(htmlString, 'text/xml');
40
+ const elements = doc.childNodes;
41
+ this.#fileContent = this.#makeDictionaryItems(elements);
42
+ this.requestUpdate();
39
43
  }
40
- #submitForm() {
41
- this._form?.requestSubmit();
44
+ #makeDictionaryItems(nodeList) {
45
+ const items = [];
46
+ const list = [];
47
+ nodeList.forEach((node) => {
48
+ if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'DictionaryItem') {
49
+ list.push(node);
50
+ }
51
+ });
52
+ list.forEach((item) => {
53
+ items.push({
54
+ name: item.getAttribute('Name') ?? '',
55
+ children: this.#makeDictionaryItems(item.childNodes) ?? undefined,
56
+ });
57
+ });
58
+ return items;
42
59
  }
43
- async #handleSubmit(e) {
60
+ #onUpload(e) {
44
61
  e.preventDefault();
45
- if (!this._form.checkValidity())
46
- return;
47
62
  const formData = new FormData(this._form);
48
- const uploadData = {
49
- temporaryFileId: formData.get('file')?.toString() ?? '',
50
- };
51
- // TODO: fix this upload experience. We need to update our form so it gets temporary file id from the server:
52
- const { data } = await this.#detailRepo.upload(uploadData);
53
- if (!data)
54
- return;
55
- this._uploadedDictionaryTempId = data;
56
- // TODO: We need to find another way to gather the data of the uploaded dictionary, to represent the dictionaryItems? See further below.
57
- //this._uploadedDictionary = data;
58
- if (!this._uploadedDictionaryTempId) {
59
- this._showErrorView = true;
60
- this._showImportView = false;
61
- return;
63
+ const file = formData.get('file');
64
+ this.#fileReader.readAsText(file);
65
+ this._temporaryFileId = file ? UmbId.new() : undefined;
66
+ }
67
+ #onParentChange(event) {
68
+ this._parentId = event.target.selectedIds[0] || undefined;
69
+ //console.log((event.target as UmbDictionaryItemInputElement).selectedIds[0] || undefined);
70
+ }
71
+ async #onFileInput() {
72
+ requestAnimationFrame(() => {
73
+ this._form.requestSubmit();
74
+ });
75
+ }
76
+ #onClear() {
77
+ this._temporaryFileId = '';
78
+ }
79
+ render() {
80
+ return html ` <umb-body-layout headline=${this.localize.term('general_import')}>
81
+ <uui-box>
82
+ ${when(this._temporaryFileId, () => this.#renderImportDestination(), () => this.#renderUploadZone())}
83
+ </uui-box>
84
+ <uui-button
85
+ slot="actions"
86
+ type="button"
87
+ label=${this.localize.term('general_cancel')}
88
+ @click=${this.#handleClose}></uui-button>
89
+ </umb-body-layout>`;
90
+ }
91
+ #renderFileContents(items) {
92
+ return html `${items.map((item) => {
93
+ return html `${item.name}
94
+ <div>${this.#renderFileContents(item.children)}</div>`;
95
+ })}`;
96
+ }
97
+ #renderImportDestination() {
98
+ return html `
99
+ <div id="wrapper">
100
+ <div>
101
+ <strong><umb-localize key="visuallyHiddenTexts_dictionaryItems">Dictionary items</umb-localize>:</strong>
102
+ <div id="item-list">${this.#renderFileContents(this.#fileContent)}</div>
103
+ </div>
104
+ <div>
105
+ <strong><umb-localize key="actions_chooseWhereToImport">Choose where to import</umb-localize>:</strong>
106
+ Work in progress<br />
107
+ ${this._parentId
108
+ // TODO
109
+ // <umb-dictionary-item-input
110
+ // @change=${this.#onParentChange}
111
+ // .selectedIds=${this._parentId ? [this._parentId] : []}
112
+ // max="1">
113
+ // </umb-dictionary-item-input>
62
114
  }
63
- this._showErrorView = false;
64
- this._showUploadView = false;
65
- this._showImportView = true;
115
+ </div>
116
+
117
+ ${this.#renderNavigate()}
118
+ </div>
119
+ `;
66
120
  }
67
- /*
68
- #handleSelectionChange(e: CustomEvent) {
69
- e.stopPropagation();
70
- const element = e.target as UmbTreeElement;
71
- this._selection = element.selection;
121
+ #renderNavigate() {
122
+ return html `<div id="nav">
123
+ <uui-button label=${this.localize.term('general_import')} look="secondary" @click=${this.#onClear}>
124
+ <uui-icon name="icon-arrow-left"></uui-icon>
125
+ ${this.localize.term('general_back')}
126
+ </uui-button>
127
+ <uui-button
128
+ type="button"
129
+ label=${this.localize.term('general_import')}
130
+ look="primary"
131
+ @click=${this.#submit}></uui-button>
132
+ </div>`;
72
133
  }
73
- */
74
- #renderUploadView() {
75
- return html `<p>
76
- To import a dictionary item, find the ".udt" file on your computer by clicking the "Import" button (you'll be
77
- asked for confirmation on the next screen)
78
- </p>
134
+ #renderUploadZone() {
135
+ return html `<umb-localize key="dictionary_importDictionaryItemHelp"></umb-localize>
79
136
  <uui-form>
80
- <form id="form" name="form" @submit=${this.#handleSubmit}>
137
+ <form id="form" name="form" @submit=${this.#onUpload}>
81
138
  <uui-form-layout-item>
82
- <uui-label for="file" slot="label" required>File</uui-label>
83
- <div>
84
- <uui-input-file
85
- accept=".udt"
86
- name="file"
87
- id="file"
88
- required
89
- required-message="File is required"></uui-input-file>
90
- </div>
139
+ <uui-label for="file" slot="label" required>${this.localize.term('formFileUpload_pickFile')}</uui-label>
140
+ <uui-input-file
141
+ accept=".udt"
142
+ name="file"
143
+ id="file"
144
+ @input=${this.#onFileInput}
145
+ required
146
+ required-message=${this.localize.term('formFileUpload_pickFile')}></uui-input-file>
91
147
  </uui-form-layout-item>
92
148
  </form>
93
- </uui-form>
94
- <uui-button slot="actions" type="button" label="Cancel" @click=${this.#handleClose}></uui-button>
95
- <uui-button slot="actions" type="button" label="Import" look="primary" @click=${this.#submitForm}></uui-button>`;
149
+ </uui-form>`;
96
150
  }
97
- /// TODO => Tree view needs isolation and single-select option
98
- #renderImportView() {
99
- //TODO: gather this data in some other way, we cannot use the feedback from the server anymore. can we use info about the file directly? or is a change to the end point required?
100
- /*
101
- if (!this._uploadedDictionary?.dictionaryItems) return;
102
-
103
- return html`
104
- <b>Dictionary items</b>
105
- <ul>
106
- ${repeat(
107
- this._uploadedDictionary.dictionaryItems,
108
- (item) => item.name,
109
- (item) => html`<li>${item.name}</li>`
110
- )}
111
- </ul>
112
- <hr />
113
- <b>Choose where to import dictionary items (optional)</b>
114
- <umb-tree
115
- alias="Umb.Tree.Dictionary"
116
- @selection-change=${this.#handleSelectionChange}
117
- .selection=${this._selection}
118
- selectable></umb-tree>
151
+ static { this.styles = [
152
+ UmbTextStyles,
153
+ css `
154
+ uui-input {
155
+ width: 100%;
156
+ }
157
+ #item-list {
158
+ padding: var(--uui-size-3) var(--uui-size-4);
159
+ border: 1px solid var(--uui-color-border);
160
+ border-radius: var(--uui-border-radius);
161
+ }
162
+ #item-list div {
163
+ padding-left: 20px;
164
+ }
119
165
 
120
- <uui-button slot="actions" type="button" label="Cancel" @click=${this.#handleClose}></uui-button>
121
- <uui-button
122
- slot="actions"
123
- type="button"
124
- label="Import"
125
- look="primary"
126
- @click=${this.#importDictionary}></uui-button>
127
- `;
128
- */
129
- }
130
- // TODO => Determine what to display when dictionary import/upload fails
131
- #renderErrorView() {
132
- return html `Something went wrong`;
133
- }
134
- render() {
135
- return html ` <umb-body-layout headline="Import">
136
- ${when(this._showUploadView, () => this.#renderUploadView())}
137
- ${when(this._showImportView, () => this.#renderImportView())}
138
- ${when(this._showErrorView, () => this.#renderErrorView())}
139
- </umb-body-layout>`;
140
- }
166
+ #wrapper {
167
+ display: flex;
168
+ flex-direction: column;
169
+ gap: var(--uui-size-3);
170
+ }
171
+ `,
172
+ ]; }
141
173
  };
142
- __decorate([
143
- query('#form')
144
- ], UmbImportDictionaryModalLayout.prototype, "_form", void 0);
145
174
  __decorate([
146
175
  state()
147
- ], UmbImportDictionaryModalLayout.prototype, "_uploadedDictionaryTempId", void 0);
176
+ ], UmbImportDictionaryModalLayout.prototype, "_parentId", void 0);
148
177
  __decorate([
149
178
  state()
150
- ], UmbImportDictionaryModalLayout.prototype, "_showUploadView", void 0);
179
+ ], UmbImportDictionaryModalLayout.prototype, "_temporaryFileId", void 0);
151
180
  __decorate([
152
- state()
153
- ], UmbImportDictionaryModalLayout.prototype, "_showImportView", void 0);
154
- __decorate([
155
- state()
156
- ], UmbImportDictionaryModalLayout.prototype, "_showErrorView", void 0);
157
- __decorate([
158
- state()
159
- ], UmbImportDictionaryModalLayout.prototype, "_selection", void 0);
181
+ query('#form')
182
+ ], UmbImportDictionaryModalLayout.prototype, "_form", void 0);
160
183
  UmbImportDictionaryModalLayout = __decorate([
161
184
  customElement('umb-import-dictionary-modal')
162
185
  ], UmbImportDictionaryModalLayout);
@@ -1,4 +1,4 @@
1
- import { UmbTextStyles } from "../../../../../shared/style/index.js";
1
+ import { UmbTextStyles } from '../../../../../shared/style/index.js';
2
2
  import { UmbEntityActionBase } from '../../../../core/entity-action/index.js';
3
3
  import { UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_IMPORT_DICTIONARY_MODAL, } from '../../../../core/modal/index.js';
4
4
  export default class UmbImportDictionaryEntityAction extends UmbEntityActionBase {
@@ -11,16 +11,10 @@ export default class UmbImportDictionaryEntityAction extends UmbEntityActionBase
11
11
  });
12
12
  }
13
13
  async execute() {
14
- // TODO: what to do if modal service is not available?
15
14
  if (!this.#modalContext)
16
15
  return;
17
16
  const modalContext = this.#modalContext?.open(UMB_IMPORT_DICTIONARY_MODAL, { unique: this.unique });
18
- // TODO: get type from modal result
19
- const { temporaryFileId, parentId } = await modalContext.onSubmit();
20
- if (!temporaryFileId)
21
- return;
22
- const result = await this.repository?.import(temporaryFileId, parentId);
23
- // TODO => get location header to route to new item
24
- console.log(result);
17
+ const { parentId, temporaryFileId } = await modalContext.onSubmit();
18
+ await this.repository?.import(temporaryFileId, parentId);
25
19
  }
26
20
  }
@@ -1,2 +1,3 @@
1
1
  export * from './repository/index.js';
2
2
  export * from './tree/index.js';
3
+ export * from './components/index.js';
@@ -1,2 +1,3 @@
1
1
  export * from './repository/index.js';
2
2
  export * from './tree/index.js';
3
+ export * from './components/index.js';