@umbraco-cms/backoffice 14.0.0-3aaba617 → 14.0.0-41f35ef1

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 (46) hide show
  1. package/dist-cms/custom-elements.json +94 -35
  2. package/dist-cms/mocks/data/template.data.d.ts +5 -23
  3. package/dist-cms/mocks/data/template.data.js +44 -21
  4. package/dist-cms/mocks/handlers/template.handlers.js +4 -0
  5. package/dist-cms/packages/core/components/button-with-dropdown/button-with-dropdown.element.d.ts +2 -0
  6. package/dist-cms/packages/core/components/button-with-dropdown/button-with-dropdown.element.js +4 -4
  7. package/dist-cms/packages/core/components/code-block/code-block.element.d.ts +6 -1
  8. package/dist-cms/packages/core/components/code-block/code-block.element.js +93 -19
  9. package/dist-cms/packages/core/components/index.d.ts +1 -0
  10. package/dist-cms/packages/core/components/index.js +1 -1
  11. package/dist-cms/packages/core/modal/token/dictionary-item-picker-modal.token.d.ts +0 -1
  12. package/dist-cms/packages/core/modal/token/dictionary-item-picker-modal.token.js +1 -2
  13. package/dist-cms/packages/core/tree/tree.context.js +8 -11
  14. package/dist-cms/packages/templating/components/insert-menu/templating-insert-menu.element.js +3 -31
  15. package/dist-cms/packages/templating/modals/insert-choose-type-sidebar.element.d.ts +2 -4
  16. package/dist-cms/packages/templating/modals/insert-choose-type-sidebar.element.js +5 -27
  17. package/dist-cms/packages/templating/modals/insert-section-modal/insert-section-input.element.js +1 -0
  18. package/dist-cms/packages/templating/modals/insert-section-modal/insert-section-modal.element.js +5 -4
  19. package/dist-cms/packages/templating/modals/manifests.d.ts +0 -1
  20. package/dist-cms/packages/templating/modals/manifests.js +0 -7
  21. package/dist-cms/packages/templating/templates/components/alias-input/alias-input.js +1 -1
  22. package/dist-cms/packages/templating/templates/index.d.ts +2 -0
  23. package/dist-cms/packages/templating/templates/index.js +2 -0
  24. package/dist-cms/packages/templating/templates/manifests.d.ts +1 -1
  25. package/dist-cms/packages/templating/templates/manifests.js +2 -0
  26. package/dist-cms/packages/templating/templates/modals/manifests.d.ts +3 -0
  27. package/dist-cms/packages/templating/templates/modals/manifests.js +10 -0
  28. package/dist-cms/packages/templating/templates/modals/modal-tokens.d.ts +3 -0
  29. package/dist-cms/packages/templating/templates/modals/modal-tokens.js +6 -0
  30. package/dist-cms/packages/templating/templates/modals/query-builder/query-builder-filter.element.d.ts +24 -0
  31. package/dist-cms/packages/templating/templates/modals/query-builder/query-builder-filter.element.js +157 -0
  32. package/dist-cms/packages/templating/templates/modals/query-builder/query-builder.element.d.ts +28 -0
  33. package/dist-cms/packages/templating/templates/modals/query-builder/query-builder.element.js +277 -0
  34. package/dist-cms/packages/templating/templates/repository/sources/template.query-builder.server.data.d.ts +33 -0
  35. package/dist-cms/packages/templating/templates/repository/sources/template.query-builder.server.data.js +37 -0
  36. package/dist-cms/packages/templating/templates/repository/template.repository.d.ts +11 -7
  37. package/dist-cms/packages/templating/templates/repository/template.repository.js +28 -14
  38. package/dist-cms/packages/templating/templates/workspace/template-workspace-editor.element.js +21 -3
  39. package/dist-cms/packages/templating/templates/workspace/template-workspace.context.js +2 -1
  40. package/dist-cms/packages/templating/templates/workspace/template-workspace.element.d.ts +1 -0
  41. package/dist-cms/packages/templating/templates/workspace/template-workspace.element.js +2 -1
  42. package/dist-cms/tsconfig.tsbuildinfo +1 -1
  43. package/dist-cms/vscode-html-custom-data.json +40 -7
  44. package/package.json +1 -1
  45. package/dist-cms/packages/templating/modals/insert-value-sidebar.element.d.ts +0 -19
  46. package/dist-cms/packages/templating/modals/insert-value-sidebar.element.js +0 -135
@@ -0,0 +1,277 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { UmbTemplateRepository } from '../../repository/template.repository.js';
8
+ import { UUITextStyles } from '../../../../../external/uui/index.js';
9
+ import { css, html, customElement, state, query, queryAll } from '../../../../../external/lit/index.js';
10
+ import { UmbModalBaseElement } from '../../../../../shared/modal/index.js';
11
+ import { UMB_DOCUMENT_PICKER_MODAL, UMB_MODAL_MANAGER_CONTEXT_TOKEN, } from '../../../../core/modal/index.js';
12
+ import { UmbDocumentRepository } from '../../../../documents/documents/index.js';
13
+ import './query-builder-filter.element.js';
14
+ var SortOrder;
15
+ (function (SortOrder) {
16
+ SortOrder["Ascending"] = "ascending";
17
+ SortOrder["Descending"] = "descending";
18
+ })(SortOrder || (SortOrder = {}));
19
+ let UmbChooseInsertTypeModalElement = class UmbChooseInsertTypeModalElement extends UmbModalBaseElement {
20
+ #documentRepository;
21
+ #modalManagerContext;
22
+ #templateRepository;
23
+ constructor() {
24
+ super();
25
+ this._queryRequest = {};
26
+ this._selectedRootContentName = 'all pages';
27
+ this._defaultSortDirection = SortOrder.Descending;
28
+ this.#postTemplateQuery = async () => {
29
+ const { data, error } = await this.#templateRepository.postTemplateQueryExecute({
30
+ requestBody: this._queryRequest,
31
+ });
32
+ if (data)
33
+ this._templateQuery = { ...data };
34
+ };
35
+ this.#openDocumentPicker = () => {
36
+ this.#modalManagerContext
37
+ ?.open(UMB_DOCUMENT_PICKER_MODAL)
38
+ .onSubmit()
39
+ .then((result) => {
40
+ this.#updateQueryRequest({ rootContentId: result.selection[0] });
41
+ if (result.selection.length > 0 && result.selection[0] === null) {
42
+ this._selectedRootContentName = 'all pages';
43
+ return;
44
+ }
45
+ if (result.selection.length > 0) {
46
+ this.#getDocumentItem(result.selection);
47
+ return;
48
+ }
49
+ });
50
+ };
51
+ this.#addFilterElement = () => {
52
+ this._filterContainer?.appendChild(this.#createFilterElement());
53
+ };
54
+ this.#updateFilters = () => {
55
+ this.#updateQueryRequest({ filters: Array.from(this._filterElements)?.map((filter) => filter.filter) ?? [] });
56
+ };
57
+ this.#removeFilter = (event) => {
58
+ const target = event.target;
59
+ this._filterContainer?.removeChild(target);
60
+ this.#updateFilters();
61
+ };
62
+ this.#templateRepository = new UmbTemplateRepository(this);
63
+ this.#documentRepository = new UmbDocumentRepository(this);
64
+ this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => {
65
+ this.#modalManagerContext = instance;
66
+ });
67
+ this.#init();
68
+ }
69
+ #init() {
70
+ this.#getTemplateQuerySettings();
71
+ this.#postTemplateQuery();
72
+ }
73
+ #close() {
74
+ this.modalContext?.reject();
75
+ }
76
+ #submit() {
77
+ this.modalContext?.submit({
78
+ value: this._templateQuery?.queryExpression ?? '',
79
+ });
80
+ }
81
+ #updateQueryRequest(update) {
82
+ this._queryRequest = { ...this._queryRequest, ...update };
83
+ this.#postTemplateQuery();
84
+ }
85
+ async #getTemplateQuerySettings() {
86
+ const { data, error } = await this.#templateRepository.getTemplateQuerySettings();
87
+ if (data)
88
+ this._queryBuilderSettings = data;
89
+ }
90
+ #postTemplateQuery;
91
+ #openDocumentPicker;
92
+ async #getDocumentItem(ids) {
93
+ const { data, error } = await this.#documentRepository.requestItemsLegacy(ids);
94
+ if (data) {
95
+ this._selectedRootContentName = data[0].name;
96
+ }
97
+ }
98
+ #createFilterElement() {
99
+ const filterElement = document.createElement('umb-query-builder-filter');
100
+ filterElement.settings = this._queryBuilderSettings;
101
+ filterElement.classList.add('row');
102
+ filterElement.addEventListener('add-filter', this.#addFilterElement);
103
+ filterElement.addEventListener('remove-filter', this.#removeFilter);
104
+ filterElement.addEventListener('update-query', this.#updateFilters);
105
+ return filterElement;
106
+ }
107
+ #setContentType(event) {
108
+ const target = event.target;
109
+ this.#updateQueryRequest({ contentTypeAlias: target.value ?? '' });
110
+ this._contentTypeDropdown.closePopover();
111
+ }
112
+ #setSortProperty(event) {
113
+ const target = event.target;
114
+ if (!this._queryRequest.sort)
115
+ this.#setSortDirection();
116
+ this.#updateQueryRequest({
117
+ sort: { ...this._queryRequest.sort, propertyAlias: target.value ?? '' },
118
+ });
119
+ this._sortDropdown.closePopover();
120
+ }
121
+ #setSortDirection() {
122
+ if (!this._queryRequest.sort?.direction) {
123
+ this.#updateQueryRequest({
124
+ sort: { ...this._queryRequest.sort, direction: this._defaultSortDirection },
125
+ });
126
+ return;
127
+ }
128
+ this.#updateQueryRequest({
129
+ sort: {
130
+ ...this._queryRequest.sort,
131
+ direction: this._queryRequest.sort?.direction === SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending,
132
+ },
133
+ });
134
+ }
135
+ #addFilterElement;
136
+ #updateFilters;
137
+ #removeFilter;
138
+ render() {
139
+ return html `
140
+ <umb-body-layout headline="Query builder">
141
+ <div id="main">
142
+ <uui-box>
143
+ <div class="row">
144
+ I want
145
+ <umb-button-with-dropdown look="outline" id="content-type-dropdown" label="Choose content type"
146
+ >${this._queryRequest?.contentTypeAlias ?? 'all content'}
147
+ <uui-combobox-list slot="dropdown" @change=${this.#setContentType} class="options-list">
148
+ <uui-combobox-list-option value="">all content</uui-combobox-list-option>
149
+ ${this._queryBuilderSettings?.contentTypeAliases?.map((alias) => html `<uui-combobox-list-option .value=${alias}
150
+ >content of type "${alias}"</uui-combobox-list-option
151
+ >`)}
152
+ </uui-combobox-list></umb-button-with-dropdown
153
+ >
154
+ from
155
+ <uui-button look="outline" @click=${this.#openDocumentPicker} label="Choose root content"
156
+ >${this._selectedRootContentName}
157
+ </uui-button>
158
+ </div>
159
+ <div id="filter-container">
160
+ <umb-query-builder-filter
161
+ unremovable
162
+ class="row"
163
+ .settings=${this._queryBuilderSettings}
164
+ @add-filter=${this.#addFilterElement}
165
+ @update-query=${this.#updateFilters}
166
+ @remove-filter=${this.#removeFilter}></umb-query-builder-filter>
167
+ </div>
168
+ <div class="row">
169
+ ordered by
170
+ <umb-button-with-dropdown look="outline" id="sort-dropdown" label="Property alias"
171
+ >${this._queryRequest.sort?.propertyAlias ?? ''}
172
+ <uui-combobox-list slot="dropdown" @change=${this.#setSortProperty} class="options-list">
173
+ ${this._queryBuilderSettings?.properties?.map((property) => html `<uui-combobox-list-option .value=${property.alias ?? ''}
174
+ >${property.alias}</uui-combobox-list-option
175
+ >`)}
176
+ </uui-combobox-list></umb-button-with-dropdown
177
+ >
178
+
179
+ ${this._queryRequest.sort?.propertyAlias
180
+ ? html `<uui-button look="outline" @click=${this.#setSortDirection}
181
+ >${this._queryRequest.sort.direction ?? this._defaultSortDirection}</uui-button
182
+ >`
183
+ : ''}
184
+ </div>
185
+ <div class="row">
186
+ <span id="results-count"
187
+ >${this._templateQuery?.resultCount ?? 0} items returned, in ${this._templateQuery?.executionTime ?? 0}
188
+ ms</span
189
+ >
190
+ </div>
191
+ <umb-code-block language="C#" copy> ${this._templateQuery?.queryExpression ?? ''} </umb-code-block>
192
+ </uui-box>
193
+ </div>
194
+
195
+ <div slot="actions">
196
+ <uui-button @click=${this.#close} look="secondary" label="Close">Close</uui-button>
197
+ <uui-button @click=${this.#submit} look="primary" color="positive" label="Submit">Submit</uui-button>
198
+ </div>
199
+ </umb-body-layout>
200
+ `;
201
+ }
202
+ static { this.styles = [
203
+ UUITextStyles,
204
+ css `
205
+ :host {
206
+ display: block;
207
+ color: var(--uui-color-text);
208
+ --umb-header-layout-height: 70px;
209
+ }
210
+
211
+ #main {
212
+ box-sizing: border-box;
213
+ height: calc(
214
+ 100dvh - var(--umb-header-layout-height) - var(--umb-footer-layout-height) - 2 * var(--uui-size-layout-1)
215
+ );
216
+ }
217
+
218
+ .options-list {
219
+ min-width: 30ch;
220
+ background-color: var(--uui-color-surface);
221
+ box-shadow: var(--uui-shadow-depth-3);
222
+ }
223
+
224
+ uui-combobox-list-option {
225
+ padding: 8px 20px;
226
+ }
227
+
228
+ .row {
229
+ display: flex;
230
+ gap: 10px;
231
+ border-bottom: 1px solid #f3f3f5;
232
+ align-items: center;
233
+ padding: 20px 0;
234
+ }
235
+
236
+ #filter-container {
237
+ flex-direction: column;
238
+ justify-content: flex-start;
239
+ }
240
+
241
+ #results-count {
242
+ font-weight: bold;
243
+ }
244
+ `,
245
+ ]; }
246
+ };
247
+ __decorate([
248
+ query('#content-type-dropdown')
249
+ ], UmbChooseInsertTypeModalElement.prototype, "_contentTypeDropdown", void 0);
250
+ __decorate([
251
+ query('#sort-dropdown')
252
+ ], UmbChooseInsertTypeModalElement.prototype, "_sortDropdown", void 0);
253
+ __decorate([
254
+ query('#filter-container')
255
+ ], UmbChooseInsertTypeModalElement.prototype, "_filterContainer", void 0);
256
+ __decorate([
257
+ queryAll('umb-query-builder-filter')
258
+ ], UmbChooseInsertTypeModalElement.prototype, "_filterElements", void 0);
259
+ __decorate([
260
+ state()
261
+ ], UmbChooseInsertTypeModalElement.prototype, "_templateQuery", void 0);
262
+ __decorate([
263
+ state()
264
+ ], UmbChooseInsertTypeModalElement.prototype, "_queryRequest", void 0);
265
+ __decorate([
266
+ state()
267
+ ], UmbChooseInsertTypeModalElement.prototype, "_queryBuilderSettings", void 0);
268
+ __decorate([
269
+ state()
270
+ ], UmbChooseInsertTypeModalElement.prototype, "_selectedRootContentName", void 0);
271
+ __decorate([
272
+ state()
273
+ ], UmbChooseInsertTypeModalElement.prototype, "_defaultSortDirection", void 0);
274
+ UmbChooseInsertTypeModalElement = __decorate([
275
+ customElement('umb-templating-query-builder-modal')
276
+ ], UmbChooseInsertTypeModalElement);
277
+ export default UmbChooseInsertTypeModalElement;
@@ -0,0 +1,33 @@
1
+ import { TemplateQueryExecuteModel } from '../../../../../external/backend-api/index.js';
2
+ import type { UmbControllerHostElement } from '../../../../../libs/controller-api/index.js';
3
+ /**
4
+ * A data source for the Template Query Builder that fetches data from the server
5
+ * @export
6
+ * @class UmbTemplateQueryBuilderServerDataSource
7
+ */
8
+ export declare class UmbTemplateQueryBuilderServerDataSource {
9
+ #private;
10
+ /**
11
+ * Creates an instance of UmbTemplateQueryBuilderServerDataSource.
12
+ * @param {UmbControllerHostElement} host
13
+ * @memberof UmbTemplateQueryBuilderServerDataSource
14
+ */
15
+ constructor(host: UmbControllerHostElement);
16
+ /**
17
+ * Fetches the query builder settings from the server
18
+ *
19
+ * @return {*}
20
+ * @memberof UmbTemplateQueryBuilderServerDataSource
21
+ */
22
+ getTemplateQuerySettings(): Promise<import("../../../../../shared/repository/index.js").DataSourceResponse<import("../../../../../external/backend-api/index.js").TemplateQuerySettingsResponseModel>>;
23
+ /**
24
+ * Executes a query builder query on the server
25
+ *
26
+ * @param {{ requestBody?: TemplateQueryExecuteModel }} { requestBody }
27
+ * @return {*}
28
+ * @memberof UmbTemplateQueryBuilderServerDataSource
29
+ */
30
+ postTemplateQueryExecute({ requestBody }: {
31
+ requestBody?: TemplateQueryExecuteModel;
32
+ }): Promise<import("../../../../../shared/repository/index.js").DataSourceResponse<import("../../../../../external/backend-api/index.js").TemplateQueryResultResponseModel>>;
33
+ }
@@ -0,0 +1,37 @@
1
+ import { TemplateResource } from '../../../../../external/backend-api/index.js';
2
+ import { tryExecuteAndNotify } from '../../../../../shared/resources/index.js';
3
+ /**
4
+ * A data source for the Template Query Builder that fetches data from the server
5
+ * @export
6
+ * @class UmbTemplateQueryBuilderServerDataSource
7
+ */
8
+ export class UmbTemplateQueryBuilderServerDataSource {
9
+ #host;
10
+ /**
11
+ * Creates an instance of UmbTemplateQueryBuilderServerDataSource.
12
+ * @param {UmbControllerHostElement} host
13
+ * @memberof UmbTemplateQueryBuilderServerDataSource
14
+ */
15
+ constructor(host) {
16
+ this.#host = host;
17
+ }
18
+ /**
19
+ * Fetches the query builder settings from the server
20
+ *
21
+ * @return {*}
22
+ * @memberof UmbTemplateQueryBuilderServerDataSource
23
+ */
24
+ async getTemplateQuerySettings() {
25
+ return tryExecuteAndNotify(this.#host, TemplateResource.getTemplateQuerySettings());
26
+ }
27
+ /**
28
+ * Executes a query builder query on the server
29
+ *
30
+ * @param {{ requestBody?: TemplateQueryExecuteModel }} { requestBody }
31
+ * @return {*}
32
+ * @memberof UmbTemplateQueryBuilderServerDataSource
33
+ */
34
+ async postTemplateQueryExecute({ requestBody }) {
35
+ return tryExecuteAndNotify(this.#host, TemplateResource.postTemplateQueryExecute({ requestBody }));
36
+ }
37
+ }
@@ -1,7 +1,7 @@
1
1
  import { Observable } from '../../../../external/rxjs/index.js';
2
2
  import type { UmbDetailRepository, UmbItemRepository, UmbTreeRepository } from '../../../../shared/repository/index.js';
3
3
  import type { UmbControllerHostElement } from '../../../../libs/controller-api/index.js';
4
- import type { CreateTemplateRequestModel, EntityTreeItemResponseModel, ItemResponseModelBaseModel, TemplateItemResponseModel, TemplateResponseModel, UpdateTemplateRequestModel } from '../../../../external/backend-api/index.js';
4
+ import type { CreateTemplateRequestModel, EntityTreeItemResponseModel, ItemResponseModelBaseModel, TemplateItemResponseModel, TemplateQueryExecuteModel, TemplateResponseModel, UpdateTemplateRequestModel } from '../../../../external/backend-api/index.js';
5
5
  export declare class UmbTemplateRepository implements UmbTreeRepository<EntityTreeItemResponseModel>, UmbDetailRepository<CreateTemplateRequestModel, string, UpdateTemplateRequestModel, TemplateResponseModel>, UmbItemRepository<TemplateItemResponseModel> {
6
6
  #private;
7
7
  constructor(host: UmbControllerHostElement);
@@ -38,12 +38,6 @@ export declare class UmbTemplateRepository implements UmbTreeRepository<EntityTr
38
38
  error: import("../../../../external/backend-api/index.js").ApiError | import("../../../../external/backend-api/index.js").CancelError | undefined;
39
39
  asObservable: () => Observable<EntityTreeItemResponseModel[]>;
40
40
  }>;
41
- requestItems(ids: Array<string>): Promise<{
42
- data: TemplateItemResponseModel[] | undefined;
43
- error: import("../../../../external/backend-api/index.js").ApiError | import("../../../../external/backend-api/index.js").CancelError | undefined;
44
- asObservable: () => Observable<TemplateItemResponseModel[]>;
45
- }>;
46
- items(uniques: string[]): Promise<Observable<ItemResponseModelBaseModel[]>>;
47
41
  byId(id: string): Promise<Observable<any>>;
48
42
  create(template: CreateTemplateRequestModel): Promise<{
49
43
  error: import("../../../../external/backend-api/index.js").ApiError | import("../../../../external/backend-api/index.js").CancelError | undefined;
@@ -54,4 +48,14 @@ export declare class UmbTemplateRepository implements UmbTreeRepository<EntityTr
54
48
  delete(id: string): Promise<{
55
49
  error: import("../../../../external/backend-api/index.js").ApiError | import("../../../../external/backend-api/index.js").CancelError | undefined;
56
50
  }>;
51
+ getTemplateQuerySettings(): Promise<import("../../../../shared/repository/index.js").DataSourceResponse<import("../../../../external/backend-api/index.js").TemplateQuerySettingsResponseModel>>;
52
+ postTemplateQueryExecute({ requestBody }: {
53
+ requestBody?: TemplateQueryExecuteModel;
54
+ }): Promise<import("../../../../shared/repository/index.js").DataSourceResponse<import("../../../../external/backend-api/index.js").TemplateQueryResultResponseModel>>;
55
+ requestItems(ids: Array<string>): Promise<{
56
+ data: TemplateItemResponseModel[] | undefined;
57
+ error: import("../../../../external/backend-api/index.js").ApiError | import("../../../../external/backend-api/index.js").CancelError | undefined;
58
+ asObservable: () => Observable<TemplateItemResponseModel[]>;
59
+ }>;
60
+ items(uniques: string[]): Promise<Observable<ItemResponseModelBaseModel[]>>;
57
61
  }
@@ -4,6 +4,7 @@ import { UmbTemplateTreeServerDataSource } from './sources/template.tree.server.
4
4
  import { UmbTemplateDetailServerDataSource } from './sources/template.detail.server.data.js';
5
5
  import { UMB_TEMPLATE_ITEM_STORE_CONTEXT_TOKEN } from './template-item.store.js';
6
6
  import { UmbTemplateItemServerDataSource } from './sources/template.item.server.data.js';
7
+ import { UmbTemplateQueryBuilderServerDataSource } from './sources/template.query-builder.server.data.js';
7
8
  import { UMB_NOTIFICATION_CONTEXT_TOKEN } from '../../../core/notification/index.js';
8
9
  import { UmbContextConsumerController } from '../../../../libs/context-api/index.js';
9
10
  export class UmbTemplateRepository {
@@ -16,11 +17,13 @@ export class UmbTemplateRepository {
16
17
  #treeStore;
17
18
  #store;
18
19
  #notificationContext;
20
+ #queryBuilderSource;
19
21
  constructor(host) {
20
22
  this.#host = host;
21
23
  this.#treeDataSource = new UmbTemplateTreeServerDataSource(this.#host);
22
24
  this.#detailDataSource = new UmbTemplateDetailServerDataSource(this.#host);
23
25
  this.#itemSource = new UmbTemplateItemServerDataSource(this.#host);
26
+ this.#queryBuilderSource = new UmbTemplateQueryBuilderServerDataSource(this.#host);
24
27
  this.#init = Promise.all([
25
28
  new UmbContextConsumerController(this.#host, UMB_TEMPLATE_ITEM_STORE_CONTEXT_TOKEN, (instance) => {
26
29
  this.#itemStore = instance;
@@ -105,20 +108,6 @@ export class UmbTemplateRepository {
105
108
  }
106
109
  return { data, error, asObservable: () => this.#treeStore.items([id]) };
107
110
  }
108
- // ITEMS:
109
- async requestItems(ids) {
110
- if (!ids)
111
- throw new Error('Ids are missing');
112
- await this.#init;
113
- const { data, error } = await this.#itemSource.getItems(ids);
114
- if (data) {
115
- this.#itemStore?.appendItems(data);
116
- }
117
- return { data, error, asObservable: () => this.#itemStore.items(ids) };
118
- }
119
- async items(uniques) {
120
- throw new Error('items method is not implemented in UmbTemplateRepository');
121
- }
122
111
  async byId(id) {
123
112
  if (!id)
124
113
  throw new Error('Key is missing');
@@ -179,4 +168,29 @@ export class UmbTemplateRepository {
179
168
  this.#treeStore?.removeItem(id);
180
169
  return { error };
181
170
  }
171
+ //#endregion
172
+ //#region TEMPLATE_QUERY:
173
+ async getTemplateQuerySettings() {
174
+ await this.#init;
175
+ return this.#queryBuilderSource.getTemplateQuerySettings();
176
+ }
177
+ async postTemplateQueryExecute({ requestBody }) {
178
+ await this.#init;
179
+ return this.#queryBuilderSource.postTemplateQueryExecute({ requestBody });
180
+ }
181
+ //#endregion
182
+ //#region ITEMS:
183
+ async requestItems(ids) {
184
+ if (!ids)
185
+ throw new Error('Ids are missing');
186
+ await this.#init;
187
+ const { data, error } = await this.#itemSource.getItems(ids);
188
+ if (data) {
189
+ this.#itemStore?.appendItems(data);
190
+ }
191
+ return { data, error, asObservable: () => this.#itemStore.items(ids) };
192
+ }
193
+ async items(uniques) {
194
+ throw new Error('items method is not implemented in UmbTemplateRepository');
195
+ }
182
196
  }
@@ -5,6 +5,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { UMB_MODAL_TEMPLATING_INSERT_SECTION_MODAL } from '../../modals/insert-section-modal/insert-section-modal.element.js';
8
+ import { UMB_TEMPLATE_QUERY_BUILDER_MODAL } from '../modals/modal-tokens.js';
9
+ import { getQuerySnippet } from '../../utils.js';
8
10
  import { camelCase } from '../../../../external/lodash/index.js';
9
11
  import { UUITextStyles } from '../../../../external/uui/index.js';
10
12
  import { css, html, customElement, query, state, nothing } from '../../../../external/lit/index.js';
@@ -99,6 +101,13 @@ export let UmbTemplateWorkspaceEditorElement = class UmbTemplateWorkspaceEditorE
99
101
  this.#templateWorkspaceContext?.setMasterTemplate(data.selection[0] ?? '');
100
102
  });
101
103
  }
104
+ #openQueryBuilder() {
105
+ const queryBuilderModal = this._modalContext?.open(UMB_TEMPLATE_QUERY_BUILDER_MODAL);
106
+ queryBuilderModal?.onSubmit().then((queryBuilderModalResult) => {
107
+ if (queryBuilderModalResult.value)
108
+ this._codeEditor?.insert(getQuerySnippet(queryBuilderModalResult.value));
109
+ });
110
+ }
102
111
  #renderMasterTemplatePicker() {
103
112
  return html `
104
113
  <uui-button-group>
@@ -129,7 +138,12 @@ export let UmbTemplateWorkspaceEditorElement = class UmbTemplateWorkspaceEditorE
129
138
  render() {
130
139
  // TODO: add correct UI elements
131
140
  return html `<umb-workspace-editor alias="Umb.Workspace.Template">
132
- <uui-input placeholder="Enter name..." slot="header" .value=${this._name} @input=${this.#onNameInput}
141
+ <uui-input
142
+ placeholder="Enter name..."
143
+ slot="header"
144
+ .value=${this._name}
145
+ @input=${this.#onNameInput}
146
+ label="template name"
133
147
  ><umb-template-alias-input
134
148
  slot="append"
135
149
  .value=${this._alias ?? ''}
@@ -140,9 +154,13 @@ export let UmbTemplateWorkspaceEditorElement = class UmbTemplateWorkspaceEditorE
140
154
  ${this.#renderMasterTemplatePicker()}
141
155
  <div>
142
156
  <umb-templating-insert-menu @insert=${this.#insertSnippet}></umb-templating-insert-menu>
143
- <!-- <uui-button look="secondary" id="query-builder-button" label="Query builder">
157
+ <uui-button
158
+ look="secondary"
159
+ id="query-builder-button"
160
+ label="Query builder"
161
+ @click=${this.#openQueryBuilder}>
144
162
  <uui-icon name="umb:wand"></uui-icon>Query builder
145
- </uui-button> -->
163
+ </uui-button>
146
164
  <uui-button
147
165
  look="secondary"
148
166
  id="sections-button"
@@ -114,6 +114,7 @@ ${currentContent}`;
114
114
  else {
115
115
  this.repository.requestRootTreeItems();
116
116
  }
117
+ return;
117
118
  }
118
119
  if (template?.id) {
119
120
  await this.repository.save(template.id, {
@@ -121,7 +122,7 @@ ${currentContent}`;
121
122
  content: template.content,
122
123
  alias: template.alias,
123
124
  });
124
- this.repository.requestTreeItemsOf(this.#masterTemplate.value?.id ?? '');
125
+ this.repository.requestTreeItemsOf(this.#masterTemplate.value?.id ?? null);
125
126
  }
126
127
  }
127
128
  async create(parentId = null) {
@@ -1,5 +1,6 @@
1
1
  import type { UmbRoute } from '../../../../shared/router/index.js';
2
2
  import { UmbLitElement } from '../../../../shared/lit-element/index.js';
3
+ import '../../components/insert-menu/templating-insert-menu.element.js';
3
4
  import './template-workspace-editor.element.js';
4
5
  export declare class UmbTemplateWorkspaceElement extends UmbLitElement {
5
6
  #private;
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { UmbTemplateWorkspaceContext } from './template-workspace.context.js';
8
8
  import { html, customElement, state } from '../../../../external/lit/index.js';
9
9
  import { UmbLitElement } from '../../../../shared/lit-element/index.js';
10
+ import '../../components/insert-menu/templating-insert-menu.element.js';
10
11
  import './template-workspace-editor.element.js';
11
12
  export let UmbTemplateWorkspaceElement = class UmbTemplateWorkspaceElement extends UmbLitElement {
12
13
  constructor() {
@@ -20,7 +21,7 @@ export let UmbTemplateWorkspaceElement = class UmbTemplateWorkspaceElement exten
20
21
  component: () => this.#element,
21
22
  setup: (component, info) => {
22
23
  const parentKey = info.match.params.parentKey;
23
- this.#templateWorkspaceContext.create(parentKey);
24
+ this.#templateWorkspaceContext.create(parentKey === 'root' ? null : parentKey);
24
25
  },
25
26
  },
26
27
  {