@agorapulse/ui-components 22.0.29 → 22.0.31
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/agorapulse-ui-components-22.0.31.tgz +0 -0
- package/fesm2022/agorapulse-ui-components-filter-dropdown.mjs +21 -13
- package/fesm2022/agorapulse-ui-components-filter-dropdown.mjs.map +1 -1
- package/fesm2022/agorapulse-ui-components-nav-selector-testing.mjs +4 -2
- package/fesm2022/agorapulse-ui-components-nav-selector-testing.mjs.map +1 -1
- package/fesm2022/agorapulse-ui-components-nav-selector.mjs +279 -141
- package/fesm2022/agorapulse-ui-components-nav-selector.mjs.map +1 -1
- package/package.json +1 -1
- package/types/agorapulse-ui-components-filter-dropdown.d.ts +6 -0
- package/types/agorapulse-ui-components-nav-selector-testing.d.ts +3 -1
- package/types/agorapulse-ui-components-nav-selector.d.ts +33 -1
- package/agorapulse-ui-components-22.0.29.tgz +0 -0
|
@@ -19,6 +19,7 @@ import { apMore, apFeatureLock as apFeatureLock$1, apPlus } from '@agorapulse/ui
|
|
|
19
19
|
import { CheckboxComponent } from '@agorapulse/ui-components/checkbox';
|
|
20
20
|
import { CounterComponent } from '@agorapulse/ui-components/counter';
|
|
21
21
|
import { ActionDropdownComponent, ActionDropdownTriggerDirective } from '@agorapulse/ui-components/action-dropdown';
|
|
22
|
+
import { FilterDropdownButtonComponent } from '@agorapulse/ui-components/filter-dropdown';
|
|
22
23
|
|
|
23
24
|
class NavSelectorPopoverItemComponent {
|
|
24
25
|
selected = input(false, /* @ts-ignore */
|
|
@@ -200,6 +201,92 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
200
201
|
}]
|
|
201
202
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { apNavSelectorPopoverTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "apNavSelectorPopoverTrigger", required: true }] }], apNavSelectorPopoverTriggerMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "apNavSelectorPopoverTriggerMode", required: false }] }], apNavSelectorPopoverDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "apNavSelectorPopoverDisabled", required: false }] }] } });
|
|
202
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Create a Record of key/value pairs from an array of objects
|
|
206
|
+
* @param array
|
|
207
|
+
* @param key attribute of the object to use as key
|
|
208
|
+
*/
|
|
209
|
+
const associateBy = (array, key) => array.reduce((previousValue, currentValue) => {
|
|
210
|
+
previousValue[`${currentValue[key]}`] = currentValue;
|
|
211
|
+
return previousValue;
|
|
212
|
+
}, {});
|
|
213
|
+
const isInternalNavSelectorEntryALeafFocusable = (leaf, { parentFolded, multipleMode }) => {
|
|
214
|
+
if (parentFolded) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
if (multipleMode) {
|
|
218
|
+
return !leaf.disabled && !leaf.displayTokenInvalid && !leaf.displayFeatureLocked;
|
|
219
|
+
}
|
|
220
|
+
return !leaf.disabled;
|
|
221
|
+
};
|
|
222
|
+
const computeFolded = (entry, children) => {
|
|
223
|
+
// If the entry is not folded, we keep it unfolded
|
|
224
|
+
if (!entry.folded) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
return !children.some(child => (isInternalNavSelectorEntryALeaf(child) && (child.selected || !child.folded)) ||
|
|
228
|
+
(isInternalNavSelectorEntryANode(child) && !child.folded) ||
|
|
229
|
+
(isInternalNavSelectorEntryAGroup(child) && child.undeterminedSelection));
|
|
230
|
+
};
|
|
231
|
+
const computeNumberOfDisplayableChildrenOnUnfold = (entry) => {
|
|
232
|
+
if (isInternalNavSelectorEntryANode(entry)) {
|
|
233
|
+
const nbChildren = entry.children.length;
|
|
234
|
+
const nbDisplayableChildrenOfUnfoldedChild = entry.children
|
|
235
|
+
.filter(child => !child.folded)
|
|
236
|
+
.reduce((acc, child) => {
|
|
237
|
+
return acc + computeNumberOfDisplayableChildrenOnUnfold(child);
|
|
238
|
+
}, 0);
|
|
239
|
+
return nbDisplayableChildrenOfUnfoldedChild + nbChildren;
|
|
240
|
+
}
|
|
241
|
+
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
242
|
+
return entry.details.length;
|
|
243
|
+
}
|
|
244
|
+
return 0;
|
|
245
|
+
};
|
|
246
|
+
const computeSelectableUids = (entries) => {
|
|
247
|
+
return entries.flatMap(entry => computeSelectableUidsByEntry(entry));
|
|
248
|
+
};
|
|
249
|
+
const computeSelectableUidsByEntry = (entry) => {
|
|
250
|
+
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
251
|
+
// Disabled leafs can now be selected programmatically
|
|
252
|
+
return [entry.uid, ...entry.details.filter(detail => !detail.hidden).map(detail => detail.uid)];
|
|
253
|
+
}
|
|
254
|
+
if (isInternalNavSelectorEntryANode(entry)) {
|
|
255
|
+
return [entry.uid, ...entry.children.flatMap(child => computeSelectableUidsByEntry(child))];
|
|
256
|
+
}
|
|
257
|
+
return [];
|
|
258
|
+
};
|
|
259
|
+
const computeVisibleUids = (entries) => {
|
|
260
|
+
return entries.flatMap(entry => computeVisibleUidsByEntry(entry));
|
|
261
|
+
};
|
|
262
|
+
const computeVisibleUidsByEntry = (entry) => {
|
|
263
|
+
if (entry.hidden) {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
267
|
+
return [entry.uid, ...entry.details.filter(detail => !detail.hidden).map(detail => detail.uid)];
|
|
268
|
+
}
|
|
269
|
+
if (isInternalNavSelectorEntryANode(entry)) {
|
|
270
|
+
return entry.children.flatMap(child => computeVisibleUidsByEntry(child));
|
|
271
|
+
}
|
|
272
|
+
// Fallback for unexpected entry types (should never be reached)
|
|
273
|
+
return [];
|
|
274
|
+
};
|
|
275
|
+
const getLeaves = (entries) => {
|
|
276
|
+
return entries.flatMap(entry => {
|
|
277
|
+
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
278
|
+
return [entry];
|
|
279
|
+
}
|
|
280
|
+
if (isInternalNavSelectorEntryAGroup(entry)) {
|
|
281
|
+
return entry.children;
|
|
282
|
+
}
|
|
283
|
+
if (isInternalNavSelectorEntryACategory(entry)) {
|
|
284
|
+
return getLeaves(entry.children);
|
|
285
|
+
}
|
|
286
|
+
return [];
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
|
|
203
290
|
/**
|
|
204
291
|
* NavSelectorAccessibility is a utility class that provides methods to manage the accessibility and the focusability of nav selector entries.
|
|
205
292
|
*/
|
|
@@ -332,13 +419,18 @@ class NavSelectorAccessibility {
|
|
|
332
419
|
*/
|
|
333
420
|
static flatten(entries) {
|
|
334
421
|
return entries.flatMap(entry => {
|
|
422
|
+
// The accessibility object is cloned as well: the focus helpers below assign tabIndex in place, and
|
|
423
|
+
// sharing it with the source entries would retroactively change every previously returned tree.
|
|
335
424
|
if (isInternalNavSelectorEntryAGroup(entry) || isInternalNavSelectorEntryACategory(entry)) {
|
|
336
|
-
return [{ ...entry, children: [] }, ...this.flatten(entry.children)];
|
|
425
|
+
return [{ ...entry, accessibility: { ...entry.accessibility }, children: [] }, ...this.flatten(entry.children)];
|
|
337
426
|
}
|
|
338
427
|
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
339
|
-
return [
|
|
428
|
+
return [
|
|
429
|
+
{ ...entry, accessibility: { ...entry.accessibility }, details: [] },
|
|
430
|
+
...entry.details.map(detail => ({ ...detail, accessibility: { ...detail.accessibility } })),
|
|
431
|
+
];
|
|
340
432
|
}
|
|
341
|
-
return [{ ...entry }];
|
|
433
|
+
return [{ ...entry, accessibility: { ...entry.accessibility } }];
|
|
342
434
|
});
|
|
343
435
|
}
|
|
344
436
|
/**
|
|
@@ -378,78 +470,6 @@ class NavSelectorAccessibility {
|
|
|
378
470
|
}
|
|
379
471
|
}
|
|
380
472
|
|
|
381
|
-
/**
|
|
382
|
-
* Create a Record of key/value pairs from an array of objects
|
|
383
|
-
* @param array
|
|
384
|
-
* @param key attribute of the object to use as key
|
|
385
|
-
*/
|
|
386
|
-
const associateBy = (array, key) => array.reduce((previousValue, currentValue) => {
|
|
387
|
-
previousValue[`${currentValue[key]}`] = currentValue;
|
|
388
|
-
return previousValue;
|
|
389
|
-
}, {});
|
|
390
|
-
const isInternalNavSelectorEntryALeafFocusable = (leaf, { parentFolded, multipleMode }) => {
|
|
391
|
-
if (parentFolded) {
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
if (multipleMode) {
|
|
395
|
-
return !leaf.disabled && !leaf.displayTokenInvalid && !leaf.displayFeatureLocked;
|
|
396
|
-
}
|
|
397
|
-
return !leaf.disabled;
|
|
398
|
-
};
|
|
399
|
-
const computeFolded = (entry, children) => {
|
|
400
|
-
// If the entry is not folded, we keep it unfolded
|
|
401
|
-
if (!entry.folded) {
|
|
402
|
-
return false;
|
|
403
|
-
}
|
|
404
|
-
return !children.some(child => (isInternalNavSelectorEntryALeaf(child) && (child.selected || !child.folded)) ||
|
|
405
|
-
(isInternalNavSelectorEntryANode(child) && !child.folded) ||
|
|
406
|
-
(isInternalNavSelectorEntryAGroup(child) && child.undeterminedSelection));
|
|
407
|
-
};
|
|
408
|
-
const computeNumberOfDisplayableChildrenOnUnfold = (entry) => {
|
|
409
|
-
if (isInternalNavSelectorEntryANode(entry)) {
|
|
410
|
-
const nbChildren = entry.children.length;
|
|
411
|
-
const nbDisplayableChildrenOfUnfoldedChild = entry.children
|
|
412
|
-
.filter(child => !child.folded)
|
|
413
|
-
.reduce((acc, child) => {
|
|
414
|
-
return acc + computeNumberOfDisplayableChildrenOnUnfold(child);
|
|
415
|
-
}, 0);
|
|
416
|
-
return nbDisplayableChildrenOfUnfoldedChild + nbChildren;
|
|
417
|
-
}
|
|
418
|
-
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
419
|
-
return entry.details.length;
|
|
420
|
-
}
|
|
421
|
-
return 0;
|
|
422
|
-
};
|
|
423
|
-
const computeSelectableUids = (entries) => {
|
|
424
|
-
return entries.flatMap(entry => computeSelectableUidsByEntry(entry));
|
|
425
|
-
};
|
|
426
|
-
const computeSelectableUidsByEntry = (entry) => {
|
|
427
|
-
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
428
|
-
// Disabled leafs can now be selected programmatically
|
|
429
|
-
return [entry.uid, ...entry.details.filter(detail => !detail.hidden).map(detail => detail.uid)];
|
|
430
|
-
}
|
|
431
|
-
if (isInternalNavSelectorEntryANode(entry)) {
|
|
432
|
-
return [entry.uid, ...entry.children.flatMap(child => computeSelectableUidsByEntry(child))];
|
|
433
|
-
}
|
|
434
|
-
return [];
|
|
435
|
-
};
|
|
436
|
-
const computeVisibleUids = (entries) => {
|
|
437
|
-
return entries.flatMap(entry => computeVisibleUidsByEntry(entry));
|
|
438
|
-
};
|
|
439
|
-
const computeVisibleUidsByEntry = (entry) => {
|
|
440
|
-
if (entry.hidden) {
|
|
441
|
-
return [];
|
|
442
|
-
}
|
|
443
|
-
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
444
|
-
return [entry.uid, ...entry.details.filter(detail => !detail.hidden).map(detail => detail.uid)];
|
|
445
|
-
}
|
|
446
|
-
if (isInternalNavSelectorEntryANode(entry)) {
|
|
447
|
-
return entry.children.flatMap(child => computeVisibleUidsByEntry(child));
|
|
448
|
-
}
|
|
449
|
-
// Fallback for unexpected entry types (should never be reached)
|
|
450
|
-
return [];
|
|
451
|
-
};
|
|
452
|
-
|
|
453
473
|
/**
|
|
454
474
|
* Class to handle the folding and unfolding of nav selector entries.
|
|
455
475
|
*/
|
|
@@ -1124,6 +1144,7 @@ class NavSelectorBuilder {
|
|
|
1124
1144
|
detailsDisplayable,
|
|
1125
1145
|
details: leaf.details.map(detail => this.buildLeafDetail(detail, level + 1, focusable && !folded)),
|
|
1126
1146
|
detailSelected: false,
|
|
1147
|
+
tags: leaf.tags,
|
|
1127
1148
|
type: 'LEAF',
|
|
1128
1149
|
viewMoreDisplayable,
|
|
1129
1150
|
viewMoreDisplayed: viewMoreDisplayable,
|
|
@@ -1196,40 +1217,56 @@ class NavSelectorBuilder {
|
|
|
1196
1217
|
*/
|
|
1197
1218
|
class NavSelectorFilter {
|
|
1198
1219
|
/**
|
|
1199
|
-
* Filters the entries based on the search string
|
|
1220
|
+
* Filters the entries based on the search string and the filtered tags.
|
|
1200
1221
|
*
|
|
1201
1222
|
* The search string is normalized and lowercase and trimmed.
|
|
1202
1223
|
*
|
|
1203
|
-
*
|
|
1204
|
-
*
|
|
1205
|
-
*
|
|
1206
|
-
*
|
|
1207
|
-
*
|
|
1224
|
+
* The search picks a scope, the tags filter inside it: when a category or a group matches the search string, every
|
|
1225
|
+
* entry it holds inherits that match, and only the tags keep filtering underneath. A leaf is therefore displayed
|
|
1226
|
+
* when the search is satisfied, by its own alias or by one of its parents, and when it carries one of the filtered
|
|
1227
|
+
* tags. Categories and groups carry no tag of their own, so they are displayed for the leaves they still hold and
|
|
1228
|
+
* hidden once all of them are.
|
|
1208
1229
|
*
|
|
1209
|
-
*
|
|
1230
|
+
* Displayed nodes are unfolded and marked as focusable, hidden entries are marked as not focusable.
|
|
1210
1231
|
*
|
|
1211
1232
|
* It also determines whenever counter and token invalid should be displayed on groups and leaves.
|
|
1212
1233
|
*
|
|
1213
1234
|
* @param entries The entries to filter.
|
|
1214
|
-
* @param
|
|
1235
|
+
* @param criteria all criteria to apply.
|
|
1215
1236
|
* @param multipleMode to update the focusable state of leaves correctly.
|
|
1216
1237
|
* @returns The filtered entries.
|
|
1217
1238
|
*/
|
|
1218
|
-
static filter(entries,
|
|
1219
|
-
const formattedSearch = this.cleanValue(search);
|
|
1220
|
-
|
|
1239
|
+
static filter(entries, criteria, multipleMode) {
|
|
1240
|
+
const formattedSearch = this.cleanValue(criteria.search);
|
|
1241
|
+
const shouldFilterByTags = Object.values(criteria.tags).some(tags => tags.length > 0);
|
|
1242
|
+
if (!formattedSearch && !shouldFilterByTags) {
|
|
1221
1243
|
return this.resetState(entries);
|
|
1222
1244
|
}
|
|
1223
|
-
|
|
1245
|
+
const tags = Object.entries(criteria.tags).reduce((acc, [key, values]) => {
|
|
1246
|
+
// A tag name selected with no value filters nothing, keeping it would hide every leaf.
|
|
1247
|
+
if (!values.length) {
|
|
1248
|
+
return acc;
|
|
1249
|
+
}
|
|
1250
|
+
const castKey = key;
|
|
1251
|
+
const tagValues = (acc[castKey] ??= {});
|
|
1252
|
+
values.forEach(value => (tagValues[value] = true));
|
|
1253
|
+
return acc;
|
|
1254
|
+
}, {});
|
|
1255
|
+
return this.filterEntries(entries, { search: formattedSearch, tags }, multipleMode);
|
|
1224
1256
|
}
|
|
1225
|
-
static filterEntries(entries,
|
|
1257
|
+
static filterEntries(entries, formattedCriteria, multipleMode, searchSatisfiedByAncestor = false) {
|
|
1226
1258
|
const newEntries = entries.map(entry => {
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
}
|
|
1259
|
+
// Matching the search opens a scope: descendants inherit the match and only the tags filter underneath.
|
|
1260
|
+
const searchSatisfied = searchSatisfiedByAncestor || this.searchSatisfiedBy(entry, formattedCriteria);
|
|
1230
1261
|
if (isInternalNavSelectorEntryANode(entry)) {
|
|
1231
|
-
|
|
1232
|
-
|
|
1262
|
+
// A node carries no tag of its own, so it is kept for the entries it still holds. An empty node has
|
|
1263
|
+
// none to speak for it: it is kept when it satisfies the search itself, and dropped as soon as tags
|
|
1264
|
+
// are filtered, having none.
|
|
1265
|
+
const children = this.filterEntries(entry.children, formattedCriteria, multipleMode, searchSatisfied);
|
|
1266
|
+
const displayable = children.length
|
|
1267
|
+
? children.some(({ hidden }) => !hidden)
|
|
1268
|
+
: searchSatisfied && !this.tagsFiltered(formattedCriteria);
|
|
1269
|
+
if (!displayable) {
|
|
1233
1270
|
return {
|
|
1234
1271
|
...entry,
|
|
1235
1272
|
children,
|
|
@@ -1248,6 +1285,9 @@ class NavSelectorFilter {
|
|
|
1248
1285
|
};
|
|
1249
1286
|
}
|
|
1250
1287
|
if (isInternalNavSelectorEntryALeaf(entry)) {
|
|
1288
|
+
if (searchSatisfied && this.tagsSatisfiedBy(entry, formattedCriteria)) {
|
|
1289
|
+
return this.displayLeaf(entry, multipleMode);
|
|
1290
|
+
}
|
|
1251
1291
|
return {
|
|
1252
1292
|
...entry,
|
|
1253
1293
|
focusable: false,
|
|
@@ -1258,54 +1298,51 @@ class NavSelectorFilter {
|
|
|
1258
1298
|
})),
|
|
1259
1299
|
};
|
|
1260
1300
|
}
|
|
1261
|
-
return
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1301
|
+
return searchSatisfied
|
|
1302
|
+
? entry
|
|
1303
|
+
: {
|
|
1304
|
+
...entry,
|
|
1305
|
+
focusable: false,
|
|
1306
|
+
hidden: true,
|
|
1307
|
+
};
|
|
1266
1308
|
});
|
|
1267
1309
|
return NavSelectorAccessibility.resetFocus(newEntries);
|
|
1268
1310
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
const children = entry.children.map(child => this.recursivelyUnfoldEntry(child, multipleMode));
|
|
1297
|
-
return {
|
|
1298
|
-
...entry,
|
|
1299
|
-
focusable: true,
|
|
1300
|
-
folded: false,
|
|
1301
|
-
hidden: false,
|
|
1302
|
-
children,
|
|
1303
|
-
};
|
|
1311
|
+
/**
|
|
1312
|
+
* Displays a leaf that satisfies every criterion, its details following the leaf own folded state.
|
|
1313
|
+
*/
|
|
1314
|
+
static displayLeaf(leaf, multipleMode) {
|
|
1315
|
+
return {
|
|
1316
|
+
...leaf,
|
|
1317
|
+
hidden: false,
|
|
1318
|
+
focusable: isInternalNavSelectorEntryALeafFocusable(leaf, { parentFolded: false, multipleMode }),
|
|
1319
|
+
displayCounter: leaf.folded && leaf.counterDisplayable,
|
|
1320
|
+
details: leaf.details.map(detail => ({
|
|
1321
|
+
...detail,
|
|
1322
|
+
focusable: !leaf.folded,
|
|
1323
|
+
})),
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Whether the entry satisfies the search by its own alias. An inactive search is satisfied by every entry.
|
|
1328
|
+
*/
|
|
1329
|
+
static searchSatisfiedBy(entry, formattedCriteria) {
|
|
1330
|
+
return !formattedCriteria.search || this.cleanValue(entry.alias).includes(formattedCriteria.search);
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Whether the leaf carries at least one of the filtered tag values. Inactive tag criteria are satisfied by every leaf.
|
|
1334
|
+
*/
|
|
1335
|
+
static tagsSatisfiedBy(leaf, formattedCriteria) {
|
|
1336
|
+
if (!this.tagsFiltered(formattedCriteria)) {
|
|
1337
|
+
return true;
|
|
1304
1338
|
}
|
|
1305
|
-
return
|
|
1339
|
+
return Object.entries(leaf.tags).some(([key, tags]) => tags.some(tag => (formattedCriteria.tags[key] ?? {})[tag]));
|
|
1306
1340
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1341
|
+
/**
|
|
1342
|
+
* Whether at least one tag value is being filtered on.
|
|
1343
|
+
*/
|
|
1344
|
+
static tagsFiltered(formattedCriteria) {
|
|
1345
|
+
return Object.keys(formattedCriteria.tags).length > 0;
|
|
1309
1346
|
}
|
|
1310
1347
|
static cleanValue(value) {
|
|
1311
1348
|
return value.trim().normalize('NFKC').toLowerCase();
|
|
@@ -1814,8 +1851,18 @@ class NavSelectorState {
|
|
|
1814
1851
|
noResults: '',
|
|
1815
1852
|
viewMore: '',
|
|
1816
1853
|
viewLess: '',
|
|
1854
|
+
filter: '',
|
|
1855
|
+
clearFilters: '',
|
|
1856
|
+
applyFilters: '',
|
|
1857
|
+
tagNames: { attributes: '' },
|
|
1817
1858
|
}, /* @ts-ignore */
|
|
1818
1859
|
...(ngDevMode ? [{ debugName: "_texts" }] : /* istanbul ignore next */ []));
|
|
1860
|
+
tagsFilterDisplayed = computed(() => {
|
|
1861
|
+
return getLeaves(this.entries()).some(leaf => Object.values(leaf.tags).some(tag => Object.values(tag).length > 0));
|
|
1862
|
+
}, /* @ts-ignore */
|
|
1863
|
+
...(ngDevMode ? [{ debugName: "tagsFilterDisplayed" }] : /* istanbul ignore next */ []));
|
|
1864
|
+
tagsFilters = signal({}, /* @ts-ignore */
|
|
1865
|
+
...(ngDevMode ? [{ debugName: "tagsFilters" }] : /* istanbul ignore next */ []));
|
|
1819
1866
|
isMultipleModeEnabled = this.multipleModeEnabled;
|
|
1820
1867
|
search = signal('', /* @ts-ignore */
|
|
1821
1868
|
...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
|
|
@@ -1861,9 +1908,9 @@ class NavSelectorState {
|
|
|
1861
1908
|
});
|
|
1862
1909
|
});
|
|
1863
1910
|
effect(() => {
|
|
1864
|
-
const
|
|
1911
|
+
const criteria = { search: this.search(), tags: this.tagsFilters() };
|
|
1865
1912
|
untracked(() => {
|
|
1866
|
-
this._entries.update(entries => NavSelectorFilter.filter(entries,
|
|
1913
|
+
this._entries.update(entries => NavSelectorFilter.filter(entries, criteria, this.multipleModeEnabled()));
|
|
1867
1914
|
});
|
|
1868
1915
|
});
|
|
1869
1916
|
}
|
|
@@ -1890,7 +1937,7 @@ class NavSelectorState {
|
|
|
1890
1937
|
const previouslySelectedUids = this.collectSelectedUids(oldEntries);
|
|
1891
1938
|
const mergeEntries = NavSelectorMerger.mergeInternalNavSelectorEntries(newEntries, oldEntries);
|
|
1892
1939
|
const unfoldedEntries = this.unfoldParentsOfNewlySelectedEntries(mergeEntries, previouslySelectedUids);
|
|
1893
|
-
return NavSelectorFilter.filter(unfoldedEntries, this.search(), this.multipleModeEnabled());
|
|
1940
|
+
return NavSelectorFilter.filter(unfoldedEntries, { search: this.search(), tags: this.tagsFilters() }, this.multipleModeEnabled());
|
|
1894
1941
|
});
|
|
1895
1942
|
}
|
|
1896
1943
|
/**
|
|
@@ -2054,6 +2101,12 @@ class NavSelectorState {
|
|
|
2054
2101
|
minified: !this.expanded(),
|
|
2055
2102
|
};
|
|
2056
2103
|
}
|
|
2104
|
+
filterTags(tags) {
|
|
2105
|
+
this.tagsFilters.set(tags);
|
|
2106
|
+
}
|
|
2107
|
+
clearFilterTags() {
|
|
2108
|
+
this.tagsFilters.set({});
|
|
2109
|
+
}
|
|
2057
2110
|
fold(entry) {
|
|
2058
2111
|
this._entries.update(entries => NavSelectorFolding.fold(entries, entry.uid, this.getFoldingOptions()));
|
|
2059
2112
|
}
|
|
@@ -3071,6 +3124,90 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
3071
3124
|
], template: "<!-- eslint-disable @angular-eslint/template/interactive-supports-focus -->\n@if (navSelectorCategoryPresenter.expanded()) {\n <div\n class=\"content\"\n apTooltipPosition=\"right\"\n [attr.data-test]=\"dataTestId()\"\n [apTooltip]=\"tooltipContent()\"\n [apTooltipDisabled]=\"tooltipDisabled()\"\n [apTreeNodeAccessibility]=\"category()\"\n (keydown.space)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\"\n (keydown.enter)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\"\n (click)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\">\n @if (category().avatarDisplayed) {\n @if (category().avatarPictureUrlDisplayed) {\n <ap-avatar\n size=\"16\"\n [showInitials]=\"true\"\n [username]=\"category().alias\"\n [profilePicture]=\"category().avatarPictureUrl\"\n [rounded]=\"category().avatarRounded\" />\n } @else {\n <ap-symbol\n size=\"sm\"\n color=\"grey-blue\"\n [symbolId]=\"category().avatarSymbolId\" />\n }\n }\n\n <span\n #alias\n class=\"caption\">\n {{ category().alias }}\n </span>\n\n <ap-symbol\n class=\"folding-button\"\n size=\"sm\"\n [symbolId]=\"foldSymbol()\" />\n </div>\n\n <div\n class=\"children-container\"\n [@accordion]=\"{\n value: animationState(),\n params: {\n maxHeight: maxHeight(),\n },\n }\">\n @if (!foldedWithDelay()) {\n <div class=\"children\">\n @if (category().children.length === 0) {\n <div class=\"empty-state\">\n @if (category().emptyStateTitle) {\n <div class=\"empty-state__title\">\n {{ category().emptyStateTitle }}\n </div>\n }\n @if (category().emptyStateAction; as emptyStateAction) {\n <a\n class=\"standalone\"\n [attr.id]=\"emptyStateAction?.id\"\n (click)=\"onEmptyStateActionClick(emptyStateAction.name)\">\n @if (emptyStateAction?.symbolId; as symbolId) {\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"symbolId\" />\n }\n {{ emptyStateAction.title }}\n @if (emptyStateAction?.featureLocked) {\n <ap-symbol\n size=\"sm\"\n color=\"purple\"\n symbolId=\"feature-lock\" />\n }\n </a>\n }\n </div>\n } @else {\n @for (child of category().children; track child.uid) {\n @if (!child.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"child.type === 'GROUP'\">\n @if (child.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"child\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (child.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"child\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n }\n </div>\n }\n }\n }\n </div>\n }\n </div>\n} @else {\n <div\n class=\"content\"\n apTooltipPosition=\"right\"\n [apTreeNodeAccessibility]=\"category()\"\n [apTooltip]=\"tooltipContent()\"\n [apTooltipDisabled]=\"tooltipDisabled()\"\n (click)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\"\n (keydown.space)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\"\n (keydown.enter)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\">\n <div class=\"name-container\">\n <span class=\"caption\">{{ category().alias }}</span>\n </div>\n\n <div class=\"toggle\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"foldSymbol()\" />\n </div>\n </div>\n\n <div\n class=\"children-container\"\n [@accordion]=\"{\n value: animationState(),\n params: {\n maxHeight: maxHeight(),\n },\n }\">\n @if (!foldedWithDelay()) {\n <div class=\"children\">\n @for (child of category().children; track child.uid) {\n @if (!child.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"child.type === 'GROUP'\">\n @if (child.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"child\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (child.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"child\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n }\n </div>\n }\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:flex;align-items:center;flex-shrink:0;align-self:stretch;flex-direction:column}:host .children-container{align-self:stretch}:host .children-container .empty-state{display:flex;padding:0 var(--ref-spacing-xxs) var(--ref-spacing-xxs) var(--ref-spacing-xxs);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs)}:host .children-container .empty-state__title{font-size:var(--ref-font-size-xs);font-weight:var(--ref-font-weight-regular);font-style:italic;color:var(--ref-color-grey-80)}:host .folding-button{display:flex;width:16px;height:16px;justify-content:center;align-items:center;flex-shrink:0}:host .content{padding:0 var(--ref-spacing-xxs);display:flex;height:36px;align-items:center;gap:var(--ref-spacing-xxs);flex-shrink:0;flex-grow:1;align-self:stretch;cursor:pointer}:host .content:hover{border-radius:var(--ref-border-radius-sm);background:var(--ref-color-electric-blue-10)}:host .content:active{border-radius:var(--ref-border-radius-sm);background:var(--ref-color-electric-blue-20)}:host .content:focus-visible{outline:none;border-radius:var(--ref-border-radius-sm);background:var(--ref-color-electric-blue-10);box-shadow:0 0 0 1px var(--ref-color-white),0 0 0 3px var(--ref-color-electric-blue-100)}:host ap-symbol[symbol-id=chevron-down],:host ap-symbol[symbol-id=chevron-up]{color:var(--ref-color-grey-80)}:host .caption{-webkit-box-orient:vertical;-webkit-line-clamp:1;flex:1 0 0;overflow:hidden;white-space:nowrap;color:var(--ref-color-grey-100);text-overflow:ellipsis;font-family:Averta;font-size:var(--sys-text-style-h4-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-md)}:host .children{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch}:host .children .entry{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;margin-left:calc(-1 * var(--ref-spacing-xxs));margin-right:calc(-1 * var(--ref-spacing-xxs))}:host .children .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .children .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .children .entry.folder:first-child{padding-top:0}:host .children .entry.folder:last-child{border-bottom:none;padding-bottom:0}:host .children .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .children .entry:not(.folder):first-child:not(:last-child){padding-top:var(--ref-spacing-xxs)}:host .children .entry:not(.folder):last-child:not(:first-child){padding-bottom:var(--ref-spacing-xxs);border-bottom:none}:host .children .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .children .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host.minified .name-container{overflow:hidden;display:flex}:host.minified .name-container span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;display:inline-block}:host.minified .caption{white-space:nowrap}:host.minified .content{position:relative}:host.minified .content .toggle{position:absolute;display:none}:host.minified .content:hover .toggle,:host.minified .content:focus-visible .toggle{inset:0;display:flex;justify-content:center;align-items:center}:host.minified .content:hover .name-container,:host.minified .content:focus-visible .name-container{display:none}\n"] }]
|
|
3072
3125
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: NavSelectorCategoryPresenter }], propDecorators: { category: [{ type: i0.Input, args: [{ isSignal: true, alias: "category", required: true }] }], emptyStateActionClicked: [{ type: i0.Output, args: ["emptyStateActionClicked"] }], actionClicked: [{ type: i0.Output, args: ["actionClicked"] }], aliasEl: [{ type: i0.ViewChild, args: ['alias', { isSignal: true }] }] } });
|
|
3073
3126
|
|
|
3127
|
+
class NavSelectorTagsFilterComponent {
|
|
3128
|
+
state = inject(NavSelectorState);
|
|
3129
|
+
filterButtonText = computed(() => this.state.texts().filter, /* @ts-ignore */
|
|
3130
|
+
...(ngDevMode ? [{ debugName: "filterButtonText" }] : /* istanbul ignore next */ []));
|
|
3131
|
+
clearFiltersText = computed(() => this.state.texts().clearFilters, /* @ts-ignore */
|
|
3132
|
+
...(ngDevMode ? [{ debugName: "clearFiltersText" }] : /* istanbul ignore next */ []));
|
|
3133
|
+
applyFiltersText = computed(() => this.state.texts().applyFilters, /* @ts-ignore */
|
|
3134
|
+
...(ngDevMode ? [{ debugName: "applyFiltersText" }] : /* istanbul ignore next */ []));
|
|
3135
|
+
value = computed(() => Object.entries(this.state.tagsFilters()).reduce((previousValue, [key, values]) => {
|
|
3136
|
+
previousValue[key] = {
|
|
3137
|
+
filterType: 'checkbox',
|
|
3138
|
+
selected: values,
|
|
3139
|
+
};
|
|
3140
|
+
return previousValue;
|
|
3141
|
+
}, {}), /* @ts-ignore */
|
|
3142
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
3143
|
+
uniqueTagValuesByTagName = computed(() => {
|
|
3144
|
+
return getLeaves(this.state.entries())
|
|
3145
|
+
.map(({ tags }) => tags)
|
|
3146
|
+
.reduce((previousValue, currentValue) => {
|
|
3147
|
+
Object.entries(currentValue).forEach(([tagName, tagValues]) => {
|
|
3148
|
+
if (!previousValue[tagName]) {
|
|
3149
|
+
previousValue[tagName] = {};
|
|
3150
|
+
}
|
|
3151
|
+
for (const tagValue of tagValues) {
|
|
3152
|
+
previousValue[tagName][tagValue] = true;
|
|
3153
|
+
}
|
|
3154
|
+
});
|
|
3155
|
+
return previousValue;
|
|
3156
|
+
}, {});
|
|
3157
|
+
}, /* @ts-ignore */
|
|
3158
|
+
...(ngDevMode ? [{ debugName: "uniqueTagValuesByTagName" }] : /* istanbul ignore next */ []));
|
|
3159
|
+
groups = computed(() => {
|
|
3160
|
+
const tagNames = this.state.texts().tagNames;
|
|
3161
|
+
return Object.entries(this.uniqueTagValuesByTagName()).map(([tagName, tagValues]) => ({
|
|
3162
|
+
key: tagName,
|
|
3163
|
+
// Tags come from consumer data, so a tag name outside NavSelectorLeafTags may turn up untranslated at
|
|
3164
|
+
// runtime. Showing it raw is poor, but better than showing nothing at all.
|
|
3165
|
+
title: tagNames[tagName] ?? tagName,
|
|
3166
|
+
expanded: false,
|
|
3167
|
+
filterType: 'checkbox',
|
|
3168
|
+
items: Object.keys(tagValues).map(value => ({ label: value, name: value })),
|
|
3169
|
+
}));
|
|
3170
|
+
}, /* @ts-ignore */
|
|
3171
|
+
...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
|
|
3172
|
+
onApplyFilters(dropdownOutput) {
|
|
3173
|
+
this.state.filterTags(Object.entries(dropdownOutput).reduce((previousValue, [key, dropdownValues]) => {
|
|
3174
|
+
previousValue[key] = dropdownValues.selected;
|
|
3175
|
+
return previousValue;
|
|
3176
|
+
}, {}));
|
|
3177
|
+
}
|
|
3178
|
+
onClearFilters() {
|
|
3179
|
+
this.state.clearFilterTags();
|
|
3180
|
+
}
|
|
3181
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NavSelectorTagsFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3182
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: NavSelectorTagsFilterComponent, isStandalone: true, selector: "ap-nav-selector-tags-filter", ngImport: i0, template: `
|
|
3183
|
+
<ap-filter-dropdown-button
|
|
3184
|
+
[buttonFilterText]="filterButtonText()"
|
|
3185
|
+
[clearFilterText]="clearFiltersText()"
|
|
3186
|
+
[applyFiltersText]="applyFiltersText()"
|
|
3187
|
+
[groups]="groups()"
|
|
3188
|
+
[closable]="false"
|
|
3189
|
+
[value]="value()"
|
|
3190
|
+
[needApplyButton]="true"
|
|
3191
|
+
(clearFilters)="onClearFilters()"
|
|
3192
|
+
(applyFilters)="onApplyFilters($event)" />
|
|
3193
|
+
`, isInline: true, styles: [""], dependencies: [{ kind: "component", type: FilterDropdownButtonComponent, selector: "ap-filter-dropdown-button", inputs: ["buttonFilterText", "groups", "value", "savedValue", "needApplyButton", "needClearButton", "closable", "expandOnOpen", "presetsFeatureLocked", "savePresetsMode", "editingPresetsMode", "showBackdrop", "disabled", "defaultPosition", "panelClass", "saveNewPresetsText", "saveAsNewPresetText", "savePresetText", "updateExistingPresetText", "resetFilterText", "applyFiltersText", "clearFilterText"], outputs: ["opened", "closed", "presetsLockedClicked", "saveNewPresets", "updatePresets", "applyFilters", "clearFilters", "resetFilters", "lockedFeatureClicked", "filterDropdownGroupLockedClicked"] }] });
|
|
3194
|
+
}
|
|
3195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NavSelectorTagsFilterComponent, decorators: [{
|
|
3196
|
+
type: Component,
|
|
3197
|
+
args: [{ selector: 'ap-nav-selector-tags-filter', template: `
|
|
3198
|
+
<ap-filter-dropdown-button
|
|
3199
|
+
[buttonFilterText]="filterButtonText()"
|
|
3200
|
+
[clearFilterText]="clearFiltersText()"
|
|
3201
|
+
[applyFiltersText]="applyFiltersText()"
|
|
3202
|
+
[groups]="groups()"
|
|
3203
|
+
[closable]="false"
|
|
3204
|
+
[value]="value()"
|
|
3205
|
+
[needApplyButton]="true"
|
|
3206
|
+
(clearFilters)="onClearFilters()"
|
|
3207
|
+
(applyFilters)="onApplyFilters($event)" />
|
|
3208
|
+
`, imports: [FilterDropdownButtonComponent] }]
|
|
3209
|
+
}] });
|
|
3210
|
+
|
|
3074
3211
|
const AUTO_MINIFIED_STATE_WIDTH_BREAKPOINT = 1280;
|
|
3075
3212
|
const EXPAND_ANIMATION_TIMINGS = '250ms cubic-bezier(.4, 0, .3, 1)';
|
|
3076
3213
|
const EXPANDED_STATE_WIDTH = '224px';
|
|
@@ -3262,7 +3399,7 @@ class NavSelectorComponent {
|
|
|
3262
3399
|
}
|
|
3263
3400
|
}
|
|
3264
3401
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NavSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3265
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NavSelectorComponent, isStandalone: true, selector: "ap-nav-selector", inputs: { navSelectorEntries: { classPropertyName: "navSelectorEntries", publicName: "navSelectorEntries", isSignal: true, isRequired: true, transformFunction: null }, translatedTexts: { classPropertyName: "translatedTexts", publicName: "translatedTexts", isSignal: true, isRequired: true, transformFunction: null }, multipleModeEnabled: { classPropertyName: "multipleModeEnabled", publicName: "multipleModeEnabled", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, detailsDisplayedLimit: { classPropertyName: "detailsDisplayedLimit", publicName: "detailsDisplayedLimit", isSignal: true, isRequired: false, transformFunction: null }, embedded: { classPropertyName: "embedded", publicName: "embedded", isSignal: true, isRequired: false, transformFunction: null }, forceExpanded: { classPropertyName: "forceExpanded", publicName: "forceExpanded", isSignal: true, isRequired: false, transformFunction: null }, expandedStateLocalStorageKey: { classPropertyName: "expandedStateLocalStorageKey", publicName: "expandedStateLocalStorageKey", isSignal: true, isRequired: false, transformFunction: null }, selectedEntryUids: { classPropertyName: "selectedEntryUids", publicName: "selectedEntryUids", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectedEntryUids: "selectedEntryUidsChange", actionClicked: "actionClicked", emptyStateActionClicked: "emptyStateActionClicked", onExpansionStateChange: "onExpansionStateChange", visibleAccountsChange: "visibleAccountsChange" }, host: { attributes: { "role": "tree" }, listeners: { "keydown.arrowDown": "onArrowDown($event)", "keydown.arrowUp": "onArrowUp($event)", "window:resize": "onWindowResize()" }, properties: { "class.minified": "!navSelectorState.expanded()", "class.embedded": "embedded()", "@expand": "expansionState()" } }, providers: [NavSelectorState, withSymbols(apArrowExpand, apArrowReduce, apSearch)], queries: [{ propertyName: "headerProjection", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "contentHeaderProjection", first: true, predicate: ["contentHeader"], descendants: true, isSignal: true }, { propertyName: "footerProjection", first: true, predicate: ["footer"], descendants: true, isSignal: true }], ngImport: i0, template: "<nav [class.embedded]=\"embedded()\">\n @let headerProjectionNotNull = headerProjection();\n @let contentHeaderProjectionNotNull = contentHeaderProjection();\n @let footerProjectionNotNull = footerProjection();\n\n <div class=\"nav-selector__header\">\n @if (!embedded()) {\n @if (navSelectorState.expanded()) {\n <span class=\"h3\">{{ translatedTexts().title }}</span>\n }\n\n <button\n type=\"button\"\n class=\"expand-button\"\n [class.expanded]=\"navSelectorState.expanded()\"\n (click)=\"clickExpandButton()\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"navSelectorState.expanded() ? 'arrow-reduce' : 'arrow-expand'\" />\n </button>\n }\n\n @if (headerProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"headerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n\n @if (navSelectorState.expanded()) {\n <ap-input-search\n [id]=\"componentUid + '_search'\"\n [placeholder]=\"translatedTexts().searchPlaceholder\"\n [ngModel]=\"navSelectorState.search()\"\n (ngModelChange)=\"navSelectorState.search.set($event ?? '')\" />\n } @else {\n <ap-icon-button\n type=\"stroked\"\n role=\"search\"\n (onClick)=\"onMinifiedSearchClicked()\">\n <ap-symbol symbolId=\"search\" />\n </ap-icon-button>\n }\n\n @if (contentHeaderProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"contentHeaderProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n </div>\n\n <div\n class=\"nav-selector__content\"\n role=\"tree\"\n [attr.aria-multiselectable]=\"navSelectorState.isMultipleModeEnabled()\">\n @for (entry of navSelectorState.entries(); track entry.uid) {\n @if (!entry.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"entry.type === 'GROUP' || entry.type === 'CATEGORY'\">\n @if (entry.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'CATEGORY') {\n <ap-nav-selector-category\n [category]=\"$any(entry)\"\n (actionClicked)=\"actionClicked.emit($event)\"\n (emptyStateActionClicked)=\"emptyStateActionClicked.emit($event)\"/>\n }\n </div>\n }\n }\n @if (navSelectorState.expanded() && navSelectorState.noResults()) {\n <div class=\"no-result\">{{ translatedTexts().noResults }}</div>\n }\n </div>\n\n @if (displayFooter() && footerProjectionNotNull) {\n <div class=\"nav-selector__footer\">\n <ng-container\n [ngTemplateOutlet]=\"footerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n </div>\n }\n</nav>\n", styles: [":host,nav{width:224px}@media only screen and (min-width:1400px){:host:not(.embedded),nav:not(.embedded){width:250px}:host:not(.embedded) .nav-selector__content,nav:not(.embedded) .nav-selector__content{width:250px}}:host{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;flex-grow:1}:host :hover .expand-button.expanded{animation-name:translateExpandButton}:host nav{display:flex;height:100%;flex-grow:1;flex-direction:column;align-items:flex-start;flex-shrink:0;overflow:hidden;background:var(--ref-color-white);transition:width .25s cubic-bezier(.4,0,.3,1)}:host nav:not(.embedded){border-right:1px solid var(--ref-color-grey-10)}:host .nav-selector__header{position:relative;display:flex;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;white-space:nowrap;border-bottom:1px solid var(--ref-color-grey-10);background:var(--ref-color-white)}:host .nav-selector__header .h3{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--sys-text-style-h3-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}:host .nav-selector__header .expand-button-container{position:absolute;right:0;top:var(--ref-spacing-xs)}:host .nav-selector__header ap-input-search{width:100%}@keyframes translateHideButton{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes translateExpandButton{0%{transform:translate(100%)}to{transform:translate(0)}}:host .nav-selector__header .expand-button{animation-duration:70ms;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:forwards;animation-name:translateHideButton}:host .nav-selector__header .expand-button.expanded{position:absolute;right:0;top:12px;transform:translate(100%)}:host .nav-selector__header .expand-button{display:flex;width:24px;height:24px;justify-content:center;align-items:center;background:var(--ref-color-grey-bg);border-top:1px solid var(--ref-color-grey-20);border-right:none;border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);border-top-left-radius:var(--ref-border-radius-sm);border-bottom-left-radius:var(--ref-border-radius-sm);cursor:pointer}:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-reduce],:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-expand]{color:var(--ref-color-grey-80)}:host .nav-selector__header .expand-button:focus-visible.expanded{animation-name:translateExpandButton}:host .nav-selector__header .expand-button:focus-visible{border-radius:var(--ref-border-radius-sm) 0px 0px var(--ref-border-radius-sm);border-top:1px solid var(--ref-color-grey-20);border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-10);box-shadow:0 0 0 1px #fff,0 0 0 3px #178dfe}:host .nav-selector__header .expand-button:hover{background-color:var(--ref-color-grey-10)}:host .nav-selector__header .expand-button:active{background-color:var(--ref-color-grey-20)}:host .nav-selector__content{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;width:224px;overflow-y:auto;overflow-x:hidden;transition:width .25s cubic-bezier(.4,0,.3,1)}:host .nav-selector__content .entry{align-self:stretch;display:flex;flex-direction:column}:host .nav-selector__content .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .nav-selector__content .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):first-child{padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):last-child{padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host .nav-selector__content .no-result{display:flex;padding:var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:italic;font-weight:400;line-height:var(--ref-font-line-height-sm)}:host .nav-selector__footer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;border-top:1px solid var(--sys-border-color-default);background:var(--ref-color-white)}:host.minified{width:64px}:host.minified nav{width:64px}:host.minified nav .nav-selector__header{align-items:center}:host.minified nav .nav-selector__header .expand-button{animation-name:none;border-radius:var(--ref-border-radius-sm);border:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-bg)}:host.minified nav .nav-selector__content{width:64px}:host.minified nav .nav-selector__content .entry{padding:var(--ref-spacing-xxxs)}\n"], dependencies: [{ kind: "component", type: NavSelectorLeafComponent, selector: "ap-nav-selector-leaf", inputs: ["leaf"], outputs: ["actionClicked"] }, { kind: "component", type: NavSelectorGroupComponent, selector: "ap-nav-selector-group", inputs: ["group"], outputs: ["actionClicked"] }, { kind: "component", type: NavSelectorCategoryComponent, selector: "ap-nav-selector-category", inputs: ["category"], outputs: ["emptyStateActionClicked", "actionClicked"] }, { kind: "component", type: InputSearchComponent, selector: "ap-input-search", inputs: ["id", "placeholder", "clearable"], outputs: ["focus", "blur", "keyup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "component", type: IconButtonComponent, selector: "ap-icon-button", inputs: ["ariaLabel", "name", "color", "disabled", "menuTrigger", "symbolId", "locked", "loading", "type"], outputs: ["onClick", "onFocus", "onBlur", "menuOpened", "menuClosed"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
|
|
3402
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NavSelectorComponent, isStandalone: true, selector: "ap-nav-selector", inputs: { navSelectorEntries: { classPropertyName: "navSelectorEntries", publicName: "navSelectorEntries", isSignal: true, isRequired: true, transformFunction: null }, translatedTexts: { classPropertyName: "translatedTexts", publicName: "translatedTexts", isSignal: true, isRequired: true, transformFunction: null }, multipleModeEnabled: { classPropertyName: "multipleModeEnabled", publicName: "multipleModeEnabled", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, detailsDisplayedLimit: { classPropertyName: "detailsDisplayedLimit", publicName: "detailsDisplayedLimit", isSignal: true, isRequired: false, transformFunction: null }, embedded: { classPropertyName: "embedded", publicName: "embedded", isSignal: true, isRequired: false, transformFunction: null }, forceExpanded: { classPropertyName: "forceExpanded", publicName: "forceExpanded", isSignal: true, isRequired: false, transformFunction: null }, expandedStateLocalStorageKey: { classPropertyName: "expandedStateLocalStorageKey", publicName: "expandedStateLocalStorageKey", isSignal: true, isRequired: false, transformFunction: null }, selectedEntryUids: { classPropertyName: "selectedEntryUids", publicName: "selectedEntryUids", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectedEntryUids: "selectedEntryUidsChange", actionClicked: "actionClicked", emptyStateActionClicked: "emptyStateActionClicked", onExpansionStateChange: "onExpansionStateChange", visibleAccountsChange: "visibleAccountsChange" }, host: { attributes: { "role": "tree" }, listeners: { "keydown.arrowDown": "onArrowDown($event)", "keydown.arrowUp": "onArrowUp($event)", "window:resize": "onWindowResize()" }, properties: { "class.minified": "!navSelectorState.expanded()", "class.embedded": "embedded()", "@expand": "expansionState()" } }, providers: [NavSelectorState, withSymbols(apArrowExpand, apArrowReduce, apSearch)], queries: [{ propertyName: "headerProjection", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "contentHeaderProjection", first: true, predicate: ["contentHeader"], descendants: true, isSignal: true }, { propertyName: "footerProjection", first: true, predicate: ["footer"], descendants: true, isSignal: true }], ngImport: i0, template: "<nav [class.embedded]=\"embedded()\">\n @let headerProjectionNotNull = headerProjection();\n @let contentHeaderProjectionNotNull = contentHeaderProjection();\n @let footerProjectionNotNull = footerProjection();\n\n <div class=\"nav-selector__header\">\n @if (!embedded()) {\n @if (navSelectorState.expanded()) {\n <span class=\"h3\">{{ translatedTexts().title }}</span>\n }\n\n <button\n type=\"button\"\n class=\"expand-button\"\n [class.expanded]=\"navSelectorState.expanded()\"\n (click)=\"clickExpandButton()\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"navSelectorState.expanded() ? 'arrow-reduce' : 'arrow-expand'\" />\n </button>\n }\n\n @if (headerProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"headerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n\n @if (navSelectorState.expanded()) {\n <ap-input-search\n [id]=\"componentUid + '_search'\"\n [placeholder]=\"translatedTexts().searchPlaceholder\"\n [ngModel]=\"navSelectorState.search()\"\n (ngModelChange)=\"navSelectorState.search.set($event ?? '')\" />\n\n @if (navSelectorState.tagsFilterDisplayed()) {\n <ap-nav-selector-tags-filter />\n }\n } @else {\n <ap-icon-button\n type=\"stroked\"\n role=\"search\"\n (onClick)=\"onMinifiedSearchClicked()\">\n <ap-symbol symbolId=\"search\" />\n </ap-icon-button>\n }\n\n @if (contentHeaderProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"contentHeaderProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n </div>\n\n <div\n class=\"nav-selector__content\"\n role=\"tree\"\n [attr.aria-multiselectable]=\"navSelectorState.isMultipleModeEnabled()\">\n @for (entry of navSelectorState.entries(); track entry.uid) {\n @if (!entry.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"entry.type === 'GROUP' || entry.type === 'CATEGORY'\">\n @if (entry.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'CATEGORY') {\n <ap-nav-selector-category\n [category]=\"$any(entry)\"\n (actionClicked)=\"actionClicked.emit($event)\"\n (emptyStateActionClicked)=\"emptyStateActionClicked.emit($event)\" />\n }\n </div>\n }\n }\n @if (navSelectorState.expanded() && navSelectorState.noResults()) {\n <div class=\"no-result\">{{ translatedTexts().noResults }}</div>\n }\n </div>\n\n @if (displayFooter() && footerProjectionNotNull) {\n <div class=\"nav-selector__footer\">\n <ng-container\n [ngTemplateOutlet]=\"footerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n </div>\n }\n</nav>\n", styles: [":host,nav{width:224px}@media only screen and (min-width:1400px){:host:not(.embedded),nav:not(.embedded){width:250px}:host:not(.embedded) .nav-selector__content,nav:not(.embedded) .nav-selector__content{width:250px}}:host{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;flex-grow:1}:host :hover .expand-button.expanded{animation-name:translateExpandButton}:host nav{display:flex;height:100%;flex-grow:1;flex-direction:column;align-items:flex-start;flex-shrink:0;overflow:hidden;background:var(--ref-color-white);transition:width .25s cubic-bezier(.4,0,.3,1)}:host nav:not(.embedded){border-right:1px solid var(--ref-color-grey-10)}:host .nav-selector__header{position:relative;display:flex;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;white-space:nowrap;border-bottom:1px solid var(--ref-color-grey-10);background:var(--ref-color-white)}:host .nav-selector__header .h3{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--sys-text-style-h3-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}:host .nav-selector__header .expand-button-container{position:absolute;right:0;top:var(--ref-spacing-xs)}:host .nav-selector__header ap-input-search{width:100%}@keyframes translateHideButton{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes translateExpandButton{0%{transform:translate(100%)}to{transform:translate(0)}}:host .nav-selector__header .expand-button{animation-duration:70ms;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:forwards;animation-name:translateHideButton}:host .nav-selector__header .expand-button.expanded{position:absolute;right:0;top:12px;transform:translate(100%)}:host .nav-selector__header .expand-button{display:flex;width:24px;height:24px;justify-content:center;align-items:center;background:var(--ref-color-grey-bg);border-top:1px solid var(--ref-color-grey-20);border-right:none;border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);border-top-left-radius:var(--ref-border-radius-sm);border-bottom-left-radius:var(--ref-border-radius-sm);cursor:pointer}:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-reduce],:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-expand]{color:var(--ref-color-grey-80)}:host .nav-selector__header .expand-button:focus-visible.expanded{animation-name:translateExpandButton}:host .nav-selector__header .expand-button:focus-visible{border-radius:var(--ref-border-radius-sm) 0px 0px var(--ref-border-radius-sm);border-top:1px solid var(--ref-color-grey-20);border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-10);box-shadow:0 0 0 1px #fff,0 0 0 3px #178dfe}:host .nav-selector__header .expand-button:hover{background-color:var(--ref-color-grey-10)}:host .nav-selector__header .expand-button:active{background-color:var(--ref-color-grey-20)}:host .nav-selector__content{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;width:224px;overflow-y:auto;overflow-x:hidden;transition:width .25s cubic-bezier(.4,0,.3,1)}:host .nav-selector__content .entry{align-self:stretch;display:flex;flex-direction:column}:host .nav-selector__content .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .nav-selector__content .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):first-child{padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):last-child{padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host .nav-selector__content .no-result{display:flex;padding:var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:italic;font-weight:400;line-height:var(--ref-font-line-height-sm)}:host .nav-selector__footer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;border-top:1px solid var(--sys-border-color-default);background:var(--ref-color-white)}:host.minified{width:64px}:host.minified nav{width:64px}:host.minified nav .nav-selector__header{align-items:center}:host.minified nav .nav-selector__header .expand-button{animation-name:none;border-radius:var(--ref-border-radius-sm);border:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-bg)}:host.minified nav .nav-selector__content{width:64px}:host.minified nav .nav-selector__content .entry{padding:var(--ref-spacing-xxxs)}\n"], dependencies: [{ kind: "component", type: NavSelectorLeafComponent, selector: "ap-nav-selector-leaf", inputs: ["leaf"], outputs: ["actionClicked"] }, { kind: "component", type: NavSelectorGroupComponent, selector: "ap-nav-selector-group", inputs: ["group"], outputs: ["actionClicked"] }, { kind: "component", type: NavSelectorCategoryComponent, selector: "ap-nav-selector-category", inputs: ["category"], outputs: ["emptyStateActionClicked", "actionClicked"] }, { kind: "component", type: InputSearchComponent, selector: "ap-input-search", inputs: ["id", "placeholder", "clearable"], outputs: ["focus", "blur", "keyup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "component", type: IconButtonComponent, selector: "ap-icon-button", inputs: ["ariaLabel", "name", "color", "disabled", "menuTrigger", "symbolId", "locked", "loading", "type"], outputs: ["onClick", "onFocus", "onBlur", "menuOpened", "menuClosed"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NavSelectorTagsFilterComponent, selector: "ap-nav-selector-tags-filter" }], animations: [
|
|
3266
3403
|
trigger('expand', [
|
|
3267
3404
|
transition('expanded => minified', animate(EXPAND_ANIMATION_TIMINGS, keyframes([style({ width: EXPANDED_STATE_WIDTH }), style({ width: '100px' }), style({ width: MINIFIED_STATE_WIDTH })]))),
|
|
3268
3405
|
transition('minified => expanded', animate(EXPAND_ANIMATION_TIMINGS, keyframes([style({ width: MINIFIED_STATE_WIDTH }), style({ width: '50%' }), style({ width: '100%' })]))),
|
|
@@ -3280,6 +3417,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
3280
3417
|
SymbolComponent,
|
|
3281
3418
|
IconButtonComponent,
|
|
3282
3419
|
NgTemplateOutlet,
|
|
3420
|
+
NavSelectorTagsFilterComponent,
|
|
3283
3421
|
], providers: [NavSelectorState, withSymbols(apArrowExpand, apArrowReduce, apSearch)], host: {
|
|
3284
3422
|
'[class.minified]': '!navSelectorState.expanded()',
|
|
3285
3423
|
'[class.embedded]': 'embedded()',
|
|
@@ -3293,7 +3431,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
3293
3431
|
transition('expanded => minified', animate(EXPAND_ANIMATION_TIMINGS, keyframes([style({ width: EXPANDED_STATE_WIDTH }), style({ width: '100px' }), style({ width: MINIFIED_STATE_WIDTH })]))),
|
|
3294
3432
|
transition('minified => expanded', animate(EXPAND_ANIMATION_TIMINGS, keyframes([style({ width: MINIFIED_STATE_WIDTH }), style({ width: '50%' }), style({ width: '100%' })]))),
|
|
3295
3433
|
]),
|
|
3296
|
-
], template: "<nav [class.embedded]=\"embedded()\">\n @let headerProjectionNotNull = headerProjection();\n @let contentHeaderProjectionNotNull = contentHeaderProjection();\n @let footerProjectionNotNull = footerProjection();\n\n <div class=\"nav-selector__header\">\n @if (!embedded()) {\n @if (navSelectorState.expanded()) {\n <span class=\"h3\">{{ translatedTexts().title }}</span>\n }\n\n <button\n type=\"button\"\n class=\"expand-button\"\n [class.expanded]=\"navSelectorState.expanded()\"\n (click)=\"clickExpandButton()\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"navSelectorState.expanded() ? 'arrow-reduce' : 'arrow-expand'\" />\n </button>\n }\n\n @if (headerProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"headerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n\n @if (navSelectorState.expanded()) {\n <ap-input-search\n [id]=\"componentUid + '_search'\"\n [placeholder]=\"translatedTexts().searchPlaceholder\"\n [ngModel]=\"navSelectorState.search()\"\n (ngModelChange)=\"navSelectorState.search.set($event ?? '')\" />\n } @else {\n <ap-icon-button\n type=\"stroked\"\n role=\"search\"\n (onClick)=\"onMinifiedSearchClicked()\">\n <ap-symbol symbolId=\"search\" />\n </ap-icon-button>\n }\n\n @if (contentHeaderProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"contentHeaderProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n </div>\n\n <div\n class=\"nav-selector__content\"\n role=\"tree\"\n [attr.aria-multiselectable]=\"navSelectorState.isMultipleModeEnabled()\">\n @for (entry of navSelectorState.entries(); track entry.uid) {\n @if (!entry.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"entry.type === 'GROUP' || entry.type === 'CATEGORY'\">\n @if (entry.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'CATEGORY') {\n <ap-nav-selector-category\n [category]=\"$any(entry)\"\n (actionClicked)=\"actionClicked.emit($event)\"\n (emptyStateActionClicked)=\"emptyStateActionClicked.emit($event)\"/>\n }\n </div>\n }\n }\n @if (navSelectorState.expanded() && navSelectorState.noResults()) {\n <div class=\"no-result\">{{ translatedTexts().noResults }}</div>\n }\n </div>\n\n @if (displayFooter() && footerProjectionNotNull) {\n <div class=\"nav-selector__footer\">\n <ng-container\n [ngTemplateOutlet]=\"footerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n </div>\n }\n</nav>\n", styles: [":host,nav{width:224px}@media only screen and (min-width:1400px){:host:not(.embedded),nav:not(.embedded){width:250px}:host:not(.embedded) .nav-selector__content,nav:not(.embedded) .nav-selector__content{width:250px}}:host{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;flex-grow:1}:host :hover .expand-button.expanded{animation-name:translateExpandButton}:host nav{display:flex;height:100%;flex-grow:1;flex-direction:column;align-items:flex-start;flex-shrink:0;overflow:hidden;background:var(--ref-color-white);transition:width .25s cubic-bezier(.4,0,.3,1)}:host nav:not(.embedded){border-right:1px solid var(--ref-color-grey-10)}:host .nav-selector__header{position:relative;display:flex;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;white-space:nowrap;border-bottom:1px solid var(--ref-color-grey-10);background:var(--ref-color-white)}:host .nav-selector__header .h3{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--sys-text-style-h3-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}:host .nav-selector__header .expand-button-container{position:absolute;right:0;top:var(--ref-spacing-xs)}:host .nav-selector__header ap-input-search{width:100%}@keyframes translateHideButton{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes translateExpandButton{0%{transform:translate(100%)}to{transform:translate(0)}}:host .nav-selector__header .expand-button{animation-duration:70ms;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:forwards;animation-name:translateHideButton}:host .nav-selector__header .expand-button.expanded{position:absolute;right:0;top:12px;transform:translate(100%)}:host .nav-selector__header .expand-button{display:flex;width:24px;height:24px;justify-content:center;align-items:center;background:var(--ref-color-grey-bg);border-top:1px solid var(--ref-color-grey-20);border-right:none;border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);border-top-left-radius:var(--ref-border-radius-sm);border-bottom-left-radius:var(--ref-border-radius-sm);cursor:pointer}:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-reduce],:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-expand]{color:var(--ref-color-grey-80)}:host .nav-selector__header .expand-button:focus-visible.expanded{animation-name:translateExpandButton}:host .nav-selector__header .expand-button:focus-visible{border-radius:var(--ref-border-radius-sm) 0px 0px var(--ref-border-radius-sm);border-top:1px solid var(--ref-color-grey-20);border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-10);box-shadow:0 0 0 1px #fff,0 0 0 3px #178dfe}:host .nav-selector__header .expand-button:hover{background-color:var(--ref-color-grey-10)}:host .nav-selector__header .expand-button:active{background-color:var(--ref-color-grey-20)}:host .nav-selector__content{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;width:224px;overflow-y:auto;overflow-x:hidden;transition:width .25s cubic-bezier(.4,0,.3,1)}:host .nav-selector__content .entry{align-self:stretch;display:flex;flex-direction:column}:host .nav-selector__content .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .nav-selector__content .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):first-child{padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):last-child{padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host .nav-selector__content .no-result{display:flex;padding:var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:italic;font-weight:400;line-height:var(--ref-font-line-height-sm)}:host .nav-selector__footer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;border-top:1px solid var(--sys-border-color-default);background:var(--ref-color-white)}:host.minified{width:64px}:host.minified nav{width:64px}:host.minified nav .nav-selector__header{align-items:center}:host.minified nav .nav-selector__header .expand-button{animation-name:none;border-radius:var(--ref-border-radius-sm);border:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-bg)}:host.minified nav .nav-selector__content{width:64px}:host.minified nav .nav-selector__content .entry{padding:var(--ref-spacing-xxxs)}\n"] }]
|
|
3434
|
+
], template: "<nav [class.embedded]=\"embedded()\">\n @let headerProjectionNotNull = headerProjection();\n @let contentHeaderProjectionNotNull = contentHeaderProjection();\n @let footerProjectionNotNull = footerProjection();\n\n <div class=\"nav-selector__header\">\n @if (!embedded()) {\n @if (navSelectorState.expanded()) {\n <span class=\"h3\">{{ translatedTexts().title }}</span>\n }\n\n <button\n type=\"button\"\n class=\"expand-button\"\n [class.expanded]=\"navSelectorState.expanded()\"\n (click)=\"clickExpandButton()\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"navSelectorState.expanded() ? 'arrow-reduce' : 'arrow-expand'\" />\n </button>\n }\n\n @if (headerProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"headerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n\n @if (navSelectorState.expanded()) {\n <ap-input-search\n [id]=\"componentUid + '_search'\"\n [placeholder]=\"translatedTexts().searchPlaceholder\"\n [ngModel]=\"navSelectorState.search()\"\n (ngModelChange)=\"navSelectorState.search.set($event ?? '')\" />\n\n @if (navSelectorState.tagsFilterDisplayed()) {\n <ap-nav-selector-tags-filter />\n }\n } @else {\n <ap-icon-button\n type=\"stroked\"\n role=\"search\"\n (onClick)=\"onMinifiedSearchClicked()\">\n <ap-symbol symbolId=\"search\" />\n </ap-icon-button>\n }\n\n @if (contentHeaderProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"contentHeaderProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n </div>\n\n <div\n class=\"nav-selector__content\"\n role=\"tree\"\n [attr.aria-multiselectable]=\"navSelectorState.isMultipleModeEnabled()\">\n @for (entry of navSelectorState.entries(); track entry.uid) {\n @if (!entry.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"entry.type === 'GROUP' || entry.type === 'CATEGORY'\">\n @if (entry.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'CATEGORY') {\n <ap-nav-selector-category\n [category]=\"$any(entry)\"\n (actionClicked)=\"actionClicked.emit($event)\"\n (emptyStateActionClicked)=\"emptyStateActionClicked.emit($event)\" />\n }\n </div>\n }\n }\n @if (navSelectorState.expanded() && navSelectorState.noResults()) {\n <div class=\"no-result\">{{ translatedTexts().noResults }}</div>\n }\n </div>\n\n @if (displayFooter() && footerProjectionNotNull) {\n <div class=\"nav-selector__footer\">\n <ng-container\n [ngTemplateOutlet]=\"footerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n </div>\n }\n</nav>\n", styles: [":host,nav{width:224px}@media only screen and (min-width:1400px){:host:not(.embedded),nav:not(.embedded){width:250px}:host:not(.embedded) .nav-selector__content,nav:not(.embedded) .nav-selector__content{width:250px}}:host{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;flex-grow:1}:host :hover .expand-button.expanded{animation-name:translateExpandButton}:host nav{display:flex;height:100%;flex-grow:1;flex-direction:column;align-items:flex-start;flex-shrink:0;overflow:hidden;background:var(--ref-color-white);transition:width .25s cubic-bezier(.4,0,.3,1)}:host nav:not(.embedded){border-right:1px solid var(--ref-color-grey-10)}:host .nav-selector__header{position:relative;display:flex;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;white-space:nowrap;border-bottom:1px solid var(--ref-color-grey-10);background:var(--ref-color-white)}:host .nav-selector__header .h3{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--sys-text-style-h3-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}:host .nav-selector__header .expand-button-container{position:absolute;right:0;top:var(--ref-spacing-xs)}:host .nav-selector__header ap-input-search{width:100%}@keyframes translateHideButton{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes translateExpandButton{0%{transform:translate(100%)}to{transform:translate(0)}}:host .nav-selector__header .expand-button{animation-duration:70ms;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:forwards;animation-name:translateHideButton}:host .nav-selector__header .expand-button.expanded{position:absolute;right:0;top:12px;transform:translate(100%)}:host .nav-selector__header .expand-button{display:flex;width:24px;height:24px;justify-content:center;align-items:center;background:var(--ref-color-grey-bg);border-top:1px solid var(--ref-color-grey-20);border-right:none;border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);border-top-left-radius:var(--ref-border-radius-sm);border-bottom-left-radius:var(--ref-border-radius-sm);cursor:pointer}:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-reduce],:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-expand]{color:var(--ref-color-grey-80)}:host .nav-selector__header .expand-button:focus-visible.expanded{animation-name:translateExpandButton}:host .nav-selector__header .expand-button:focus-visible{border-radius:var(--ref-border-radius-sm) 0px 0px var(--ref-border-radius-sm);border-top:1px solid var(--ref-color-grey-20);border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-10);box-shadow:0 0 0 1px #fff,0 0 0 3px #178dfe}:host .nav-selector__header .expand-button:hover{background-color:var(--ref-color-grey-10)}:host .nav-selector__header .expand-button:active{background-color:var(--ref-color-grey-20)}:host .nav-selector__content{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;width:224px;overflow-y:auto;overflow-x:hidden;transition:width .25s cubic-bezier(.4,0,.3,1)}:host .nav-selector__content .entry{align-self:stretch;display:flex;flex-direction:column}:host .nav-selector__content .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .nav-selector__content .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):first-child{padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):last-child{padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host .nav-selector__content .no-result{display:flex;padding:var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:italic;font-weight:400;line-height:var(--ref-font-line-height-sm)}:host .nav-selector__footer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;border-top:1px solid var(--sys-border-color-default);background:var(--ref-color-white)}:host.minified{width:64px}:host.minified nav{width:64px}:host.minified nav .nav-selector__header{align-items:center}:host.minified nav .nav-selector__header .expand-button{animation-name:none;border-radius:var(--ref-border-radius-sm);border:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-bg)}:host.minified nav .nav-selector__content{width:64px}:host.minified nav .nav-selector__content .entry{padding:var(--ref-spacing-xxxs)}\n"] }]
|
|
3297
3435
|
}], ctorParameters: () => [], propDecorators: { navSelectorEntries: [{ type: i0.Input, args: [{ isSignal: true, alias: "navSelectorEntries", required: true }] }], translatedTexts: [{ type: i0.Input, args: [{ isSignal: true, alias: "translatedTexts", required: true }] }], multipleModeEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "multipleModeEnabled", required: false }] }], style: [{ type: i0.Input, args: [{ isSignal: true, alias: "style", required: false }] }], detailsDisplayedLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailsDisplayedLimit", required: false }] }], embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }], forceExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "forceExpanded", required: false }] }], expandedStateLocalStorageKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedStateLocalStorageKey", required: false }] }], selectedEntryUids: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedEntryUids", required: true }] }, { type: i0.Output, args: ["selectedEntryUidsChange"] }], actionClicked: [{ type: i0.Output, args: ["actionClicked"] }], emptyStateActionClicked: [{ type: i0.Output, args: ["emptyStateActionClicked"] }], headerProjection: [{ type: i0.ContentChild, args: ['header', { isSignal: true }] }], contentHeaderProjection: [{ type: i0.ContentChild, args: ['contentHeader', { isSignal: true }] }], footerProjection: [{ type: i0.ContentChild, args: ['footer', { isSignal: true }] }], onExpansionStateChange: [{ type: i0.Output, args: ["onExpansionStateChange"] }], visibleAccountsChange: [{ type: i0.Output, args: ["visibleAccountsChange"] }] } });
|
|
3298
3436
|
|
|
3299
3437
|
/**
|