@acorex/platform 20.6.0-next.19 → 20.6.0-next.20

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 (33) hide show
  1. package/common/index.d.ts +2 -2
  2. package/core/index.d.ts +1 -0
  3. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  4. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-layout-builder.mjs +38 -117
  6. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-layout-components.mjs +1 -9
  8. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-layout-entity.mjs +2725 -1727
  10. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-views.mjs +2 -1
  12. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  13. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-C1l2KSDa.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-m8rHZP8L.mjs} +2 -2
  14. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-m8rHZP8L.mjs.map +1 -0
  15. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-D-31ej0C.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs} +2 -2
  16. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-layout-widgets.mjs +5 -5
  18. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  19. package/fesm2022/{acorex-platform-themes-default-entity-master-create-view.component-xtWnr98z.mjs → acorex-platform-themes-default-entity-master-create-view.component-mARj77Mr.mjs} +3 -3
  20. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-mARj77Mr.mjs.map +1 -0
  21. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-BbACUabi.mjs → acorex-platform-themes-default-entity-master-list-view.component-CenhnHXi.mjs} +453 -31
  22. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-CenhnHXi.mjs.map +1 -0
  23. package/fesm2022/acorex-platform-themes-default.mjs +5 -5
  24. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  25. package/layout/builder/index.d.ts +6 -33
  26. package/layout/entity/index.d.ts +145 -22
  27. package/package.json +13 -13
  28. package/fesm2022/acorex-platform-layout-entity-create-entity.command-Bui87lV1.mjs +0 -83
  29. package/fesm2022/acorex-platform-layout-entity-create-entity.command-Bui87lV1.mjs.map +0 -1
  30. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-C1l2KSDa.mjs.map +0 -1
  31. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-D-31ej0C.mjs.map +0 -1
  32. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-xtWnr98z.mjs.map +0 -1
  33. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-BbACUabi.mjs.map +0 -1
@@ -40,10 +40,11 @@ import { AXPLayoutThemeService } from '@acorex/platform/themes/shared';
40
40
  import * as i2$1 from '@acorex/components/skeleton';
41
41
  import { AXSkeletonModule } from '@acorex/components/skeleton';
42
42
  import { AXTreeViewModule, AXTreeViewComponent } from '@acorex/components/tree-view';
43
+ import { AXPRefreshEvent, AXPSettingService, AXPCommonSettings } from '@acorex/platform/common';
43
44
  import { AXPEntityResolver, AXPCategoryTreeService, AXPEntityListViewColumnViewModel } from '@acorex/platform/layout/entity';
44
- import { AXPWorkflowService } from '@acorex/platform/workflow';
45
+ import { AXPWorkflowService, ofType } from '@acorex/platform/workflow';
46
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
45
47
  import { AXPDeviceService } from '@acorex/platform/core';
46
- import { AXPSettingService, AXPCommonSettings } from '@acorex/platform/common';
47
48
  import { isEqual } from 'lodash-es';
48
49
 
49
50
  //#region ---- Constants ----
@@ -67,10 +68,9 @@ class AXPEntityCategoryComponent {
67
68
  this.tree = viewChild('tree', ...(ngDevMode ? [{ debugName: "tree" }] : []));
68
69
  this.searchValue = input('', ...(ngDevMode ? [{ debugName: "searchValue" }] : []));
69
70
  // Tree view inputs with defaults
70
- this.selectMode = input('single', ...(ngDevMode ? [{ debugName: "selectMode" }] : []));
71
- this.showCheckbox = input(false, ...(ngDevMode ? [{ debugName: "showCheckbox" }] : []));
71
+ this.selectMode = input('multiple', ...(ngDevMode ? [{ debugName: "selectMode" }] : []));
72
72
  this.selectionBehavior = input('intermediate', ...(ngDevMode ? [{ debugName: "selectionBehavior" }] : []));
73
- this.dragArea = input('handler', ...(ngDevMode ? [{ debugName: "dragArea" }] : [])); //TODO FIX ACOREX
73
+ this.dragArea = input('handler', ...(ngDevMode ? [{ debugName: "dragArea" }] : []));
74
74
  this.dragBehavior = input('none', ...(ngDevMode ? [{ debugName: "dragBehavior" }] : []));
75
75
  this.showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
76
76
  this.showChildrenBadge = input(false, ...(ngDevMode ? [{ debugName: "showChildrenBadge" }] : []));
@@ -78,19 +78,39 @@ class AXPEntityCategoryComponent {
78
78
  this.collapsedIcon = input('fa-solid fa-chevron-right', ...(ngDevMode ? [{ debugName: "collapsedIcon" }] : []));
79
79
  this.indentSize = input(16, ...(ngDevMode ? [{ debugName: "indentSize" }] : []));
80
80
  this.look = input('default', ...(ngDevMode ? [{ debugName: "look" }] : []));
81
+ this.searchWithChildren = input(true, ...(ngDevMode ? [{ debugName: "searchWithChildren" }] : [])); // Include children of search results
81
82
  //#endregion
82
83
  //#region ---- Component State ----
83
84
  this.isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
85
+ this.isSearching = signal(false, ...(ngDevMode ? [{ debugName: "isSearching" }] : []));
86
+ this.searchResultCount = signal(0, ...(ngDevMode ? [{ debugName: "searchResultCount" }] : []));
87
+ this.currentSearchValue = signal('', ...(ngDevMode ? [{ debugName: "currentSearchValue" }] : []));
88
+ this.resultsFoundText = signal('', ...(ngDevMode ? [{ debugName: "resultsFoundText" }] : []));
84
89
  //#endregion
85
90
  //#region ---- Private Properties ----
86
91
  this.loadingTimeoutId = null;
87
92
  this.treeData = null;
88
93
  this.treeConfig = null;
89
- this.searchResults = null;
94
+ this.matchingNodeIds = new Set();
95
+ this.relevantNodeIds = new Set(); // For search filtering
96
+ this.nodeDataCache = new Map(); // Cache parent data from search results
97
+ this.expandedNodesBeforeSearch = [];
98
+ this.nodesExpandedDuringSearch = [];
99
+ this.currentSearchTerm = null;
90
100
  //#endregion
91
101
  //#region ---- Computed Properties ----
92
102
  this.textField = computed(() => this.vm().entityDef.category?.textField || DEFAULT_TEXT_FIELD, ...(ngDevMode ? [{ debugName: "textField" }] : []));
93
103
  this.valueField = computed(() => this.vm().entityDef.category?.valueField || DEFAULT_VALUE_FIELD, ...(ngDevMode ? [{ debugName: "valueField" }] : []));
104
+ /**
105
+ * Computed property to check if we should show the "no search results" empty state.
106
+ * Returns true when search is active, not searching, and no results found.
107
+ */
108
+ this.showNoSearchResults = computed(() => {
109
+ const searchValue = this.currentSearchValue().trim();
110
+ const isSearching = this.isSearching();
111
+ const resultCount = this.searchResultCount();
112
+ return searchValue.length > 0 && !isSearching && resultCount === 0;
113
+ }, ...(ngDevMode ? [{ debugName: "showNoSearchResults" }] : []));
94
114
  this.categoryEntityKey = computed(() => {
95
115
  const key = this.vm().entityDef.category?.entity;
96
116
  if (!key) {
@@ -98,6 +118,9 @@ class AXPEntityCategoryComponent {
98
118
  }
99
119
  return key;
100
120
  }, ...(ngDevMode ? [{ debugName: "categoryEntityKey" }] : []));
121
+ // protected toggleExpand(e: AXTreeViewNodeDoubleClickEvent) {
122
+ // (e.component as AXTreeViewComponent).toggleNodeExpansion(String(e.node[this.valueField()] ?? ''));
123
+ // }
101
124
  //#endregion
102
125
  //#region ---- Tree Data Source ----
103
126
  /**
@@ -105,6 +128,7 @@ class AXPEntityCategoryComponent {
105
128
  * Provides lazy loading support for tree nodes.
106
129
  */
107
130
  this.datasource = async (parentId) => {
131
+ console.log('datasource', parentId);
108
132
  if (!this.isTreeInitialized()) {
109
133
  return [];
110
134
  }
@@ -118,33 +142,388 @@ class AXPEntityCategoryComponent {
118
142
  afterNextRender(() => {
119
143
  this.initializeTree();
120
144
  });
145
+ this.workflow.events$
146
+ .pipe(ofType(AXPRefreshEvent))
147
+ .pipe(takeUntilDestroyed())
148
+ .subscribe((event) => {
149
+ this.tree()?.reloadData();
150
+ // this.tree()?.refresh();
151
+ });
121
152
  }
122
153
  //#endregion
123
154
  //#region ---- Public Methods ----
124
155
  /**
125
- * Handles category search input changes
156
+ * Handles category search input changes - Uses server-side search for efficiency and reliability
126
157
  */
127
158
  async handleCategorySearchChange(event) {
128
159
  if (!this.isTreeInitialized()) {
129
160
  return;
130
161
  }
131
- this.setLoadingWithDelay(true);
162
+ const searchTerm = (event.value ?? '').trim().toLowerCase();
163
+ const previousSearchTerm = this.currentSearchValue();
164
+ // If search is cleared, reset tree
165
+ if (!searchTerm) {
166
+ if (previousSearchTerm || this.matchingNodeIds.size > 0) {
167
+ this.currentSearchValue.set('');
168
+ this.currentSearchTerm = null;
169
+ await this.resetSearch();
170
+ }
171
+ return;
172
+ }
173
+ // For non-empty search, only process user interactions
174
+ if (!event.isUserInteraction) {
175
+ return;
176
+ }
177
+ // Prevent concurrent searches
178
+ if (this.isSearching() && this.currentSearchTerm !== null) {
179
+ if (this.currentSearchTerm === searchTerm) {
180
+ return;
181
+ }
182
+ }
183
+ this.currentSearchValue.set(event.value ?? '');
184
+ this.currentSearchTerm = searchTerm;
185
+ const treeComponent = this.tree();
186
+ if (!treeComponent) {
187
+ return;
188
+ }
189
+ // Store expanded nodes before starting a new search (only on first search)
190
+ if (!previousSearchTerm && this.expandedNodesBeforeSearch.length === 0) {
191
+ const expandedNodes = treeComponent.getExpandedNodes();
192
+ this.expandedNodesBeforeSearch = expandedNodes
193
+ .map((node) => String(node['id'] ?? ''))
194
+ .filter((id) => id && id !== ROOT_NODE_ID);
195
+ }
196
+ // Collapse nodes from previous search before starting new search
197
+ if (previousSearchTerm && this.nodesExpandedDuringSearch.length > 0) {
198
+ const nodesToCollapse = [...this.nodesExpandedDuringSearch].reverse();
199
+ this.nodesExpandedDuringSearch = [];
200
+ for (const nodeId of nodesToCollapse) {
201
+ // Only collapse if it wasn't originally expanded before search
202
+ if (!this.expandedNodesBeforeSearch.includes(nodeId)) {
203
+ try {
204
+ treeComponent.collapseNode(nodeId);
205
+ }
206
+ catch {
207
+ // Node might not exist anymore, ignore
208
+ }
209
+ }
210
+ }
211
+ }
212
+ this.isSearching.set(true);
132
213
  try {
133
- const items = await this.categoryTreeService.searchCategories(event.value, this.treeData, this.treeConfig);
134
- if (!items) {
135
- this.clearLoadingState();
214
+ // Step 1: Use server-side search to get matching items
215
+ const searchResults = await this.categoryTreeService.searchCategories(searchTerm, this.treeData, this.treeConfig);
216
+ // Check if search term changed during the API call
217
+ if (this.currentSearchTerm !== searchTerm) {
218
+ return;
219
+ }
220
+ if (!searchResults || searchResults.length === 0) {
221
+ this.matchingNodeIds.clear();
222
+ this.searchResultCount.set(0);
223
+ await this.updateTranslatedMessages(0);
136
224
  return;
137
225
  }
138
- this.searchResults = items;
139
- this.refreshTree();
226
+ // Store matching node IDs from search results
227
+ this.matchingNodeIds.clear();
228
+ const valueField = this.valueField();
229
+ searchResults.forEach((item) => {
230
+ const nodeId = String(item[valueField] ?? '');
231
+ if (nodeId) {
232
+ this.matchingNodeIds.add(nodeId);
233
+ }
234
+ });
235
+ const resultCount = searchResults.length;
236
+ this.searchResultCount.set(resultCount);
237
+ // Update translated messages
238
+ await this.updateTranslatedMessages(resultCount);
239
+ // Step 2: Collect parent IDs (builds relevantNodeIds for filtering)
240
+ const parentsToExpand = await this.collectParentIds(searchResults);
241
+ // Step 2.5: Collect children IDs if searchWithChildren is enabled
242
+ if (this.searchWithChildren()) {
243
+ await this.collectChildrenIds(searchResults);
244
+ }
245
+ // Step 3: Reload tree to apply filtering
246
+ await treeComponent.reloadData();
247
+ // Step 4: Expand root node
248
+ if (!treeComponent.isNodeExpanded(ROOT_NODE_ID)) {
249
+ try {
250
+ await treeComponent.expandNode(ROOT_NODE_ID);
251
+ this.nodesExpandedDuringSearch.push(ROOT_NODE_ID);
252
+ }
253
+ catch {
254
+ // Root might not exist
255
+ }
256
+ }
257
+ // Step 4: Expand all parent nodes in order (from root to leaves)
258
+ // Sort parents by their depth to expand in correct order
259
+ const sortedParents = await this.sortParentsByDepth(Array.from(parentsToExpand));
260
+ for (const parentId of sortedParents) {
261
+ // Only expand if not already expanded
262
+ if (!treeComponent.isNodeExpanded(parentId)) {
263
+ try {
264
+ await treeComponent.expandNode(parentId);
265
+ this.nodesExpandedDuringSearch.push(parentId);
266
+ // Small delay to prevent overwhelming the tree component
267
+ await new Promise((resolve) => setTimeout(resolve, 10));
268
+ }
269
+ catch {
270
+ // Node might not exist, ignore
271
+ }
272
+ }
273
+ }
140
274
  }
141
275
  catch (error) {
142
276
  console.error('Error searching categories:', error);
277
+ this.matchingNodeIds.clear();
278
+ this.searchResultCount.set(0);
143
279
  }
144
280
  finally {
145
- this.clearLoadingState();
281
+ if (this.currentSearchTerm === searchTerm) {
282
+ this.currentSearchTerm = null;
283
+ }
284
+ this.isSearching.set(false);
146
285
  }
147
286
  }
287
+ /**
288
+ * Collects all parent IDs for the given search results
289
+ * Handles both nested 'parent' object and 'parentId' field in search results
290
+ * Recursively fetches parent nodes to build the full parent chain
291
+ */
292
+ async collectParentIds(items) {
293
+ const parentsToExpand = new Set();
294
+ const valueField = this.valueField();
295
+ const parentKey = this.treeData?.categoryEntityDef?.parentKey || 'parentId';
296
+ // Build relevantNodeIds = matching nodes + all parents
297
+ this.relevantNodeIds.clear();
298
+ this.matchingNodeIds.forEach((id) => this.relevantNodeIds.add(id));
299
+ // Recursively extract all parent IDs
300
+ const extractParentIds = async (item) => {
301
+ // First, try to get parent from nested 'parent' object (if available)
302
+ const parent = item['parent'];
303
+ if (parent) {
304
+ const parentId = String(parent[valueField] ?? parent['id'] ?? '');
305
+ if (parentId && parentId !== ROOT_NODE_ID) {
306
+ parentsToExpand.add(parentId);
307
+ this.relevantNodeIds.add(parentId); // Add to filter set
308
+ this.nodeDataCache.set(parentId, parent);
309
+ await extractParentIds(parent);
310
+ }
311
+ }
312
+ else {
313
+ // Fallback: use parentId field and fetch parent from server
314
+ // Try both parentKey from entity definition and common 'parentId' field
315
+ const parentIdValue = item[parentKey] ?? item['parentId'];
316
+ if (parentIdValue) {
317
+ const parentId = String(parentIdValue);
318
+ if (parentId && parentId !== ROOT_NODE_ID) {
319
+ // Add to sets first
320
+ parentsToExpand.add(parentId);
321
+ this.relevantNodeIds.add(parentId);
322
+ // Fetch parent from server if not already cached
323
+ if (!this.nodeDataCache.has(parentId)) {
324
+ const parentItem = await this.fetchItemById(parentId);
325
+ if (parentItem) {
326
+ this.nodeDataCache.set(parentId, parentItem);
327
+ // Recursively fetch parent's parent
328
+ await extractParentIds(parentItem);
329
+ }
330
+ }
331
+ else {
332
+ // Parent already in cache, recursively process it
333
+ const cachedParent = this.nodeDataCache.get(parentId);
334
+ if (cachedParent) {
335
+ await extractParentIds(cachedParent);
336
+ }
337
+ }
338
+ }
339
+ }
340
+ }
341
+ };
342
+ // Process all items
343
+ for (const item of items) {
344
+ await extractParentIds(item);
345
+ }
346
+ return parentsToExpand;
347
+ }
348
+ /**
349
+ * Collects children IDs for matching search results recursively
350
+ * Adds all descendants (children, grandchildren, etc.) to relevantNodeIds so they appear in the filtered tree
351
+ */
352
+ async collectChildrenIds(items) {
353
+ if (!this.treeData?.categoryEntityQueryFunc || !this.treeConfig) {
354
+ return;
355
+ }
356
+ const valueField = this.valueField();
357
+ const parentKey = this.treeData.categoryEntityDef?.parentKey;
358
+ if (!parentKey) {
359
+ return;
360
+ }
361
+ // For each matching node, recursively fetch all its descendants
362
+ for (const item of items) {
363
+ const nodeId = String(item[valueField] ?? '');
364
+ if (!nodeId || nodeId === ROOT_NODE_ID) {
365
+ continue;
366
+ }
367
+ await this.collectChildrenRecursively(nodeId, valueField, parentKey);
368
+ }
369
+ }
370
+ /**
371
+ * Recursively collects all descendant IDs for a given node
372
+ */
373
+ async collectChildrenRecursively(nodeId, valueField, parentKey) {
374
+ if (!this.treeData?.categoryEntityQueryFunc) {
375
+ return;
376
+ }
377
+ try {
378
+ // Fetch children for this node
379
+ const event = {
380
+ ...this.treeData.basicQueryEvent,
381
+ filter: {
382
+ field: parentKey,
383
+ value: nodeId,
384
+ operator: { type: 'equal' },
385
+ },
386
+ };
387
+ const res = await this.treeData.categoryEntityQueryFunc(event);
388
+ if (res?.items && res.items.length > 0) {
389
+ // Add children IDs to relevantNodeIds so they appear in filtered tree
390
+ for (const child of res.items) {
391
+ const childId = String(child[valueField] ?? '');
392
+ if (childId && childId !== ROOT_NODE_ID) {
393
+ this.relevantNodeIds.add(childId);
394
+ // Cache child data
395
+ this.nodeDataCache.set(childId, child);
396
+ // Recursively fetch children of this child
397
+ await this.collectChildrenRecursively(childId, valueField, parentKey);
398
+ }
399
+ }
400
+ }
401
+ }
402
+ catch (error) {
403
+ console.error(`Error fetching children for node ${nodeId}:`, error);
404
+ }
405
+ }
406
+ /**
407
+ * Fetches a single item by ID from the server
408
+ */
409
+ async fetchItemById(id) {
410
+ if (!this.treeData?.categoryEntityQueryFunc) {
411
+ return null;
412
+ }
413
+ try {
414
+ const valueField = this.valueField();
415
+ const event = {
416
+ ...this.treeData.basicQueryEvent,
417
+ filter: {
418
+ field: valueField,
419
+ value: id,
420
+ operator: { type: 'equal' },
421
+ },
422
+ };
423
+ const res = await this.treeData.categoryEntityQueryFunc(event);
424
+ return res?.items?.[0] ?? null;
425
+ }
426
+ catch (error) {
427
+ console.error('Error fetching item by ID:', error);
428
+ return null;
429
+ }
430
+ }
431
+ /**
432
+ * Sorts parent IDs by their depth (root first, leaves last)
433
+ * Uses cached data from collectParentIds
434
+ */
435
+ async sortParentsByDepth(parentIds) {
436
+ const parentKey = this.treeData?.categoryEntityDef?.parentKey;
437
+ if (!parentKey || parentIds.length === 0) {
438
+ return parentIds;
439
+ }
440
+ // Build depth map using cached data
441
+ const depthMap = new Map();
442
+ for (const parentId of parentIds) {
443
+ if (depthMap.has(parentId)) {
444
+ continue;
445
+ }
446
+ let depth = 0;
447
+ let currentId = parentId;
448
+ const visited = new Set();
449
+ while (currentId && currentId !== ROOT_NODE_ID && !visited.has(currentId)) {
450
+ visited.add(currentId);
451
+ depth++;
452
+ // Use nodeDataCache which was populated by collectParentIds
453
+ const item = this.nodeDataCache.get(currentId);
454
+ if (item) {
455
+ currentId = item[parentKey] ? String(item[parentKey]) : null;
456
+ }
457
+ else {
458
+ break;
459
+ }
460
+ }
461
+ depthMap.set(parentId, depth);
462
+ }
463
+ // Sort by depth (lower depth = closer to root = expand first)
464
+ return parentIds.sort((a, b) => {
465
+ const depthA = depthMap.get(a) ?? 0;
466
+ const depthB = depthMap.get(b) ?? 0;
467
+ return depthA - depthB;
468
+ });
469
+ }
470
+ /**
471
+ * Updates translated messages for search results
472
+ */
473
+ async updateTranslatedMessages(resultCount) {
474
+ if (resultCount > 0) {
475
+ const key = resultCount === 1
476
+ ? '@general:terms.interface.category.search.results-found.singular'
477
+ : '@general:terms.interface.category.search.results-found.plural';
478
+ const text = await this.translate.translateAsync(key, { params: { count: resultCount } });
479
+ this.resultsFoundText.set(text);
480
+ }
481
+ else {
482
+ this.resultsFoundText.set('');
483
+ }
484
+ }
485
+ /**
486
+ * Resets search state and restores tree to original expanded state
487
+ */
488
+ async resetSearch() {
489
+ this.searchResultCount.set(0);
490
+ this.resultsFoundText.set('');
491
+ this.currentSearchTerm = null;
492
+ this.isSearching.set(false);
493
+ this.matchingNodeIds.clear();
494
+ this.relevantNodeIds.clear();
495
+ this.nodeDataCache.clear();
496
+ const treeComponent = this.tree();
497
+ if (!treeComponent) {
498
+ this.expandedNodesBeforeSearch = [];
499
+ this.nodesExpandedDuringSearch = [];
500
+ return;
501
+ }
502
+ // Reload tree to show all nodes (no filtering)
503
+ await treeComponent.reloadData();
504
+ // Collapse nodes that were expanded during search (in reverse order - leaves first)
505
+ const nodesToCollapse = [...this.nodesExpandedDuringSearch].reverse();
506
+ this.nodesExpandedDuringSearch = [];
507
+ for (const nodeId of nodesToCollapse) {
508
+ // Only collapse if it wasn't originally expanded before search
509
+ if (!this.expandedNodesBeforeSearch.includes(nodeId)) {
510
+ try {
511
+ treeComponent.collapseNode(nodeId);
512
+ }
513
+ catch {
514
+ // Node might not exist anymore, ignore
515
+ }
516
+ }
517
+ }
518
+ // Clear the stored expanded nodes
519
+ this.expandedNodesBeforeSearch = [];
520
+ }
521
+ /**
522
+ * Checks if a node matches the current search term
523
+ */
524
+ isMatchingNode(nodeId) {
525
+ return this.matchingNodeIds.has(nodeId);
526
+ }
148
527
  /**
149
528
  * Handles node click events to apply category filters
150
529
  */
@@ -245,7 +624,6 @@ class AXPEntityCategoryComponent {
245
624
  if (this.treeData.categoryEntityDef?.parentKey) {
246
625
  this.treeConfig.parentKey = this.treeData.categoryEntityDef.parentKey;
247
626
  }
248
- this.searchResults = null;
249
627
  }
250
628
  catch (error) {
251
629
  console.error('Error loading categories:', error);
@@ -261,17 +639,20 @@ class AXPEntityCategoryComponent {
261
639
  if (!this.isTreeInitialized()) {
262
640
  return [];
263
641
  }
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
642
  // Load root categories
270
643
  const items = await this.categoryTreeService.loadRootCategories(this.treeData, this.treeConfig);
271
644
  if (!items) {
272
645
  return [];
273
646
  }
274
647
  const rootNode = await this.categoryTreeService.createRootNode(items, this.treeConfig);
648
+ // Filter root's children when search is active
649
+ if (this.relevantNodeIds.size > 0 && rootNode['children']) {
650
+ rootNode['children'] = rootNode['children'].filter((child) => {
651
+ const childId = String(child['id'] ?? '');
652
+ return this.relevantNodeIds.has(childId);
653
+ });
654
+ rootNode['childrenCount'] = rootNode['children'].length;
655
+ }
275
656
  return [rootNode];
276
657
  }
277
658
  /**
@@ -281,12 +662,19 @@ class AXPEntityCategoryComponent {
281
662
  if (!this.isTreeInitialized()) {
282
663
  return [];
283
664
  }
665
+ // Create minimal node object - loadChildren only needs node.id
284
666
  const targetNode = {
285
- ['id']: parentId,
286
- ['title']: '',
287
- ['data']: {},
667
+ id: parentId,
288
668
  };
289
- return await this.categoryTreeService.loadChildren(targetNode, this.treeData, this.treeConfig);
669
+ let children = await this.categoryTreeService.loadChildren(targetNode, this.treeData, this.treeConfig);
670
+ // Filter children when search is active
671
+ if (this.relevantNodeIds.size > 0) {
672
+ children = children.filter((child) => {
673
+ const childId = String(child['id'] ?? '');
674
+ return this.relevantNodeIds.has(childId);
675
+ });
676
+ }
677
+ return children;
290
678
  }
291
679
  /**
292
680
  * Refreshes the tree view component
@@ -301,7 +689,6 @@ class AXPEntityCategoryComponent {
301
689
  * Refreshes tree after CRUD operations
302
690
  */
303
691
  async refreshAfterChange(parentId) {
304
- this.searchResults = null;
305
692
  this.refreshTree();
306
693
  }
307
694
  /**
@@ -367,6 +754,41 @@ class AXPEntityCategoryComponent {
367
754
  await this.refreshNodeParent(entityData);
368
755
  return;
369
756
  }
757
+ // Check if parent changed
758
+ const parentKey = this.treeData?.categoryEntityDef?.parentKey;
759
+ let newParentId = undefined;
760
+ if (parentKey && entityData[parentKey]) {
761
+ const parentValue = String(entityData[parentKey]);
762
+ // 'all' means root, so treat it as undefined
763
+ newParentId = parentValue !== 'all' && parentValue !== '' ? parentValue : undefined;
764
+ }
765
+ const currentParent = treeComponent.getParent(nodeId);
766
+ const currentParentId = currentParent ? String(currentParent['id'] ?? '') : undefined;
767
+ // Normalize current parent: 'all' means root (undefined)
768
+ const normalizedCurrentParentId = currentParentId === 'all' || currentParentId === '' ? undefined : currentParentId;
769
+ // Handle parent change: move node to new parent if parent changed
770
+ if (newParentId !== normalizedCurrentParentId) {
771
+ // If parent changed, move the node first
772
+ const moved = treeComponent.moveNode(nodeId, newParentId);
773
+ if (!moved) {
774
+ // If move failed, refresh the tree to ensure consistency
775
+ await this.refreshNodeParent(entityData);
776
+ return;
777
+ }
778
+ // After moving, we need to ensure the new parent is expanded
779
+ if (newParentId) {
780
+ if (!treeComponent.isNodeExpanded(newParentId)) {
781
+ await treeComponent.expandNode(newParentId);
782
+ }
783
+ }
784
+ else {
785
+ // Moving to root - ensure root is expanded
786
+ if (!treeComponent.isNodeExpanded(ROOT_NODE_ID)) {
787
+ await treeComponent.expandNode(ROOT_NODE_ID);
788
+ }
789
+ }
790
+ }
791
+ // Update node properties (title, data, etc.)
370
792
  const updatedNode = this.categoryTreeService.convertToTreeNode(entityData, this.treeConfig);
371
793
  const updates = {
372
794
  ['title']: updatedNode['title'],
@@ -563,7 +985,7 @@ class AXPEntityCategoryComponent {
563
985
  this.isLoading.set(false);
564
986
  }
565
987
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
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 }); }
988
+ 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 }, 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 }, searchWithChildren: { classPropertyName: "searchWithChildren", publicName: "searchWithChildren", 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 <div class=\"ax-flex ax-flex-col ax-gap-1 ax-w-full\">\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 @if (isSearching() && currentSearchValue().trim()) {\n <div class=\"ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1\">\n <span>{{ '@general:terms.interface.category.search.searching' | translate | async }}</span>\n </div>\n } @else if (currentSearchValue().trim() && !isSearching()) {\n <div class=\"ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1\">\n @if (searchResultCount() > 0) {\n <span>{{ resultsFoundText() }}</span>\n } @else {\n <span>{{ '@general:terms.interface.category.search.no-results' | translate | async }}</span>\n }\n </div>\n }\n </div>\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 (showNoSearchResults()) {\n <axp-state-message\n icon=\"fa-light fa-search\"\n [title]=\"'@general:terms.interface.category.search.no-results-found.title'\"\n [description]=\"'@general:terms.interface.category.search.no-results-found.description'\"\n >\n </axp-state-message>\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 [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 [expandOnDoubleClick]=\"true\"\n [nodeTemplate]=\"itemTemplate\"\n (onNodeToggle)=\"onNodeToggle($event)\"\n (onNodeClick)=\"handleNodeClick($event.node)\"\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 @let isMatch = isMatchingNode(node.id);\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden ax-py-1\"\n [class.ax-bg-secondary-100]=\"isMatch\"\n [class.ax-rounded]=\"isMatch\"\n [class.ax-px-2]=\"isMatch\"\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\" [class.ax-font-semibold]=\"isMatch\">{{ 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", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick"], outputs: ["datasourceChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "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 }); }
567
989
  }
568
990
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryComponent, decorators: [{
569
991
  type: Component,
@@ -581,8 +1003,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
581
1003
  AXButtonModule,
582
1004
  AXDropdownModule,
583
1005
  AXPStateMessageComponent,
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 }] }] } });
1006
+ ], 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 <div class=\"ax-flex ax-flex-col ax-gap-1 ax-w-full\">\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 @if (isSearching() && currentSearchValue().trim()) {\n <div class=\"ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1\">\n <span>{{ '@general:terms.interface.category.search.searching' | translate | async }}</span>\n </div>\n } @else if (currentSearchValue().trim() && !isSearching()) {\n <div class=\"ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1\">\n @if (searchResultCount() > 0) {\n <span>{{ resultsFoundText() }}</span>\n } @else {\n <span>{{ '@general:terms.interface.category.search.no-results' | translate | async }}</span>\n }\n </div>\n }\n </div>\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 (showNoSearchResults()) {\n <axp-state-message\n icon=\"fa-light fa-search\"\n [title]=\"'@general:terms.interface.category.search.no-results-found.title'\"\n [description]=\"'@general:terms.interface.category.search.no-results-found.description'\"\n >\n </axp-state-message>\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 [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 [expandOnDoubleClick]=\"true\"\n [nodeTemplate]=\"itemTemplate\"\n (onNodeToggle)=\"onNodeToggle($event)\"\n (onNodeClick)=\"handleNodeClick($event.node)\"\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 @let isMatch = isMatchingNode(node.id);\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden ax-py-1\"\n [class.ax-bg-secondary-100]=\"isMatch\"\n [class.ax-rounded]=\"isMatch\"\n [class.ax-px-2]=\"isMatch\"\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\" [class.ax-font-semibold]=\"isMatch\">{{ 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" }]
1007
+ }], 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 }] }], 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 }] }], searchWithChildren: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchWithChildren", required: false }] }] } });
586
1008
 
587
1009
  class AXPEntityMasterToolbarViewComponent {
588
1010
  constructor() {
@@ -1044,13 +1466,13 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
1044
1466
  provide: AXPPageLayoutBase,
1045
1467
  useExisting: AXPEntityMasterListViewComponent,
1046
1468
  },
1047
- ], viewQueries: [{ propertyName: "grid", first: true, predicate: ["grid"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.entityDef.category) {\n <axp-layout-start-side id=\"axp-entity-category-drawer\">\n <axp-entity-category\n id=\"axp-entity-category\"\n class=\"ax-w-80\"\n [vm]=\"vm\"\n [searchValue]=\"categorySearchValue()\"\n ></axp-entity-category>\n </axp-layout-start-side>\n }\n <axp-page-toolbar id=\"axp-entity-toolbar\">\n <axp-entity-master-toolbar-view [viewModel]=\"vm\"></axp-entity-master-toolbar-view>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-overflow-auto ax-pt-0\">\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1 ax-pb-1\"\n [class.ax-invisible]=\"!grid.selectedRows.length\"\n >\n <span\n >{{ grid.selectedRows.length }}\n <span>{{ '@general:terms.interface.items-selected' | translate | async }}</span>\n </span>\n <ax-button text=\"@general:terms.interface.unselect-all\" class=\"ax-xs\" (onClick)=\"handleUnselectAll()\"></ax-button>\n </div>\n <ax-data-table\n id=\"axp-entity-table\"\n [allowReordering]=\"true\"\n (onColumnsOrderChanged)=\"onColumnsOrderChanged($event)\"\n #grid\n [showFooter]=\"false\"\n class=\"ax-flex-1\"\n [paging]=\"true\"\n [fetchDataMode]=\"'manual'\"\n [parentField]=\"vm.parentKey()\"\n [loading]=\"{ enabled: true, animation: true }\"\n [dataSource]=\"vm.dataSource\"\n (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowDbClick)=\"handleRowDbClick($event)\"\n (onColumnSizeChanged)=\"onColumnSizeChanged($event)\"\n (onPageChanged)=\"onPageChanged($event)\"\n >\n @if (vm.view().indexCol === true) {\n <ax-index-column id=\"axp-table-col-index\" fixed=\"start\" [width]=\"'80px'\" [padZero]=\"true\"></ax-index-column>\n }\n @if (vm.selectedScopeActionsCount()) {\n <ax-select-column id=\"axp-table-col-select\" fixed=\"start\" [width]=\"'60px'\"></ax-select-column>\n }\n @for (col of vm.columns(); track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer\n [attr.id]=\"'axp-table-col-' + col.name\"\n [expandHandler]=\"$index === 0 && vm.parentKey() ? true : false\"\n [caption]=\"(col.title | translate | async)!\"\n [node]=\"col.node()\"\n [customWidth]=\"col.width\"\n ></axp-widget-column-renderer>\n }\n }\n @if (getCommandRowItems().length) {\n <ax-command-column\n id=\"axp-table-col-commands\"\n fixed=\"end\"\n [width]=\"getCommandRowItems().length * 60 + 'px'\"\n [items]=\"getCommandRowItems()\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-command-column>\n }\n <ax-dropdown-command-column\n id=\"axp-table-col-dropdown-commands\"\n fixed=\"end\"\n [width]=\"'60px'\"\n [items]=\"getDropdownRowItems\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-dropdown-command-column>\n </ax-data-table>\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axp-entity-master-list axp-layout-start-side{min-width:20rem!important;border-inline-end-width:1px;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}axp-entity-master-list axp-layout-header{padding-bottom:.25rem!important}.cdk-drag-preview{border-radius:.375rem;border-width:1px;--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background:rgba(var(--ax-color-on-surface));padding:.5rem;height:max-content!important}.collapsed-search-box{margin-top:0;height:0px;opacity:0}.view-drawer{width:85vw}@media (min-width: 768px){.view-drawer{width:45vw}}@media (min-width: 1024px){.view-drawer{width:35vw}}@media (min-width: 1536px){.view-drawer{width:20vw}}.view-drawer{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));border-inline-start-width:1px;border-inline-start-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));border-top-width:1px;--tw-border-opacity: 1;border-top-color:rgba(var(--ax-sys-color-primary-600),var(--tw-border-opacity, 1))}.view-drawer ax-header{display:flex;align-items:center;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.5rem 1rem}.view-drawer ax-header h2{font-size:1.25rem;line-height:1.75rem;font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lighter-surface),var(--tw-text-opacity, 1))}.view-drawer ax-footer{position:absolute!important;bottom:0!important;width:100%!important;justify-content:flex-start!important;border-top-width:1px!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))!important;padding:.5rem 1rem!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { 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: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXActionSheetModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "ngmodule", type: AXDialogModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i7.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i7.AXRowIndexColumnComponent, selector: "ax-index-column", inputs: ["width", "caption", "fixed", "footerTemplate", "padZero"] }, { kind: "component", type: i7.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "component", type: i7.AXRowCommandColumnComponent, selector: "ax-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "items"], outputs: ["onItemClick"] }, { kind: "component", type: i7.AXRowDropdownCommandColumnComponent, selector: "ax-dropdown-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "emptyStateTemplate", "emptyStateText", "items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i10.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "ngmodule", type:
1469
+ ], viewQueries: [{ propertyName: "grid", first: true, predicate: ["grid"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.entityDef.category) {\n <axp-layout-start-side id=\"axp-entity-category-drawer\">\n <axp-entity-category\n id=\"axp-entity-category\"\n class=\"ax-w-80\"\n [vm]=\"vm\"\n [searchValue]=\"categorySearchValue()\"\n ></axp-entity-category>\n </axp-layout-start-side>\n }\n <axp-page-toolbar id=\"axp-entity-toolbar\">\n <axp-entity-master-toolbar-view [viewModel]=\"vm\"></axp-entity-master-toolbar-view>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-overflow-auto ax-pt-0\">\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1 ax-pb-1\"\n [class.ax-invisible]=\"!grid.selectedRows.length\"\n >\n <span\n >{{ grid.selectedRows.length }}\n <span>{{ '@general:terms.interface.items-selected' | translate | async }}</span>\n </span>\n <ax-button text=\"@general:terms.interface.unselect-all\" class=\"ax-xs\" (onClick)=\"handleUnselectAll()\"></ax-button>\n </div>\n <ax-data-table\n id=\"axp-entity-table\"\n [allowReordering]=\"true\"\n (onColumnsOrderChanged)=\"onColumnsOrderChanged($event)\"\n #grid\n [showFooter]=\"false\"\n class=\"ax-flex-1\"\n [paging]=\"true\"\n [fetchDataMode]=\"'manual'\"\n [parentField]=\"vm.parentKey()\"\n [loading]=\"{ enabled: true, animation: true }\"\n [dataSource]=\"vm.dataSource\"\n (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowDbClick)=\"handleRowDbClick($event)\"\n (onColumnSizeChanged)=\"onColumnSizeChanged($event)\"\n (onPageChanged)=\"onPageChanged($event)\"\n >\n @if (vm.view().indexCol === true) {\n <ax-index-column id=\"axp-table-col-index\" fixed=\"start\" [width]=\"'80px'\" [padZero]=\"true\"></ax-index-column>\n }\n @if (vm.selectedScopeActionsCount()) {\n <ax-select-column id=\"axp-table-col-select\" fixed=\"start\" [width]=\"'60px'\"></ax-select-column>\n }\n @for (col of vm.columns(); track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer\n [attr.id]=\"'axp-table-col-' + col.name\"\n [expandHandler]=\"$index === 0 && vm.parentKey() ? true : false\"\n [caption]=\"(col.title | translate | async)!\"\n [node]=\"col.node()\"\n [customWidth]=\"col.width\"\n ></axp-widget-column-renderer>\n }\n }\n @if (getCommandRowItems().length) {\n <ax-command-column\n id=\"axp-table-col-commands\"\n fixed=\"end\"\n [width]=\"getCommandRowItems().length * 60 + 'px'\"\n [items]=\"getCommandRowItems()\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-command-column>\n }\n <ax-dropdown-command-column\n id=\"axp-table-col-dropdown-commands\"\n fixed=\"end\"\n [width]=\"'60px'\"\n [items]=\"getDropdownRowItems\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-dropdown-command-column>\n </ax-data-table>\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axp-entity-master-list axp-layout-start-side{min-width:20rem!important;border-inline-end-width:1px;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}axp-entity-master-list axp-layout-header{padding-bottom:.25rem!important}.cdk-drag-preview{border-radius:.375rem;border-width:1px;--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background:rgba(var(--ax-color-on-surface));padding:.5rem;height:max-content!important}.collapsed-search-box{margin-top:0;height:0px;opacity:0}.view-drawer{width:85vw}@media (min-width: 768px){.view-drawer{width:45vw}}@media (min-width: 1024px){.view-drawer{width:35vw}}@media (min-width: 1536px){.view-drawer{width:20vw}}.view-drawer{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));border-inline-start-width:1px;border-inline-start-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));border-top-width:1px;--tw-border-opacity: 1;border-top-color:rgba(var(--ax-sys-color-primary-600),var(--tw-border-opacity, 1))}.view-drawer ax-header{display:flex;align-items:center;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.5rem 1rem}.view-drawer ax-header h2{font-size:1.25rem;line-height:1.75rem;font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lighter-surface),var(--tw-text-opacity, 1))}.view-drawer ax-footer{position:absolute!important;bottom:0!important;width:100%!important;justify-content:flex-start!important;border-top-width:1px!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))!important;padding:.5rem 1rem!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { 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: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXActionSheetModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "ngmodule", type: AXDialogModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i7.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "rowDetailsTemplate", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i7.AXRowIndexColumnComponent, selector: "ax-index-column", inputs: ["width", "caption", "fixed", "footerTemplate", "padZero"] }, { kind: "component", type: i7.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "component", type: i7.AXRowCommandColumnComponent, selector: "ax-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "items"], outputs: ["onItemClick"] }, { kind: "component", type: i7.AXRowDropdownCommandColumnComponent, selector: "ax-dropdown-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "emptyStateTemplate", "emptyStateText", "items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i10.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "ngmodule", type:
1048
1470
  //
1049
1471
  AXPWidgetCoreModule }, { kind: "component", type: i7$1.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "node", "footerTemplate", "expandHandler", "cellTemplate", "headerTemplate"] }, { kind: "ngmodule", type: AXPWidgetsModule }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "component", type:
1050
1472
  //
1051
1473
  AXPEntityMasterToolbarViewComponent, selector: "axp-entity-master-toolbar-view", inputs: ["viewModel"] }, { kind: "component", type:
1052
1474
  //
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 }); }
1475
+ 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", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "searchWithChildren"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1054
1476
  }
1055
1477
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityMasterListViewComponent, decorators: [{
1056
1478
  type: Component,
@@ -1097,4 +1519,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1097
1519
  }], ctorParameters: () => [{ type: i1$1.AXPlatform }], propDecorators: { grid: [{ type: i0.ViewChild, args: ['grid', { isSignal: true }] }] } });
1098
1520
 
1099
1521
  export { AXPEntityMasterListViewComponent };
1100
- //# sourceMappingURL=acorex-platform-themes-default-entity-master-list-view.component-BbACUabi.mjs.map
1522
+ //# sourceMappingURL=acorex-platform-themes-default-entity-master-list-view.component-CenhnHXi.mjs.map