@acorex/platform 20.6.0-next.18 → 20.6.0-next.19
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/fesm2022/acorex-platform-layout-entity.mjs +1134 -413
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +3 -2
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +4 -4
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-4nWLEm89.mjs → acorex-platform-themes-default-entity-master-list-view.component-BbACUabi.mjs} +406 -173
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-BbACUabi.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default.mjs +2 -2
- package/layout/entity/index.d.ts +168 -24
- package/layout/views/index.d.ts +1 -0
- package/package.json +1 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-4nWLEm89.mjs.map +0 -1
|
@@ -46,8 +46,15 @@ import { AXPDeviceService } from '@acorex/platform/core';
|
|
|
46
46
|
import { AXPSettingService, AXPCommonSettings } from '@acorex/platform/common';
|
|
47
47
|
import { isEqual } from 'lodash-es';
|
|
48
48
|
|
|
49
|
+
//#region ---- Constants ----
|
|
50
|
+
const ROOT_NODE_ID = 'all';
|
|
51
|
+
const LOADING_DELAY_MS = 300;
|
|
52
|
+
const DEFAULT_TEXT_FIELD = 'title';
|
|
53
|
+
const DEFAULT_VALUE_FIELD = 'id';
|
|
54
|
+
//#endregion
|
|
49
55
|
class AXPEntityCategoryComponent {
|
|
50
56
|
//#endregion
|
|
57
|
+
//#region ---- Constructor & Lifecycle ----
|
|
51
58
|
constructor() {
|
|
52
59
|
//#region ---- Services & Dependencies ----
|
|
53
60
|
this.entityResolver = inject(AXPEntityResolver);
|
|
@@ -59,19 +66,31 @@ class AXPEntityCategoryComponent {
|
|
|
59
66
|
this.vm = input.required(...(ngDevMode ? [{ debugName: "vm" }] : []));
|
|
60
67
|
this.tree = viewChild('tree', ...(ngDevMode ? [{ debugName: "tree" }] : []));
|
|
61
68
|
this.searchValue = input('', ...(ngDevMode ? [{ debugName: "searchValue" }] : []));
|
|
69
|
+
// Tree view inputs with defaults
|
|
70
|
+
this.selectMode = input('single', ...(ngDevMode ? [{ debugName: "selectMode" }] : []));
|
|
71
|
+
this.showCheckbox = input(false, ...(ngDevMode ? [{ debugName: "showCheckbox" }] : []));
|
|
72
|
+
this.selectionBehavior = input('intermediate', ...(ngDevMode ? [{ debugName: "selectionBehavior" }] : []));
|
|
73
|
+
this.dragArea = input('handler', ...(ngDevMode ? [{ debugName: "dragArea" }] : [])); //TODO FIX ACOREX
|
|
74
|
+
this.dragBehavior = input('none', ...(ngDevMode ? [{ debugName: "dragBehavior" }] : []));
|
|
75
|
+
this.showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
|
|
76
|
+
this.showChildrenBadge = input(false, ...(ngDevMode ? [{ debugName: "showChildrenBadge" }] : []));
|
|
77
|
+
this.expandedIcon = input('fa-solid fa-chevron-down', ...(ngDevMode ? [{ debugName: "expandedIcon" }] : []));
|
|
78
|
+
this.collapsedIcon = input('fa-solid fa-chevron-right', ...(ngDevMode ? [{ debugName: "collapsedIcon" }] : []));
|
|
79
|
+
this.indentSize = input(16, ...(ngDevMode ? [{ debugName: "indentSize" }] : []));
|
|
80
|
+
this.look = input('default', ...(ngDevMode ? [{ debugName: "look" }] : []));
|
|
62
81
|
//#endregion
|
|
63
82
|
//#region ---- Component State ----
|
|
64
83
|
this.isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
65
84
|
//#endregion
|
|
66
85
|
//#region ---- Private Properties ----
|
|
67
86
|
this.loadingTimeoutId = null;
|
|
68
|
-
this.LOADING_DELAY = 300; // Show skeleton only if loading takes more than 300ms
|
|
69
87
|
this.treeData = null;
|
|
70
88
|
this.treeConfig = null;
|
|
71
89
|
this.searchResults = null;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
this.
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region ---- Computed Properties ----
|
|
92
|
+
this.textField = computed(() => this.vm().entityDef.category?.textField || DEFAULT_TEXT_FIELD, ...(ngDevMode ? [{ debugName: "textField" }] : []));
|
|
93
|
+
this.valueField = computed(() => this.vm().entityDef.category?.valueField || DEFAULT_VALUE_FIELD, ...(ngDevMode ? [{ debugName: "valueField" }] : []));
|
|
75
94
|
this.categoryEntityKey = computed(() => {
|
|
76
95
|
const key = this.vm().entityDef.category?.entity;
|
|
77
96
|
if (!key) {
|
|
@@ -79,57 +98,45 @@ class AXPEntityCategoryComponent {
|
|
|
79
98
|
}
|
|
80
99
|
return key;
|
|
81
100
|
}, ...(ngDevMode ? [{ debugName: "categoryEntityKey" }] : []));
|
|
82
|
-
//#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region ---- Tree Data Source ----
|
|
103
|
+
/**
|
|
104
|
+
* Datasource callback for tree-view component.
|
|
105
|
+
* Provides lazy loading support for tree nodes.
|
|
106
|
+
*/
|
|
107
|
+
this.datasource = async (parentId) => {
|
|
108
|
+
if (!this.isTreeInitialized()) {
|
|
86
109
|
return [];
|
|
87
110
|
}
|
|
88
|
-
//
|
|
89
|
-
if (!
|
|
90
|
-
|
|
91
|
-
if (this.searchResults) {
|
|
92
|
-
const rootNode = await this.categoryTreeService.createRootNode(this.searchResults, this.treeConfig);
|
|
93
|
-
return [rootNode];
|
|
94
|
-
}
|
|
95
|
-
// Otherwise load root categories
|
|
96
|
-
const items = await this.categoryTreeService.loadRootCategories(this.treeData, this.treeConfig);
|
|
97
|
-
if (!items) {
|
|
98
|
-
return [];
|
|
99
|
-
}
|
|
100
|
-
const rootNode = await this.categoryTreeService.createRootNode(items, this.treeConfig);
|
|
101
|
-
return [rootNode];
|
|
111
|
+
// Load root nodes if no parent ID provided
|
|
112
|
+
if (!parentId) {
|
|
113
|
+
return await this.loadRootNodes();
|
|
102
114
|
}
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
id,
|
|
106
|
-
label: '',
|
|
107
|
-
data: {},
|
|
108
|
-
};
|
|
109
|
-
return await this.categoryTreeService.loadChildren(targetNode, this.treeData, this.treeConfig);
|
|
115
|
+
// Load children for the specified parent
|
|
116
|
+
return await this.loadChildNodes(parentId);
|
|
110
117
|
};
|
|
111
118
|
afterNextRender(() => {
|
|
112
|
-
this.
|
|
119
|
+
this.initializeTree();
|
|
113
120
|
});
|
|
114
121
|
}
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
//#endregion
|
|
123
|
+
//#region ---- Public Methods ----
|
|
124
|
+
/**
|
|
125
|
+
* Handles category search input changes
|
|
126
|
+
*/
|
|
127
|
+
async handleCategorySearchChange(event) {
|
|
128
|
+
if (!this.isTreeInitialized()) {
|
|
117
129
|
return;
|
|
118
130
|
}
|
|
119
131
|
this.setLoadingWithDelay(true);
|
|
120
132
|
try {
|
|
121
|
-
const items = await this.categoryTreeService.searchCategories(
|
|
133
|
+
const items = await this.categoryTreeService.searchCategories(event.value, this.treeData, this.treeConfig);
|
|
122
134
|
if (!items) {
|
|
123
135
|
this.clearLoadingState();
|
|
124
136
|
return;
|
|
125
137
|
}
|
|
126
|
-
// Store search results for datasource callback
|
|
127
138
|
this.searchResults = items;
|
|
128
|
-
|
|
129
|
-
const treeComponent = this.tree();
|
|
130
|
-
if (treeComponent) {
|
|
131
|
-
treeComponent.refresh?.();
|
|
132
|
-
}
|
|
139
|
+
this.refreshTree();
|
|
133
140
|
}
|
|
134
141
|
catch (error) {
|
|
135
142
|
console.error('Error searching categories:', error);
|
|
@@ -138,7 +145,89 @@ class AXPEntityCategoryComponent {
|
|
|
138
145
|
this.clearLoadingState();
|
|
139
146
|
}
|
|
140
147
|
}
|
|
141
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Handles node click events to apply category filters
|
|
150
|
+
*/
|
|
151
|
+
handleNodeClick(node) {
|
|
152
|
+
const nodeData = this.extractNodeData(node);
|
|
153
|
+
const applyConditions = this.vm().entityDef.category?.applyConditions || [];
|
|
154
|
+
const categoryFilters = this.buildCategoryFilters(nodeData, applyConditions);
|
|
155
|
+
const viewFilters = this.buildViewFilters();
|
|
156
|
+
this.vm().dataSource.filter({
|
|
157
|
+
filters: [...viewFilters, ...categoryFilters],
|
|
158
|
+
logic: 'and',
|
|
159
|
+
});
|
|
160
|
+
this.vm().dataSource.refresh();
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Handles node toggle events (expansion/collapse)
|
|
164
|
+
*/
|
|
165
|
+
async onNodeToggle(_event) {
|
|
166
|
+
// Tree component handles lazy loading via datasource callback
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region ---- CRUD Operations ----
|
|
170
|
+
/**
|
|
171
|
+
* Creates a new root category node
|
|
172
|
+
*/
|
|
173
|
+
async handleCreateRootClick(event) {
|
|
174
|
+
this.preventDefaultAndStopPropagation(event);
|
|
175
|
+
try {
|
|
176
|
+
const context = await this.executeCreateWorkflow(undefined);
|
|
177
|
+
await this.handleCreateResult(context, undefined);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
console.error('Error creating root category:', error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Creates a new child category under the given parent node
|
|
185
|
+
*/
|
|
186
|
+
async handleCreateChildClick(node, event) {
|
|
187
|
+
this.preventDefaultAndStopPropagation(event);
|
|
188
|
+
try {
|
|
189
|
+
const parentId = this.extractNodeId(node);
|
|
190
|
+
const context = await this.executeCreateWorkflow(parentId);
|
|
191
|
+
await this.handleCreateResult(context, parentId);
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
console.error('Error creating child category:', error);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Updates an existing category node
|
|
199
|
+
*/
|
|
200
|
+
async handleEditNodeClick(node, event) {
|
|
201
|
+
this.preventDefaultAndStopPropagation(event);
|
|
202
|
+
try {
|
|
203
|
+
const nodeData = this.extractNodeData(node);
|
|
204
|
+
const context = await this.executeModifyWorkflow(nodeData);
|
|
205
|
+
await this.handleModifyResult(context, node);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
console.error('Error editing category:', error);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Deletes a category node
|
|
213
|
+
*/
|
|
214
|
+
async handleDeleteNodeClick(node, event) {
|
|
215
|
+
this.preventDefaultAndStopPropagation(event);
|
|
216
|
+
try {
|
|
217
|
+
const nodeData = this.extractNodeData(node);
|
|
218
|
+
const context = await this.executeDeleteWorkflow(nodeData);
|
|
219
|
+
await this.handleDeleteResult(context, node);
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
console.error('Error deleting category:', error);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region ---- Private Tree Management Methods ----
|
|
227
|
+
/**
|
|
228
|
+
* Initializes the category tree data structure
|
|
229
|
+
*/
|
|
230
|
+
async initializeTree() {
|
|
142
231
|
this.setLoadingWithDelay(true);
|
|
143
232
|
try {
|
|
144
233
|
const entityKey = this.categoryEntityKey();
|
|
@@ -152,12 +241,10 @@ class AXPEntityCategoryComponent {
|
|
|
152
241
|
this.clearLoadingState();
|
|
153
242
|
return;
|
|
154
243
|
}
|
|
155
|
-
//
|
|
244
|
+
// Set parent key from entity definition
|
|
156
245
|
if (this.treeData.categoryEntityDef?.parentKey) {
|
|
157
246
|
this.treeConfig.parentKey = this.treeData.categoryEntityDef.parentKey;
|
|
158
247
|
}
|
|
159
|
-
// Tree will be loaded via datasource callback
|
|
160
|
-
// Clear any previous search results
|
|
161
248
|
this.searchResults = null;
|
|
162
249
|
}
|
|
163
250
|
catch (error) {
|
|
@@ -167,170 +254,316 @@ class AXPEntityCategoryComponent {
|
|
|
167
254
|
this.clearLoadingState();
|
|
168
255
|
}
|
|
169
256
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
.view()
|
|
190
|
-
.conditions.map((i) => ({ ...i, field: i.name }));
|
|
191
|
-
this.vm().dataSource.filter({
|
|
192
|
-
filters: [...viewFilters, ...filters],
|
|
193
|
-
logic: 'and',
|
|
194
|
-
});
|
|
195
|
-
this.vm().dataSource.refresh();
|
|
257
|
+
/**
|
|
258
|
+
* Loads root nodes for the tree
|
|
259
|
+
*/
|
|
260
|
+
async loadRootNodes() {
|
|
261
|
+
if (!this.isTreeInitialized()) {
|
|
262
|
+
return [];
|
|
263
|
+
}
|
|
264
|
+
// Use search results if available
|
|
265
|
+
if (this.searchResults) {
|
|
266
|
+
const rootNode = await this.categoryTreeService.createRootNode(this.searchResults, this.treeConfig);
|
|
267
|
+
return [rootNode];
|
|
268
|
+
}
|
|
269
|
+
// Load root categories
|
|
270
|
+
const items = await this.categoryTreeService.loadRootCategories(this.treeData, this.treeConfig);
|
|
271
|
+
if (!items) {
|
|
272
|
+
return [];
|
|
273
|
+
}
|
|
274
|
+
const rootNode = await this.categoryTreeService.createRootNode(items, this.treeConfig);
|
|
275
|
+
return [rootNode];
|
|
196
276
|
}
|
|
197
|
-
/**
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
277
|
+
/**
|
|
278
|
+
* Loads child nodes for a given parent ID
|
|
279
|
+
*/
|
|
280
|
+
async loadChildNodes(parentId) {
|
|
281
|
+
if (!this.isTreeInitialized()) {
|
|
282
|
+
return [];
|
|
283
|
+
}
|
|
284
|
+
const targetNode = {
|
|
285
|
+
['id']: parentId,
|
|
286
|
+
['title']: '',
|
|
287
|
+
['data']: {},
|
|
288
|
+
};
|
|
289
|
+
return await this.categoryTreeService.loadChildren(targetNode, this.treeData, this.treeConfig);
|
|
203
290
|
}
|
|
204
|
-
/**
|
|
205
|
-
|
|
206
|
-
|
|
291
|
+
/**
|
|
292
|
+
* Refreshes the tree view component
|
|
293
|
+
*/
|
|
294
|
+
refreshTree() {
|
|
295
|
+
const treeComponent = this.tree();
|
|
296
|
+
if (treeComponent) {
|
|
297
|
+
treeComponent.refresh();
|
|
298
|
+
}
|
|
207
299
|
}
|
|
208
|
-
/**
|
|
300
|
+
/**
|
|
301
|
+
* Refreshes tree after CRUD operations
|
|
302
|
+
*/
|
|
209
303
|
async refreshAfterChange(parentId) {
|
|
210
|
-
// Clear search results to show all categories
|
|
211
304
|
this.searchResults = null;
|
|
212
|
-
|
|
305
|
+
this.refreshTree();
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Adds a new node to the tree after create operation
|
|
309
|
+
*/
|
|
310
|
+
async addNodeToTree(entityData, parentId) {
|
|
311
|
+
if (!this.isTreeInitialized()) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
213
314
|
const treeComponent = this.tree();
|
|
214
|
-
if (treeComponent) {
|
|
215
|
-
|
|
315
|
+
if (!treeComponent) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const newNode = this.categoryTreeService.convertToTreeNode(entityData, this.treeConfig);
|
|
319
|
+
if (parentId) {
|
|
320
|
+
await this.addChildNode(treeComponent, parentId, newNode);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
await this.addRootNode(treeComponent, newNode);
|
|
216
324
|
}
|
|
217
325
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
async
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
326
|
+
/**
|
|
327
|
+
* Adds a child node to a parent node
|
|
328
|
+
*/
|
|
329
|
+
async addChildNode(treeComponent, parentId, newNode) {
|
|
330
|
+
const parentNode = treeComponent.findNode(parentId);
|
|
331
|
+
if (!parentNode) {
|
|
332
|
+
await this.refreshAfterChange(parentId);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
if (!treeComponent.isNodeExpanded(parentId)) {
|
|
336
|
+
await treeComponent.expandNode(parentId);
|
|
337
|
+
}
|
|
338
|
+
treeComponent.addChild(parentId, newNode);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Adds a root node to the tree
|
|
342
|
+
*/
|
|
343
|
+
async addRootNode(treeComponent, newNode) {
|
|
344
|
+
const rootNode = treeComponent.findNode(ROOT_NODE_ID);
|
|
345
|
+
if (!rootNode) {
|
|
229
346
|
await this.refreshAfterChange();
|
|
347
|
+
return;
|
|
230
348
|
}
|
|
231
|
-
|
|
232
|
-
|
|
349
|
+
if (!treeComponent.isNodeExpanded(ROOT_NODE_ID)) {
|
|
350
|
+
await treeComponent.expandNode(ROOT_NODE_ID);
|
|
233
351
|
}
|
|
352
|
+
treeComponent.addChild(ROOT_NODE_ID, newNode);
|
|
234
353
|
}
|
|
235
|
-
/**
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const data = {};
|
|
242
|
-
if (parentKey) {
|
|
243
|
-
data[parentKey] = node.id;
|
|
244
|
-
}
|
|
245
|
-
await this.workflow.execute('create-entity', {
|
|
246
|
-
entity: this.getCategoryEntityKey(),
|
|
247
|
-
data,
|
|
248
|
-
options: { process: { redirect: false, canCreateNewOne: true } },
|
|
249
|
-
});
|
|
250
|
-
await this.refreshAfterChange(node.id);
|
|
354
|
+
/**
|
|
355
|
+
* Updates an existing node in the tree after edit operation
|
|
356
|
+
*/
|
|
357
|
+
async updateNodeInTree(nodeId, entityData) {
|
|
358
|
+
if (!this.isTreeInitialized()) {
|
|
359
|
+
return;
|
|
251
360
|
}
|
|
252
|
-
|
|
253
|
-
|
|
361
|
+
const treeComponent = this.tree();
|
|
362
|
+
if (!treeComponent) {
|
|
363
|
+
return;
|
|
254
364
|
}
|
|
365
|
+
const existingNode = treeComponent.findNode(nodeId);
|
|
366
|
+
if (!existingNode) {
|
|
367
|
+
await this.refreshNodeParent(entityData);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const updatedNode = this.categoryTreeService.convertToTreeNode(entityData, this.treeConfig);
|
|
371
|
+
const updates = {
|
|
372
|
+
['title']: updatedNode['title'],
|
|
373
|
+
['data']: updatedNode['data'],
|
|
374
|
+
['childrenCount']: updatedNode['childrenCount'],
|
|
375
|
+
['icon']: updatedNode['icon'],
|
|
376
|
+
};
|
|
377
|
+
treeComponent.editNode(nodeId, updates);
|
|
255
378
|
}
|
|
256
|
-
/**
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
entity: this.getCategoryEntityKey(),
|
|
264
|
-
data: nodeData,
|
|
265
|
-
options: { layout: { size: 'md' } },
|
|
266
|
-
});
|
|
267
|
-
const parentKey = this.treeData?.categoryEntityDef?.parentKey;
|
|
268
|
-
if (parentKey && nodeData[parentKey]) {
|
|
269
|
-
await this.refreshAfterChange(nodeData[parentKey]);
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
await this.refreshAfterChange();
|
|
273
|
-
}
|
|
379
|
+
/**
|
|
380
|
+
* Removes a node from the tree after delete operation
|
|
381
|
+
*/
|
|
382
|
+
async removeNodeFromTree(nodeId) {
|
|
383
|
+
const treeComponent = this.tree();
|
|
384
|
+
if (!treeComponent) {
|
|
385
|
+
return;
|
|
274
386
|
}
|
|
275
|
-
|
|
276
|
-
|
|
387
|
+
const nodeToDelete = treeComponent.findNode(nodeId);
|
|
388
|
+
if (!nodeToDelete) {
|
|
389
|
+
await this.refreshAfterChange();
|
|
390
|
+
return;
|
|
277
391
|
}
|
|
392
|
+
treeComponent.removeNode(nodeId);
|
|
278
393
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
});
|
|
290
|
-
const parentKey = this.treeData?.categoryEntityDef?.parentKey;
|
|
291
|
-
if (parentKey && nodeData[parentKey]) {
|
|
292
|
-
await this.refreshAfterChange(nodeData[parentKey]);
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
await this.refreshAfterChange();
|
|
296
|
-
}
|
|
394
|
+
//#endregion
|
|
395
|
+
//#region ---- Workflow Execution Methods ----
|
|
396
|
+
/**
|
|
397
|
+
* Executes the create entity workflow
|
|
398
|
+
*/
|
|
399
|
+
async executeCreateWorkflow(parentId) {
|
|
400
|
+
const entityKey = this.categoryEntityKey();
|
|
401
|
+
const workflowData = {};
|
|
402
|
+
if (parentId && this.treeData?.categoryEntityDef?.parentKey) {
|
|
403
|
+
workflowData[this.treeData.categoryEntityDef.parentKey] = parentId;
|
|
297
404
|
}
|
|
298
|
-
|
|
299
|
-
|
|
405
|
+
return await this.workflow.execute('create-entity', {
|
|
406
|
+
entity: entityKey,
|
|
407
|
+
data: Object.keys(workflowData).length > 0 ? workflowData : undefined,
|
|
408
|
+
options: { process: { redirect: false, canCreateNewOne: !!parentId } },
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Executes the modify entity workflow
|
|
413
|
+
*/
|
|
414
|
+
async executeModifyWorkflow(nodeData) {
|
|
415
|
+
return await this.workflow.execute('quick-modify-entity', {
|
|
416
|
+
entity: this.categoryEntityKey(),
|
|
417
|
+
data: nodeData,
|
|
418
|
+
options: { layout: { size: 'md' } },
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Executes the delete entity workflow
|
|
423
|
+
*/
|
|
424
|
+
async executeDeleteWorkflow(nodeData) {
|
|
425
|
+
return await this.workflow.execute('delete-entity', {
|
|
426
|
+
entity: this.categoryEntityKey(),
|
|
427
|
+
data: nodeData,
|
|
428
|
+
options: { process: { showResult: true } },
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Handles the result of a create operation
|
|
433
|
+
*/
|
|
434
|
+
async handleCreateResult(context, parentId) {
|
|
435
|
+
const result = context.getOutput('result');
|
|
436
|
+
if (!result || !this.isTreeInitialized()) {
|
|
437
|
+
await this.refreshAfterChange(parentId);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const newEntityData = context.getVariable('data');
|
|
441
|
+
if (newEntityData) {
|
|
442
|
+
await this.addNodeToTree(newEntityData, parentId);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
await this.refreshAfterChange(parentId);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Handles the result of a modify operation
|
|
450
|
+
*/
|
|
451
|
+
async handleModifyResult(context, node) {
|
|
452
|
+
const result = context.getOutput('result');
|
|
453
|
+
if (!result || !this.isTreeInitialized()) {
|
|
454
|
+
await this.refreshNodeParent(this.extractNodeData(node));
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
const updatedEntityData = context.getVariable('data');
|
|
458
|
+
if (updatedEntityData) {
|
|
459
|
+
await this.updateNodeInTree(this.extractNodeId(node), updatedEntityData);
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
await this.refreshNodeParent(this.extractNodeData(node));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Handles the result of a delete operation
|
|
467
|
+
*/
|
|
468
|
+
async handleDeleteResult(context, node) {
|
|
469
|
+
const result = context.getOutput('result');
|
|
470
|
+
if (result) {
|
|
471
|
+
await this.removeNodeFromTree(this.extractNodeId(node));
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
await this.refreshNodeParent(this.extractNodeData(node));
|
|
300
475
|
}
|
|
301
476
|
}
|
|
302
477
|
//#endregion
|
|
478
|
+
//#region ---- Utility Methods ----
|
|
479
|
+
/**
|
|
480
|
+
* Checks if tree data and config are initialized
|
|
481
|
+
*/
|
|
482
|
+
isTreeInitialized() {
|
|
483
|
+
return !!(this.treeData && this.treeConfig);
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Extracts node data from a tree node
|
|
487
|
+
*/
|
|
488
|
+
extractNodeData(node) {
|
|
489
|
+
return (node['data'] || node);
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Extracts node ID from a tree node
|
|
493
|
+
*/
|
|
494
|
+
extractNodeId(node) {
|
|
495
|
+
return String(node['id'] ?? '');
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Builds category filters from node data and apply conditions
|
|
499
|
+
*/
|
|
500
|
+
buildCategoryFilters(nodeData, applyConditions) {
|
|
501
|
+
return applyConditions
|
|
502
|
+
.map((condition) => {
|
|
503
|
+
const value = nodeData[condition.value];
|
|
504
|
+
if (value === 'all' || value == null) {
|
|
505
|
+
return null;
|
|
506
|
+
}
|
|
507
|
+
return {
|
|
508
|
+
field: condition.name,
|
|
509
|
+
value,
|
|
510
|
+
operator: condition.operator,
|
|
511
|
+
};
|
|
512
|
+
})
|
|
513
|
+
.filter((item) => item !== null);
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Builds view filters from view conditions
|
|
517
|
+
*/
|
|
518
|
+
buildViewFilters() {
|
|
519
|
+
return this.vm()
|
|
520
|
+
.view()
|
|
521
|
+
.conditions.map((condition) => ({ ...condition, field: condition.name }));
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Refreshes the parent node of the given entity data
|
|
525
|
+
*/
|
|
526
|
+
async refreshNodeParent(entityData) {
|
|
527
|
+
const parentKey = this.treeData?.categoryEntityDef?.parentKey;
|
|
528
|
+
const parentId = parentKey && entityData[parentKey] ? entityData[parentKey] : undefined;
|
|
529
|
+
await this.refreshAfterChange(parentId);
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Prevents default behavior and stops event propagation
|
|
533
|
+
*/
|
|
534
|
+
preventDefaultAndStopPropagation(event) {
|
|
535
|
+
event.nativeEvent.preventDefault();
|
|
536
|
+
event.nativeEvent.stopPropagation();
|
|
537
|
+
}
|
|
538
|
+
//#endregion
|
|
303
539
|
//#region ---- Loading State Management ----
|
|
304
540
|
/**
|
|
305
|
-
*
|
|
541
|
+
* Sets loading state with delay to avoid flickering for fast responses
|
|
306
542
|
*/
|
|
307
543
|
setLoadingWithDelay(loading) {
|
|
308
|
-
if (loading) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
// Only show skeleton if loading takes more than LOADING_DELAY ms
|
|
314
|
-
this.loadingTimeoutId = setTimeout(() => {
|
|
315
|
-
this.isLoading.set(true);
|
|
316
|
-
this.loadingTimeoutId = null;
|
|
317
|
-
}, this.LOADING_DELAY);
|
|
544
|
+
if (!loading) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
if (this.loadingTimeoutId) {
|
|
548
|
+
clearTimeout(this.loadingTimeoutId);
|
|
318
549
|
}
|
|
550
|
+
this.loadingTimeoutId = setTimeout(() => {
|
|
551
|
+
this.isLoading.set(true);
|
|
552
|
+
this.loadingTimeoutId = null;
|
|
553
|
+
}, LOADING_DELAY_MS);
|
|
319
554
|
}
|
|
320
555
|
/**
|
|
321
|
-
*
|
|
556
|
+
* Clears loading state and cancels any pending timeout
|
|
322
557
|
*/
|
|
323
558
|
clearLoadingState() {
|
|
324
|
-
// Cancel the delayed loading state if it hasn't been set yet
|
|
325
559
|
if (this.loadingTimeoutId) {
|
|
326
560
|
clearTimeout(this.loadingTimeoutId);
|
|
327
561
|
this.loadingTimeoutId = null;
|
|
328
562
|
}
|
|
329
|
-
// Clear the loading state
|
|
330
563
|
this.isLoading.set(false);
|
|
331
564
|
}
|
|
332
565
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
333
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityCategoryComponent, isStandalone: true, selector: "axp-entity-category", inputs: { vm: { classPropertyName: "vm", publicName: "vm", isSignal: true, isRequired: true, transformFunction: null }, searchValue: { classPropertyName: "searchValue", publicName: "searchValue", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-layout-header>\n <axp-layout-title>{{\n vm().entityDef.category?.title || '@general:terms.classification.category' | translate | async\n }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n (onValueChanged)=\"handleCategorySearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"'@general:terms.interface.category.search.placeholder' | translate | async\"\n >\n </ax-search-box>\n </axp-layout-toolbar>\n</axp-layout-header>\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeData) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\">\n <ax-tree-view\n [datasource]=\"datasource\"\n [showCheckbox]=\"false\"\n [showIcons]=\"true\"\n [itemTemplate]=\"itemTemplate\"\n (onNodeToggle)=\"onNodeToggle($event)\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:terms.interface.category.search.no-records.title'\"\n [description]=\"'@general:terms.interface.category.search.no-records.description'\"\n >\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.add-new.title' | translate | async\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let item = node.data || node;\n @let textField = vm().entityDef.category?.textField || 'title';\n @let valueField = vm().entityDef.category?.valueField || 'id';\n @let itemId = item[valueField] || node.id;\n @let itemTitle = item[textField] || node.label;\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden\"\n (click)=\"handleNodeClick(node)\"\n >\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon\n class=\"fas fa-folder\"\n [style.color]=\"item.color ?? 'rgba(var(--ax-sys-color-warning-500), 1)'\"\n ></ax-icon>\n <span class=\"ax-truncate\">{{ itemTitle }}</span>\n </div>\n @if (itemId && itemId !== 'all') {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n (onClick)=\"handleCreateChildClick(node, $event)\"\n look=\"blank\"\n color=\"default\"\n text=\"Add New Child\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n <ax-button-item (onClick)=\"handleEditNodeClick(node, $event)\" look=\"blank\" text=\"Edit\">\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(node, $event)\"\n color=\"danger\"\n look=\"blank\"\n text=\"Delete\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n } @else if (itemId === 'all') {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n", styles: ["ax-tree-view-item .ax-tree-view-items{width:100%;min-width:0px}ax-tree-view-item .ax-tree-view-items>div{width:100%}ax-tree-view-item .ax-state-tree-view-active{background-color:rgb(var(--ax-sys-color-light-surface))!important;color:rgb(var(--ax-sys-color-on-light-surface))!important;border-color:rgb(var(--ax-sys-color-border-light-surface))!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTreeViewModule }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "showCheckbox", "checkChildrenOnSelect", "intermediateState", "checkOnClick", "dragMode", "dragOperationType", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "nodeHeight", "look", "itemTemplate"], outputs: ["datasourceChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i6.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
566
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityCategoryComponent, isStandalone: true, selector: "axp-entity-category", inputs: { vm: { classPropertyName: "vm", publicName: "vm", isSignal: true, isRequired: true, transformFunction: null }, searchValue: { classPropertyName: "searchValue", publicName: "searchValue", isSignal: true, isRequired: false, transformFunction: null }, selectMode: { classPropertyName: "selectMode", publicName: "selectMode", isSignal: true, isRequired: false, transformFunction: null }, showCheckbox: { classPropertyName: "showCheckbox", publicName: "showCheckbox", isSignal: true, isRequired: false, transformFunction: null }, selectionBehavior: { classPropertyName: "selectionBehavior", publicName: "selectionBehavior", isSignal: true, isRequired: false, transformFunction: null }, dragArea: { classPropertyName: "dragArea", publicName: "dragArea", isSignal: true, isRequired: false, transformFunction: null }, dragBehavior: { classPropertyName: "dragBehavior", publicName: "dragBehavior", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, showChildrenBadge: { classPropertyName: "showChildrenBadge", publicName: "showChildrenBadge", isSignal: true, isRequired: false, transformFunction: null }, expandedIcon: { classPropertyName: "expandedIcon", publicName: "expandedIcon", isSignal: true, isRequired: false, transformFunction: null }, collapsedIcon: { classPropertyName: "collapsedIcon", publicName: "collapsedIcon", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-layout-header>\n <axp-layout-title>{{\n vm().entityDef.category?.title || '@general:terms.classification.category' | translate | async\n }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n (onValueChanged)=\"handleCategorySearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"'@general:terms.interface.category.search.placeholder' | translate | async\"\n >\n </ax-search-box>\n </axp-layout-toolbar>\n</axp-layout-header>\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeData) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\">\n <ax-tree-view\n [datasource]=\"datasource\"\n [selectMode]=\"selectMode()\"\n [showCheckbox]=\"showCheckbox()\"\n [selectionBehavior]=\"selectionBehavior()\"\n [dragArea]=\"dragArea()\"\n [dragBehavior]=\"dragBehavior()\"\n [showIcons]=\"showIcons()\"\n [showChildrenBadge]=\"showChildrenBadge()\"\n [expandedIcon]=\"expandedIcon()\"\n [collapsedIcon]=\"collapsedIcon()\"\n [indentSize]=\"indentSize()\"\n [look]=\"look()\"\n [titleField]=\"textField()\"\n [idField]=\"valueField()\"\n [nodeTemplate]=\"itemTemplate\"\n (onNodeToggle)=\"onNodeToggle($event)\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:terms.interface.category.search.no-records.title'\"\n [description]=\"'@general:terms.interface.category.search.no-records.description'\"\n >\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.add-new.title' | translate | async\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let item = node.data || node;\n @let textField = vm().entityDef.category?.textField || 'title';\n @let valueField = vm().entityDef.category?.valueField || 'id';\n @let itemId = item[valueField] || node.id;\n @let itemTitle = item[textField] || node.title;\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden\"\n (click)=\"handleNodeClick(node)\"\n >\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon\n class=\"fas fa-folder\"\n [style.color]=\"item.color ?? 'rgba(var(--ax-sys-color-warning-500), 1)'\"\n ></ax-icon>\n <span class=\"ax-truncate\">{{ itemTitle }}</span>\n </div>\n @if (itemId && itemId !== 'all') {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n (onClick)=\"handleCreateChildClick(node, $event)\"\n look=\"blank\"\n color=\"default\"\n text=\"Add New Child\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n <ax-button-item (onClick)=\"handleEditNodeClick(node, $event)\" look=\"blank\" text=\"Edit\">\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(node, $event)\"\n color=\"danger\"\n look=\"blank\"\n text=\"Delete\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n } @else if (itemId === 'all') {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTreeViewModule }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "showCheckbox", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField"], outputs: ["datasourceChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i6.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
334
567
|
}
|
|
335
568
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryComponent, decorators: [{
|
|
336
569
|
type: Component,
|
|
@@ -348,8 +581,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
348
581
|
AXButtonModule,
|
|
349
582
|
AXDropdownModule,
|
|
350
583
|
AXPStateMessageComponent,
|
|
351
|
-
], template: "<axp-layout-header>\n <axp-layout-title>{{\n vm().entityDef.category?.title || '@general:terms.classification.category' | translate | async\n }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n (onValueChanged)=\"handleCategorySearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"'@general:terms.interface.category.search.placeholder' | translate | async\"\n >\n </ax-search-box>\n </axp-layout-toolbar>\n</axp-layout-header>\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeData) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\">\n <ax-tree-view\n [datasource]=\"datasource\"\n [showCheckbox]=\"
|
|
352
|
-
}], ctorParameters: () => [], propDecorators: { vm: [{ type: i0.Input, args: [{ isSignal: true, alias: "vm", required: true }] }], tree: [{ type: i0.ViewChild, args: ['tree', { isSignal: true }] }], searchValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchValue", required: false }] }] } });
|
|
584
|
+
], template: "<axp-layout-header>\n <axp-layout-title>{{\n vm().entityDef.category?.title || '@general:terms.classification.category' | translate | async\n }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n (onValueChanged)=\"handleCategorySearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"'@general:terms.interface.category.search.placeholder' | translate | async\"\n >\n </ax-search-box>\n </axp-layout-toolbar>\n</axp-layout-header>\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeData) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\">\n <ax-tree-view\n [datasource]=\"datasource\"\n [selectMode]=\"selectMode()\"\n [showCheckbox]=\"showCheckbox()\"\n [selectionBehavior]=\"selectionBehavior()\"\n [dragArea]=\"dragArea()\"\n [dragBehavior]=\"dragBehavior()\"\n [showIcons]=\"showIcons()\"\n [showChildrenBadge]=\"showChildrenBadge()\"\n [expandedIcon]=\"expandedIcon()\"\n [collapsedIcon]=\"collapsedIcon()\"\n [indentSize]=\"indentSize()\"\n [look]=\"look()\"\n [titleField]=\"textField()\"\n [idField]=\"valueField()\"\n [nodeTemplate]=\"itemTemplate\"\n (onNodeToggle)=\"onNodeToggle($event)\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:terms.interface.category.search.no-records.title'\"\n [description]=\"'@general:terms.interface.category.search.no-records.description'\"\n >\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.add-new.title' | translate | async\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let item = node.data || node;\n @let textField = vm().entityDef.category?.textField || 'title';\n @let valueField = vm().entityDef.category?.valueField || 'id';\n @let itemId = item[valueField] || node.id;\n @let itemTitle = item[textField] || node.title;\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden\"\n (click)=\"handleNodeClick(node)\"\n >\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon\n class=\"fas fa-folder\"\n [style.color]=\"item.color ?? 'rgba(var(--ax-sys-color-warning-500), 1)'\"\n ></ax-icon>\n <span class=\"ax-truncate\">{{ itemTitle }}</span>\n </div>\n @if (itemId && itemId !== 'all') {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n (onClick)=\"handleCreateChildClick(node, $event)\"\n look=\"blank\"\n color=\"default\"\n text=\"Add New Child\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n <ax-button-item (onClick)=\"handleEditNodeClick(node, $event)\" look=\"blank\" text=\"Edit\">\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(node, $event)\"\n color=\"danger\"\n look=\"blank\"\n text=\"Delete\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n } @else if (itemId === 'all') {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n" }]
|
|
585
|
+
}], ctorParameters: () => [], propDecorators: { vm: [{ type: i0.Input, args: [{ isSignal: true, alias: "vm", required: true }] }], tree: [{ type: i0.ViewChild, args: ['tree', { isSignal: true }] }], searchValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchValue", required: false }] }], selectMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectMode", required: false }] }], showCheckbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCheckbox", required: false }] }], selectionBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionBehavior", required: false }] }], dragArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragArea", required: false }] }], dragBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragBehavior", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], showChildrenBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "showChildrenBadge", required: false }] }], expandedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedIcon", required: false }] }], collapsedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedIcon", required: false }] }], indentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentSize", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }] } });
|
|
353
586
|
|
|
354
587
|
class AXPEntityMasterToolbarViewComponent {
|
|
355
588
|
constructor() {
|
|
@@ -817,7 +1050,7 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
817
1050
|
//
|
|
818
1051
|
AXPEntityMasterToolbarViewComponent, selector: "axp-entity-master-toolbar-view", inputs: ["viewModel"] }, { kind: "component", type:
|
|
819
1052
|
//
|
|
820
|
-
AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXPEntityCategoryComponent, selector: "axp-entity-category", inputs: ["vm", "searchValue"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1053
|
+
AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXPEntityCategoryComponent, selector: "axp-entity-category", inputs: ["vm", "searchValue", "selectMode", "showCheckbox", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
821
1054
|
}
|
|
822
1055
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityMasterListViewComponent, decorators: [{
|
|
823
1056
|
type: Component,
|
|
@@ -864,4 +1097,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
864
1097
|
}], ctorParameters: () => [{ type: i1$1.AXPlatform }], propDecorators: { grid: [{ type: i0.ViewChild, args: ['grid', { isSignal: true }] }] } });
|
|
865
1098
|
|
|
866
1099
|
export { AXPEntityMasterListViewComponent };
|
|
867
|
-
//# sourceMappingURL=acorex-platform-themes-default-entity-master-list-view.component-
|
|
1100
|
+
//# sourceMappingURL=acorex-platform-themes-default-entity-master-list-view.component-BbACUabi.mjs.map
|