@yuuvis/client-framework 3.1.0 → 3.2.0

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 (65) hide show
  1. package/fesm2022/yuuvis-client-framework-actions.mjs +214 -126
  2. package/fesm2022/yuuvis-client-framework-actions.mjs.map +1 -1
  3. package/fesm2022/yuuvis-client-framework-app-bar.mjs +3 -3
  4. package/fesm2022/yuuvis-client-framework-app-bar.mjs.map +1 -1
  5. package/fesm2022/yuuvis-client-framework-badges.mjs +379 -0
  6. package/fesm2022/yuuvis-client-framework-badges.mjs.map +1 -0
  7. package/fesm2022/yuuvis-client-framework-breadcrumb.mjs +3 -3
  8. package/fesm2022/yuuvis-client-framework-breadcrumb.mjs.map +1 -1
  9. package/fesm2022/yuuvis-client-framework-clipboard.mjs +8 -8
  10. package/fesm2022/yuuvis-client-framework-clipboard.mjs.map +1 -1
  11. package/fesm2022/yuuvis-client-framework-datepicker.mjs +31 -31
  12. package/fesm2022/yuuvis-client-framework-datepicker.mjs.map +1 -1
  13. package/fesm2022/yuuvis-client-framework-forms.mjs +65 -66
  14. package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
  15. package/fesm2022/yuuvis-client-framework-icons.mjs +9 -9
  16. package/fesm2022/yuuvis-client-framework-icons.mjs.map +1 -1
  17. package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs +7 -7
  18. package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs.map +1 -1
  19. package/fesm2022/yuuvis-client-framework-metadata-form.mjs +15 -15
  20. package/fesm2022/yuuvis-client-framework-metadata-form.mjs.map +1 -1
  21. package/fesm2022/yuuvis-client-framework-object-details.mjs +53 -46
  22. package/fesm2022/yuuvis-client-framework-object-details.mjs.map +1 -1
  23. package/fesm2022/yuuvis-client-framework-object-flavor.mjs +18 -18
  24. package/fesm2022/yuuvis-client-framework-object-flavor.mjs.map +1 -1
  25. package/fesm2022/yuuvis-client-framework-object-form.mjs +32 -32
  26. package/fesm2022/yuuvis-client-framework-object-form.mjs.map +1 -1
  27. package/fesm2022/yuuvis-client-framework-object-preview.mjs +9 -9
  28. package/fesm2022/yuuvis-client-framework-object-preview.mjs.map +1 -1
  29. package/fesm2022/yuuvis-client-framework-object-relationship.mjs +28 -28
  30. package/fesm2022/yuuvis-client-framework-object-relationship.mjs.map +1 -1
  31. package/fesm2022/yuuvis-client-framework-object-summary.mjs +14 -14
  32. package/fesm2022/yuuvis-client-framework-object-summary.mjs.map +1 -1
  33. package/fesm2022/yuuvis-client-framework-object-versions.mjs +18 -12
  34. package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
  35. package/fesm2022/yuuvis-client-framework-pagination.mjs +3 -3
  36. package/fesm2022/yuuvis-client-framework-pagination.mjs.map +1 -1
  37. package/fesm2022/yuuvis-client-framework-query-list.mjs +7 -7
  38. package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -1
  39. package/fesm2022/yuuvis-client-framework-renderer.mjs +39 -39
  40. package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -1
  41. package/fesm2022/yuuvis-client-framework-sequence-list.mjs +3 -3
  42. package/fesm2022/yuuvis-client-framework-sequence-list.mjs.map +1 -1
  43. package/fesm2022/yuuvis-client-framework-simple-search.mjs +3 -3
  44. package/fesm2022/yuuvis-client-framework-simple-search.mjs.map +1 -1
  45. package/fesm2022/yuuvis-client-framework-sort.mjs +3 -3
  46. package/fesm2022/yuuvis-client-framework-sort.mjs.map +1 -1
  47. package/fesm2022/yuuvis-client-framework-tile-list.mjs +163 -125
  48. package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
  49. package/fesm2022/yuuvis-client-framework-token-search.mjs +7 -7
  50. package/fesm2022/yuuvis-client-framework-token-search.mjs.map +1 -1
  51. package/fesm2022/yuuvis-client-framework-tree.mjs +9 -9
  52. package/fesm2022/yuuvis-client-framework-tree.mjs.map +1 -1
  53. package/fesm2022/yuuvis-client-framework-upload-progress.mjs +10 -10
  54. package/fesm2022/yuuvis-client-framework-upload-progress.mjs.map +1 -1
  55. package/fesm2022/yuuvis-client-framework.mjs +96 -51
  56. package/fesm2022/yuuvis-client-framework.mjs.map +1 -1
  57. package/lib/assets/i18n/de.json +12 -1
  58. package/lib/assets/i18n/en.json +12 -1
  59. package/package.json +9 -5
  60. package/types/yuuvis-client-framework-actions.d.ts +91 -52
  61. package/types/yuuvis-client-framework-badges.d.ts +194 -0
  62. package/types/yuuvis-client-framework-object-details.d.ts +5 -5
  63. package/types/yuuvis-client-framework-object-versions.d.ts +1 -0
  64. package/types/yuuvis-client-framework-tile-list.d.ts +10 -6
  65. package/types/yuuvis-client-framework.d.ts +13 -0
@@ -0,0 +1,379 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, input, computed, Component, signal, Injectable, output } from '@angular/core';
3
+ import * as i1 from '@angular/material/icon';
4
+ import { MatIconModule } from '@angular/material/icon';
5
+ import * as i2 from '@angular/material/tooltip';
6
+ import { MatTooltipModule } from '@angular/material/tooltip';
7
+ import * as i2$1 from '@yuuvis/client-core';
8
+ import { TranslateService, TranslatePipe, BaseObjectTypeField, SystemSOT, RetentionField, YUV_USER, ObjectLockingService, TranslateModule } from '@yuuvis/client-core';
9
+ import { YmtBadge } from '@yuuvis/material/badge';
10
+ import { NgClass } from '@angular/common';
11
+ import { _ } from '@ngx-translate/core';
12
+
13
+ class BadgeChipComponent {
14
+ constructor() {
15
+ this.#translate = inject(TranslateService);
16
+ this.badge = input.required(...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
17
+ this.showLabel = input(false, ...(ngDevMode ? [{ debugName: "showLabel" }] : /* istanbul ignore next */ []));
18
+ this.tooltip = computed(() => {
19
+ const current = this.badge();
20
+ return this.#translate.instant(current.descriptionKey ?? current.labelKey);
21
+ }, ...(ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []));
22
+ }
23
+ #translate;
24
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: BadgeChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
25
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: BadgeChipComponent, isStandalone: true, selector: "yuv-badge-chip", inputs: { badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: true, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let b = badge();\n\n<ymt-badge [severity]=\"b.severity ?? 'neutral'\" [matTooltip]=\"tooltip()\" class=\"badge-chip\">\n @if (b.svgIcon) {\n <mat-icon [svgIcon]=\"b.icon\" inert=\"true\" />\n } @else {\n <mat-icon inert=\"true\">{{ b.icon }}</mat-icon>\n }\n @if (showLabel()) {\n <span>{{ b.labelKey | translate }}</span>\n }\n</ymt-badge>\n", styles: [":host{display:flex}:host .badge-chip{gap:var(--ymt-spacing-xs);align-items:center;justify-content:center;padding:var(--ymt-spacing-xs);height:var(--ymt-spacing-xl)}:host .badge-chip mat-icon{width:var(--ymt-spacing-l);height:var(--ymt-spacing-m);font-size:var(--ymt-font-title-medium-size);line-height:var(--ymt-spacing-m)}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
26
+ }
27
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: BadgeChipComponent, decorators: [{
28
+ type: Component,
29
+ args: [{ selector: 'yuv-badge-chip', imports: [MatIconModule, MatTooltipModule, YmtBadge, TranslatePipe], template: "@let b = badge();\n\n<ymt-badge [severity]=\"b.severity ?? 'neutral'\" [matTooltip]=\"tooltip()\" class=\"badge-chip\">\n @if (b.svgIcon) {\n <mat-icon [svgIcon]=\"b.icon\" inert=\"true\" />\n } @else {\n <mat-icon inert=\"true\">{{ b.icon }}</mat-icon>\n }\n @if (showLabel()) {\n <span>{{ b.labelKey | translate }}</span>\n }\n</ymt-badge>\n", styles: [":host{display:flex}:host .badge-chip{gap:var(--ymt-spacing-xs);align-items:center;justify-content:center;padding:var(--ymt-spacing-xs);height:var(--ymt-spacing-xl)}:host .badge-chip mat-icon{width:var(--ymt-spacing-l);height:var(--ymt-spacing-m);font-size:var(--ymt-font-title-medium-size);line-height:var(--ymt-spacing-m)}\n"] }]
30
+ }], propDecorators: { badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: true }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }] } });
31
+
32
+ /**
33
+ * Badge shown when an object is locked by another user.
34
+ */
35
+ const LOCK_BADGE = {
36
+ id: 'yuv.badge.lock',
37
+ labelKey: _('yuv.badge.lock.label'),
38
+ descriptionKey: _('yuv.badge.lock.description'),
39
+ icon: 'lock',
40
+ severity: 'warning',
41
+ priority: 10,
42
+ /**
43
+ * Applies if a lock tag exists and the current user is not the lock owner.
44
+ */
45
+ applies: (_dmsObject, ctx) => !!ctx.lockState?.locked && !ctx.lockState.lockedByCurrentUser
46
+ };
47
+ /**
48
+ * Badge shown when an object is locked by the current user.
49
+ */
50
+ const LOCK_SELF_BADGE = {
51
+ id: 'yuv.badge.lock.self',
52
+ labelKey: _('yuv.badge.lock.self.label'),
53
+ descriptionKey: _('yuv.badge.lock.self.description'),
54
+ icon: 'lock_person',
55
+ severity: 'primary',
56
+ priority: 10,
57
+ variantOf: 'yuv.badge.lock',
58
+ /**
59
+ * Applies if a lock tag exists and the current user is the lock owner.
60
+ */
61
+ applies: (_dmsObject, ctx) => !!ctx.lockState?.locked && ctx.lockState.lockedByCurrentUser
62
+ };
63
+
64
+ /**
65
+ * Badge definition for DMS objects that are subject to a destruction retention policy.
66
+ *
67
+ * This badge is displayed when a DMS object has the `DESTRUCTION_RETENTION` secondary object type
68
+ * assigned and an active or ongoing retention period. It helps users identify objects that are
69
+ * legally or organizationally protected from deletion during their retention period.
70
+ *
71
+ * **Applies when:**
72
+ * - The object includes the `SystemSOT.DESTRUCTION_RETENTION` secondary object type.
73
+ * - A retention start date (`RetentionField.RETENTION_START`) is present.
74
+ * - The retention period has started (start date is in the past), or an end date is set and
75
+ * still lies in the future.
76
+ *
77
+ * @remarks
78
+ * - `severity` is set to `'danger'` to visually emphasize the retention constraint.
79
+ * - `priority` is `20`, which controls the display order relative to other badges.
80
+ */ const RETENTION_BADGE = {
81
+ id: 'yuv.badge.retention',
82
+ labelKey: _('yuv.badge.retention.label'),
83
+ descriptionKey: _('yuv.badge.retention.description'),
84
+ icon: 'gavel',
85
+ severity: 'danger',
86
+ priority: 20,
87
+ applies: (dmsObject) => {
88
+ const sots = dmsObject.data[BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS];
89
+ if (!sots?.includes(SystemSOT.DESTRUCTION_RETENTION))
90
+ return false;
91
+ const startRetention = dmsObject.data[RetentionField.RETENTION_START];
92
+ if (!startRetention)
93
+ return false;
94
+ const now = new Date();
95
+ const start = new Date(startRetention);
96
+ const endRetention = dmsObject.data[RetentionField.RETENTION_END];
97
+ const end = endRetention ? new Date(endRetention) : null;
98
+ return start < now || (end !== null && end > now);
99
+ }
100
+ };
101
+
102
+ /**
103
+ * Evaluates a single badge rule against a given DMS object.
104
+ *
105
+ * Supported operations:
106
+ * - `isSet`: returns `true` when the field value is not `undefined`, `null`, or an empty string.
107
+ * - `equals`: returns `true` when the field value strictly equals `rule.value`.
108
+ * - `tagPresent`: returns `true` when the configured tags field contains a tag whose first element equals `rule.value`.
109
+ *
110
+ * @param rule Badge rule definition to evaluate.
111
+ * @param dmsObject Source object containing field data.
112
+ * @returns `true` if the rule matches; otherwise `false`.
113
+ */
114
+ function evaluateRule(rule, dmsObject) {
115
+ switch (rule.op) {
116
+ case 'isSet': {
117
+ const value = dmsObject.data[rule.field];
118
+ return value !== undefined && value !== null && value !== '';
119
+ }
120
+ case 'equals': {
121
+ return dmsObject.data[rule.field] === rule.value;
122
+ }
123
+ case 'tagPresent': {
124
+ const tagsField = rule.field || BaseObjectTypeField.TAGS;
125
+ const tags = dmsObject.data[tagsField];
126
+ return !!tags?.some((tag) => Array.isArray(tag) && tag[0] === rule.value);
127
+ }
128
+ default:
129
+ return false;
130
+ }
131
+ }
132
+
133
+ class BadgeRegistryService {
134
+ #store = signal({ main: [], buckets: new Map() }, ...(ngDevMode ? [{ debugName: "#store" }] : /* istanbul ignore next */ []));
135
+ #currentUser = inject(YUV_USER, { optional: true }) ?? undefined;
136
+ #objectLocking = inject(ObjectLockingService);
137
+ /**
138
+ * Registers one or multiple badges in the registry.
139
+ *
140
+ * If a badge with the same id already exists in the same scope, it is replaced.
141
+ * Otherwise, the badge is added to the scope.
142
+ *
143
+ * @param badges An array of badges to register.
144
+ * @param bucket Optional bucket id (typically an APP_ID). If omitted, badges are
145
+ * registered globally and visible to every consumer. If provided,
146
+ * badges are scoped to that bucket and only visible when consumers
147
+ * query with the matching bucket.
148
+ *
149
+ * @see {@link Badge}
150
+ */
151
+ registerBadges(badges, bucket) {
152
+ this.#store.update((current) => {
153
+ const next = { main: current.main, buckets: new Map(current.buckets) };
154
+ if (bucket === undefined) {
155
+ next.main = this.#mergeInto(current.main, badges);
156
+ }
157
+ else {
158
+ const existing = current.buckets.get(bucket) ?? [];
159
+ next.buckets.set(bucket, this.#mergeInto(existing, badges));
160
+ }
161
+ return next;
162
+ });
163
+ }
164
+ /**
165
+ * Registers the default badges into the registry.
166
+ *
167
+ * Initializes three built-in badge types:
168
+ * - LOCK_BADGE: Indicates objects locked by other users
169
+ * - LOCK_SELF_BADGE: Indicates objects locked by the current user
170
+ * - RETENTION_BADGE: Indicates objects under retention hold
171
+ *
172
+ * @param bucket Optional bucket id. If omitted, defaults are registered globally.
173
+ *
174
+ * @see {@link Badge}
175
+ */
176
+ registerDefaultBadges(bucket) {
177
+ this.registerBadges([LOCK_BADGE, LOCK_SELF_BADGE, RETENTION_BADGE], bucket);
178
+ }
179
+ /**
180
+ * Unregisters one or multiple badges from the registry by id.
181
+ *
182
+ * Operates only on the specified scope: omitting `bucket` removes from the global
183
+ * scope only, providing `bucket` removes from that bucket only.
184
+ *
185
+ * @param id A single badge id or an array of badge ids to remove.
186
+ * @param bucket Optional bucket id.
187
+ */
188
+ unregister(id, bucket) {
189
+ const ids = Array.isArray(id) ? id : [id];
190
+ this.#store.update((current) => {
191
+ const next = { main: current.main, buckets: new Map(current.buckets) };
192
+ if (bucket === undefined) {
193
+ next.main = current.main.filter((badge) => !ids.includes(badge.id));
194
+ }
195
+ else {
196
+ const existing = current.buckets.get(bucket);
197
+ if (existing) {
198
+ next.buckets.set(bucket, existing.filter((badge) => !ids.includes(badge.id)));
199
+ }
200
+ }
201
+ return next;
202
+ });
203
+ }
204
+ /**
205
+ * Returns a registered badge by id.
206
+ *
207
+ * Looks first in the given bucket (if any), then in the global scope.
208
+ *
209
+ * @param id The badge id.
210
+ * @param bucket Optional bucket id.
211
+ * @returns The matching badge, or undefined if no badge is registered with that id.
212
+ */
213
+ get(id, bucket) {
214
+ const { main, buckets } = this.#store();
215
+ if (bucket !== undefined) {
216
+ const local = buckets.get(bucket)?.find((badge) => badge.id === id);
217
+ if (local)
218
+ return local;
219
+ }
220
+ return main.find((badge) => badge.id === id);
221
+ }
222
+ /**
223
+ * Returns all registered badges across the global scope and every bucket.
224
+ *
225
+ * Bucket entries override globals with the same id; remaining duplicates between
226
+ * buckets keep the first occurrence. Useful for tests and debug inspection.
227
+ */
228
+ all() {
229
+ const { main, buckets } = this.#store();
230
+ const byId = new Map();
231
+ for (const badge of main)
232
+ byId.set(badge.id, badge);
233
+ for (const list of buckets.values()) {
234
+ for (const badge of list)
235
+ byId.set(badge.id, badge);
236
+ }
237
+ return Array.from(byId.values());
238
+ }
239
+ /**
240
+ * Returns a reactive list of badges visible in the given scope.
241
+ *
242
+ * The returned signal recomputes whenever the registry changes. The list contains
243
+ * the global badges merged with the named bucket's badges (bucket entries override
244
+ * globals with the same id), sorted by ascending priority. At equal priority,
245
+ * globals come first, then bucket-local badges.
246
+ *
247
+ * @param bucket Optional bucket id.
248
+ */
249
+ getBadgesForBucket(bucket) {
250
+ return computed(() => this.#visibleScope(bucket).sort(this.#byPriority));
251
+ }
252
+ /**
253
+ * Resolves all active badges for a given object in the given scope.
254
+ *
255
+ * The visible scope is `main ∪ bucket`. Variants only resolve when their parent id
256
+ * is present in the visible scope. If `idFilter` is provided, only badges whose id
257
+ * (or whose variant's parent id) is in the filter are considered. The resulting
258
+ * list is sorted by ascending priority.
259
+ *
260
+ * @param dmsObject The object to evaluate badges against.
261
+ * @param options Optional bucket and id filter.
262
+ */
263
+ getActiveBadges(dmsObject, options) {
264
+ const visible = this.#visibleScope(options?.bucket);
265
+ const idFilter = options?.idFilter;
266
+ const filtered = visible.filter((badge) => {
267
+ if (badge.variantOf !== undefined) {
268
+ const parentVisible = visible.some((parent) => parent.id === badge.variantOf);
269
+ if (!parentVisible)
270
+ return false;
271
+ return idFilter ? idFilter.includes(badge.variantOf) : true;
272
+ }
273
+ return idFilter ? idFilter.includes(badge.id) : true;
274
+ });
275
+ return filtered.filter((badge) => this.#isActive(badge, dmsObject)).sort(this.#byPriority);
276
+ }
277
+ /**
278
+ * Returns globals merged with the named bucket. Bucket entries with the same id
279
+ * override globals (the bucket entry replaces the global entry in place, preserving
280
+ * the global's position). At equal priority, globals appear first.
281
+ */
282
+ #visibleScope(bucket) {
283
+ const { main, buckets } = this.#store();
284
+ if (bucket === undefined)
285
+ return [...main];
286
+ const local = buckets.get(bucket);
287
+ if (!local || local.length === 0)
288
+ return [...main];
289
+ const localById = new Map(local.map((badge) => [badge.id, badge]));
290
+ const merged = main.map((global) => localById.get(global.id) ?? global);
291
+ const additions = local.filter((badge) => !main.some((global) => global.id === badge.id));
292
+ return [...merged, ...additions];
293
+ }
294
+ #byPriority = (first, second) => (first.priority ?? 0) - (second.priority ?? 0);
295
+ /**
296
+ * Merges incoming badges into an existing list, replacing entries with the same id
297
+ * in place and appending new ones at the end.
298
+ */
299
+ #mergeInto(existing, incoming) {
300
+ const next = [...existing];
301
+ for (const badge of incoming) {
302
+ const idx = next.findIndex((current) => current.id === badge.id);
303
+ if (idx === -1)
304
+ next.push(badge);
305
+ else
306
+ next[idx] = badge;
307
+ }
308
+ return next;
309
+ }
310
+ /**
311
+ * Evaluates whether a badge applies to the given object.
312
+ *
313
+ * A custom {@link Badge.applies} function has precedence over rule evaluation.
314
+ * If neither applies nor rule is provided, the badge is considered inactive.
315
+ */
316
+ #isActive(badge, dmsObject) {
317
+ const ctx = {
318
+ currentUser: this.#currentUser,
319
+ lockState: this.#objectLocking.getLockState(dmsObject)
320
+ };
321
+ if (badge.applies)
322
+ return !!badge.applies(dmsObject, ctx);
323
+ if (badge.rule)
324
+ return evaluateRule(badge.rule, dmsObject);
325
+ return false;
326
+ }
327
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: BadgeRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
328
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: BadgeRegistryService, providedIn: 'root' }); }
329
+ }
330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: BadgeRegistryService, decorators: [{
331
+ type: Injectable,
332
+ args: [{ providedIn: 'root' }]
333
+ }] });
334
+
335
+ class BadgeSelectComponent {
336
+ constructor() {
337
+ this.#registry = inject(BadgeRegistryService);
338
+ this.selectedBadgeIds = input([], ...(ngDevMode ? [{ debugName: "selectedBadgeIds" }] : /* istanbul ignore next */ []));
339
+ this.bucket = input(...(ngDevMode ? [undefined, { debugName: "bucket" }] : /* istanbul ignore next */ []));
340
+ this.badgeSelect = output();
341
+ this.badges = computed(() => this.#registry
342
+ .getBadgesForBucket(this.bucket())()
343
+ .filter((badge) => badge.variantOf === undefined), ...(ngDevMode ? [{ debugName: "badges" }] : /* istanbul ignore next */ []));
344
+ }
345
+ #registry;
346
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: BadgeSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
347
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: BadgeSelectComponent, isStandalone: true, selector: "yuv-tile-badge-select", inputs: { selectedBadgeIds: { classPropertyName: "selectedBadgeIds", publicName: "selectedBadgeIds", isSignal: true, isRequired: false, transformFunction: null }, bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { badgeSelect: "badgeSelect" }, ngImport: i0, template: "<div class=\"badges\">\n @for (b of badges(); track b.id) {\n <button type=\"button\" [ngClass]=\"{ selected: selectedBadgeIds().includes(b.id) }\" (click)=\"badgeSelect.emit(b)\">\n @if (b.svgIcon) {\n <mat-icon [svgIcon]=\"b.icon\" inert=\"true\" />\n } @else {\n <mat-icon inert=\"true\">{{ b.icon }}</mat-icon>\n }\n <span>{{ b.labelKey | translate }}</span>\n </button>\n } @empty {\n <span class=\"empty\">\n {{ 'yuv.badge.empty.selection' | translate }}\n </span>\n }\n</div>\n", styles: [":host .badges{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-xs)}:host .badges button{border:0;display:inline-flex;gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);align-items:center;border-radius:var(--ymt-corner-s);background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container);cursor:pointer}:host .badges button.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }] }); }
348
+ }
349
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: BadgeSelectComponent, decorators: [{
350
+ type: Component,
351
+ args: [{ selector: 'yuv-tile-badge-select', imports: [NgClass, MatIconModule, TranslateModule], template: "<div class=\"badges\">\n @for (b of badges(); track b.id) {\n <button type=\"button\" [ngClass]=\"{ selected: selectedBadgeIds().includes(b.id) }\" (click)=\"badgeSelect.emit(b)\">\n @if (b.svgIcon) {\n <mat-icon [svgIcon]=\"b.icon\" inert=\"true\" />\n } @else {\n <mat-icon inert=\"true\">{{ b.icon }}</mat-icon>\n }\n <span>{{ b.labelKey | translate }}</span>\n </button>\n } @empty {\n <span class=\"empty\">\n {{ 'yuv.badge.empty.selection' | translate }}\n </span>\n }\n</div>\n", styles: [":host .badges{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-xs)}:host .badges button{border:0;display:inline-flex;gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);align-items:center;border-radius:var(--ymt-corner-s);background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container);cursor:pointer}:host .badges button.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}\n"] }]
352
+ }], propDecorators: { selectedBadgeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedBadgeIds", required: false }] }], bucket: [{ type: i0.Input, args: [{ isSignal: true, alias: "bucket", required: false }] }], badgeSelect: [{ type: i0.Output, args: ["badgeSelect"] }] } });
353
+
354
+ class TileBadgesComponent {
355
+ constructor() {
356
+ this.#registry = inject(BadgeRegistryService);
357
+ this.dmsObject = input.required(...(ngDevMode ? [{ debugName: "dmsObject" }] : /* istanbul ignore next */ []));
358
+ this.badgeIds = input(...(ngDevMode ? [undefined, { debugName: "badgeIds" }] : /* istanbul ignore next */ []));
359
+ this.bucket = input(...(ngDevMode ? [undefined, { debugName: "bucket" }] : /* istanbul ignore next */ []));
360
+ this.activeBadges = computed(() => this.#registry.getActiveBadges(this.dmsObject(), {
361
+ bucket: this.bucket(),
362
+ idFilter: this.badgeIds()
363
+ }), ...(ngDevMode ? [{ debugName: "activeBadges" }] : /* istanbul ignore next */ []));
364
+ }
365
+ #registry;
366
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TileBadgesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
367
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TileBadgesComponent, isStandalone: true, selector: "yuv-tile-badges", inputs: { dmsObject: { classPropertyName: "dmsObject", publicName: "dmsObject", isSignal: true, isRequired: true, transformFunction: null }, badgeIds: { classPropertyName: "badgeIds", publicName: "badgeIds", isSignal: true, isRequired: false, transformFunction: null }, bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@for (b of activeBadges(); track $index) {\n <yuv-badge-chip [badge]=\"b\" />\n}\n", styles: [":host{display:inline-flex;gap:var(--ymt-spacing-2xs);flex-wrap:wrap}\n"], dependencies: [{ kind: "component", type: BadgeChipComponent, selector: "yuv-badge-chip", inputs: ["badge", "showLabel"] }] }); }
368
+ }
369
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TileBadgesComponent, decorators: [{
370
+ type: Component,
371
+ args: [{ selector: 'yuv-tile-badges', imports: [BadgeChipComponent], template: "@for (b of activeBadges(); track $index) {\n <yuv-badge-chip [badge]=\"b\" />\n}\n", styles: [":host{display:inline-flex;gap:var(--ymt-spacing-2xs);flex-wrap:wrap}\n"] }]
372
+ }], propDecorators: { dmsObject: [{ type: i0.Input, args: [{ isSignal: true, alias: "dmsObject", required: true }] }], badgeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeIds", required: false }] }], bucket: [{ type: i0.Input, args: [{ isSignal: true, alias: "bucket", required: false }] }] } });
373
+
374
+ /**
375
+ * Generated bundle index. Do not edit.
376
+ */
377
+
378
+ export { BadgeChipComponent, BadgeRegistryService, BadgeSelectComponent, LOCK_BADGE, LOCK_SELF_BADGE, RETENTION_BADGE, TileBadgesComponent, evaluateRule };
379
+ //# sourceMappingURL=yuuvis-client-framework-badges.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yuuvis-client-framework-badges.mjs","sources":["../../../../../libs/yuuvis/client-framework/badges/src/lib/badge-chip/badge-chip.component.ts","../../../../../libs/yuuvis/client-framework/badges/src/lib/badge-chip/badge-chip.component.html","../../../../../libs/yuuvis/client-framework/badges/src/lib/default-badges/lock.badge.ts","../../../../../libs/yuuvis/client-framework/badges/src/lib/default-badges/retention.badge.ts","../../../../../libs/yuuvis/client-framework/badges/src/lib/utils/badge.utils.ts","../../../../../libs/yuuvis/client-framework/badges/src/lib/services/badge.service.ts","../../../../../libs/yuuvis/client-framework/badges/src/lib/badge-select/badge-select.component.ts","../../../../../libs/yuuvis/client-framework/badges/src/lib/badge-select/badge-select.component.html","../../../../../libs/yuuvis/client-framework/badges/src/lib/tile-badges/tile-badges.component.ts","../../../../../libs/yuuvis/client-framework/badges/src/lib/tile-badges/tile-badges.component.html","../../../../../libs/yuuvis/client-framework/badges/src/yuuvis-client-framework-badges.ts"],"sourcesContent":["import { Component, computed, inject, input } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { TranslatePipe, TranslateService } from '@yuuvis/client-core';\nimport { YmtBadge } from '@yuuvis/material/badge';\nimport { Badge } from '../models';\n@Component({\n selector: 'yuv-badge-chip',\n imports: [MatIconModule, MatTooltipModule, YmtBadge, TranslatePipe],\n templateUrl: './badge-chip.component.html',\n styleUrls: ['./badge-chip.component.scss']\n})\nexport class BadgeChipComponent {\n readonly #translate = inject(TranslateService);\n\n badge = input.required<Badge>();\n showLabel = input<boolean>(false);\n\n readonly tooltip = computed<string>(() => {\n const current = this.badge();\n return this.#translate.instant(current.descriptionKey ?? current.labelKey);\n });\n}\n","@let b = badge();\n\n<ymt-badge [severity]=\"b.severity ?? 'neutral'\" [matTooltip]=\"tooltip()\" class=\"badge-chip\">\n @if (b.svgIcon) {\n <mat-icon [svgIcon]=\"b.icon\" inert=\"true\" />\n } @else {\n <mat-icon inert=\"true\">{{ b.icon }}</mat-icon>\n }\n @if (showLabel()) {\n <span>{{ b.labelKey | translate }}</span>\n }\n</ymt-badge>\n","import { _ as marker } from '@ngx-translate/core';\nimport { Badge } from '../models';\n\n/**\n * Badge shown when an object is locked by another user.\n */\nexport const LOCK_BADGE: Badge = {\n id: 'yuv.badge.lock',\n labelKey: marker('yuv.badge.lock.label'),\n descriptionKey: marker('yuv.badge.lock.description'),\n icon: 'lock',\n severity: 'warning',\n priority: 10,\n /**\n * Applies if a lock tag exists and the current user is not the lock owner.\n */\n applies: (_dmsObject, ctx) => !!ctx.lockState?.locked && !ctx.lockState.lockedByCurrentUser\n};\n\n/**\n * Badge shown when an object is locked by the current user.\n */\nexport const LOCK_SELF_BADGE: Badge = {\n id: 'yuv.badge.lock.self',\n labelKey: marker('yuv.badge.lock.self.label'),\n descriptionKey: marker('yuv.badge.lock.self.description'),\n icon: 'lock_person',\n severity: 'primary',\n priority: 10,\n variantOf: 'yuv.badge.lock',\n /**\n * Applies if a lock tag exists and the current user is the lock owner.\n */\n applies: (_dmsObject, ctx) => !!ctx.lockState?.locked && ctx.lockState.lockedByCurrentUser\n};\n","import { _ as marker } from '@ngx-translate/core';\nimport { BaseObjectTypeField, RetentionField, SystemSOT } from '@yuuvis/client-core';\nimport { Badge } from '../models/badge.models';\n\n/**\n * Badge definition for DMS objects that are subject to a destruction retention policy.\n *\n * This badge is displayed when a DMS object has the `DESTRUCTION_RETENTION` secondary object type\n * assigned and an active or ongoing retention period. It helps users identify objects that are\n * legally or organizationally protected from deletion during their retention period.\n *\n * **Applies when:**\n * - The object includes the `SystemSOT.DESTRUCTION_RETENTION` secondary object type.\n * - A retention start date (`RetentionField.RETENTION_START`) is present.\n * - The retention period has started (start date is in the past), or an end date is set and\n * still lies in the future.\n *\n * @remarks\n * - `severity` is set to `'danger'` to visually emphasize the retention constraint.\n * - `priority` is `20`, which controls the display order relative to other badges.\n */ export const RETENTION_BADGE: Badge = {\n id: 'yuv.badge.retention',\n labelKey: marker('yuv.badge.retention.label'),\n descriptionKey: marker('yuv.badge.retention.description'),\n icon: 'gavel',\n severity: 'danger',\n priority: 20,\n applies: (dmsObject) => {\n const sots = dmsObject.data[BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS] as string[] | undefined;\n if (!sots?.includes(SystemSOT.DESTRUCTION_RETENTION)) return false;\n const startRetention = dmsObject.data[RetentionField.RETENTION_START] as string | undefined;\n if (!startRetention) return false;\n const now = new Date();\n const start = new Date(startRetention);\n const endRetention = dmsObject.data[RetentionField.RETENTION_END] as string | undefined;\n const end = endRetention ? new Date(endRetention) : null;\n return start < now || (end !== null && end > now);\n }\n};\n","import { BaseObjectTypeField, DmsObject } from '@yuuvis/client-core';\nimport { BadgeRule } from '../models/badge.models';\n\n/**\n * Evaluates a single badge rule against a given DMS object.\n *\n * Supported operations:\n * - `isSet`: returns `true` when the field value is not `undefined`, `null`, or an empty string.\n * - `equals`: returns `true` when the field value strictly equals `rule.value`.\n * - `tagPresent`: returns `true` when the configured tags field contains a tag whose first element equals `rule.value`.\n *\n * @param rule Badge rule definition to evaluate.\n * @param dmsObject Source object containing field data.\n * @returns `true` if the rule matches; otherwise `false`.\n */\nexport function evaluateRule(rule: BadgeRule, dmsObject: DmsObject): boolean {\n switch (rule.op) {\n case 'isSet': {\n const value = dmsObject.data[rule.field];\n return value !== undefined && value !== null && value !== '';\n }\n case 'equals': {\n return dmsObject.data[rule.field] === rule.value;\n }\n case 'tagPresent': {\n const tagsField = rule.field || BaseObjectTypeField.TAGS;\n const tags = dmsObject.data[tagsField] as unknown[][] | undefined;\n return !!tags?.some((tag) => Array.isArray(tag) && tag[0] === rule.value);\n }\n default:\n return false;\n }\n}\n","import { Injectable, Signal, computed, inject, signal } from '@angular/core';\nimport { DmsObject, ObjectLockingService, YUV_USER } from '@yuuvis/client-core';\nimport { LOCK_BADGE, LOCK_SELF_BADGE, RETENTION_BADGE } from '../default-badges';\nimport { Badge, BadgeContext } from '../models/badge.models';\nimport { evaluateRule } from '../utils';\n\ninterface StoredBadges {\n main: Badge[];\n buckets: Map<string, Badge[]>;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class BadgeRegistryService {\n readonly #store = signal<StoredBadges>({ main: [], buckets: new Map() });\n readonly #currentUser = inject(YUV_USER, { optional: true }) ?? undefined;\n readonly #objectLocking = inject(ObjectLockingService);\n\n /**\n * Registers one or multiple badges in the registry.\n *\n * If a badge with the same id already exists in the same scope, it is replaced.\n * Otherwise, the badge is added to the scope.\n *\n * @param badges An array of badges to register.\n * @param bucket Optional bucket id (typically an APP_ID). If omitted, badges are\n * registered globally and visible to every consumer. If provided,\n * badges are scoped to that bucket and only visible when consumers\n * query with the matching bucket.\n *\n * @see {@link Badge}\n */\n registerBadges(badges: Badge[], bucket?: string): void {\n this.#store.update((current) => {\n const next: StoredBadges = { main: current.main, buckets: new Map(current.buckets) };\n if (bucket === undefined) {\n next.main = this.#mergeInto(current.main, badges);\n } else {\n const existing = current.buckets.get(bucket) ?? [];\n next.buckets.set(bucket, this.#mergeInto(existing, badges));\n }\n return next;\n });\n }\n\n /**\n * Registers the default badges into the registry.\n *\n * Initializes three built-in badge types:\n * - LOCK_BADGE: Indicates objects locked by other users\n * - LOCK_SELF_BADGE: Indicates objects locked by the current user\n * - RETENTION_BADGE: Indicates objects under retention hold\n *\n * @param bucket Optional bucket id. If omitted, defaults are registered globally.\n *\n * @see {@link Badge}\n */\n registerDefaultBadges(bucket?: string): void {\n this.registerBadges([LOCK_BADGE, LOCK_SELF_BADGE, RETENTION_BADGE], bucket);\n }\n\n /**\n * Unregisters one or multiple badges from the registry by id.\n *\n * Operates only on the specified scope: omitting `bucket` removes from the global\n * scope only, providing `bucket` removes from that bucket only.\n *\n * @param id A single badge id or an array of badge ids to remove.\n * @param bucket Optional bucket id.\n */\n unregister(id: string | string[], bucket?: string): void {\n const ids = Array.isArray(id) ? id : [id];\n this.#store.update((current) => {\n const next: StoredBadges = { main: current.main, buckets: new Map(current.buckets) };\n if (bucket === undefined) {\n next.main = current.main.filter((badge) => !ids.includes(badge.id));\n } else {\n const existing = current.buckets.get(bucket);\n if (existing) {\n next.buckets.set(\n bucket,\n existing.filter((badge) => !ids.includes(badge.id))\n );\n }\n }\n return next;\n });\n }\n\n /**\n * Returns a registered badge by id.\n *\n * Looks first in the given bucket (if any), then in the global scope.\n *\n * @param id The badge id.\n * @param bucket Optional bucket id.\n * @returns The matching badge, or undefined if no badge is registered with that id.\n */\n get(id: string, bucket?: string): Badge | undefined {\n const { main, buckets } = this.#store();\n if (bucket !== undefined) {\n const local = buckets.get(bucket)?.find((badge) => badge.id === id);\n if (local) return local;\n }\n return main.find((badge) => badge.id === id);\n }\n\n /**\n * Returns all registered badges across the global scope and every bucket.\n *\n * Bucket entries override globals with the same id; remaining duplicates between\n * buckets keep the first occurrence. Useful for tests and debug inspection.\n */\n all(): Badge[] {\n const { main, buckets } = this.#store();\n const byId = new Map<string, Badge>();\n for (const badge of main) byId.set(badge.id, badge);\n for (const list of buckets.values()) {\n for (const badge of list) byId.set(badge.id, badge);\n }\n return Array.from(byId.values());\n }\n\n /**\n * Returns a reactive list of badges visible in the given scope.\n *\n * The returned signal recomputes whenever the registry changes. The list contains\n * the global badges merged with the named bucket's badges (bucket entries override\n * globals with the same id), sorted by ascending priority. At equal priority,\n * globals come first, then bucket-local badges.\n *\n * @param bucket Optional bucket id.\n */\n getBadgesForBucket(bucket?: string): Signal<Badge[]> {\n return computed(() => this.#visibleScope(bucket).sort(this.#byPriority));\n }\n\n /**\n * Resolves all active badges for a given object in the given scope.\n *\n * The visible scope is `main ∪ bucket`. Variants only resolve when their parent id\n * is present in the visible scope. If `idFilter` is provided, only badges whose id\n * (or whose variant's parent id) is in the filter are considered. The resulting\n * list is sorted by ascending priority.\n *\n * @param dmsObject The object to evaluate badges against.\n * @param options Optional bucket and id filter.\n */\n getActiveBadges(dmsObject: DmsObject, options?: { bucket?: string; idFilter?: string[] }): Badge[] {\n const visible = this.#visibleScope(options?.bucket);\n const idFilter = options?.idFilter;\n const filtered = visible.filter((badge) => {\n if (badge.variantOf !== undefined) {\n const parentVisible = visible.some((parent) => parent.id === badge.variantOf);\n if (!parentVisible) return false;\n return idFilter ? idFilter.includes(badge.variantOf) : true;\n }\n return idFilter ? idFilter.includes(badge.id) : true;\n });\n return filtered.filter((badge) => this.#isActive(badge, dmsObject)).sort(this.#byPriority);\n }\n\n /**\n * Returns globals merged with the named bucket. Bucket entries with the same id\n * override globals (the bucket entry replaces the global entry in place, preserving\n * the global's position). At equal priority, globals appear first.\n */\n #visibleScope(bucket?: string): Badge[] {\n const { main, buckets } = this.#store();\n if (bucket === undefined) return [...main];\n const local = buckets.get(bucket);\n if (!local || local.length === 0) return [...main];\n const localById = new Map(local.map((badge) => [badge.id, badge]));\n const merged: Badge[] = main.map((global) => localById.get(global.id) ?? global);\n const additions = local.filter((badge) => !main.some((global) => global.id === badge.id));\n return [...merged, ...additions];\n }\n\n readonly #byPriority = (first: Badge, second: Badge): number => (first.priority ?? 0) - (second.priority ?? 0);\n\n /**\n * Merges incoming badges into an existing list, replacing entries with the same id\n * in place and appending new ones at the end.\n */\n #mergeInto(existing: Badge[], incoming: Badge[]): Badge[] {\n const next = [...existing];\n for (const badge of incoming) {\n const idx = next.findIndex((current) => current.id === badge.id);\n if (idx === -1) next.push(badge);\n else next[idx] = badge;\n }\n return next;\n }\n\n /**\n * Evaluates whether a badge applies to the given object.\n *\n * A custom {@link Badge.applies} function has precedence over rule evaluation.\n * If neither applies nor rule is provided, the badge is considered inactive.\n */\n #isActive(badge: Badge, dmsObject: DmsObject): boolean {\n const ctx: BadgeContext = {\n currentUser: this.#currentUser,\n lockState: this.#objectLocking.getLockState(dmsObject)\n };\n if (badge.applies) return !!badge.applies(dmsObject, ctx);\n if (badge.rule) return evaluateRule(badge.rule, dmsObject);\n return false;\n }\n}\n","import { NgClass } from '@angular/common';\nimport { Component, Signal, computed, inject, input, output } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { TranslateModule } from '@yuuvis/client-core';\nimport { Badge } from '../models';\nimport { BadgeRegistryService } from '../services/badge.service';\n\n@Component({\n selector: 'yuv-tile-badge-select',\n imports: [NgClass, MatIconModule, TranslateModule],\n templateUrl: './badge-select.component.html',\n styleUrls: ['./badge-select.component.scss']\n})\nexport class BadgeSelectComponent {\n readonly #registry = inject(BadgeRegistryService);\n\n selectedBadgeIds = input<string[]>([]);\n bucket = input<string | undefined>();\n badgeSelect = output<Badge>();\n\n readonly badges: Signal<Badge[]> = computed<Badge[]>(() =>\n this.#registry\n .getBadgesForBucket(this.bucket())()\n .filter((badge) => badge.variantOf === undefined)\n );\n}\n","<div class=\"badges\">\n @for (b of badges(); track b.id) {\n <button type=\"button\" [ngClass]=\"{ selected: selectedBadgeIds().includes(b.id) }\" (click)=\"badgeSelect.emit(b)\">\n @if (b.svgIcon) {\n <mat-icon [svgIcon]=\"b.icon\" inert=\"true\" />\n } @else {\n <mat-icon inert=\"true\">{{ b.icon }}</mat-icon>\n }\n <span>{{ b.labelKey | translate }}</span>\n </button>\n } @empty {\n <span class=\"empty\">\n {{ 'yuv.badge.empty.selection' | translate }}\n </span>\n }\n</div>\n","import { Component, computed, inject, input } from '@angular/core';\nimport { DmsObject } from '@yuuvis/client-core';\nimport { BadgeChipComponent } from '../badge-chip/badge-chip.component';\nimport { Badge } from '../models/badge.models';\nimport { BadgeRegistryService } from '../services/badge.service';\n\n@Component({\n selector: 'yuv-tile-badges',\n imports: [BadgeChipComponent],\n templateUrl: './tile-badges.component.html',\n styleUrls: ['./tile-badges.component.scss']\n})\nexport class TileBadgesComponent {\n readonly #registry = inject(BadgeRegistryService);\n\n dmsObject = input.required<DmsObject>();\n badgeIds = input<string[] | undefined>();\n bucket = input<string | undefined>();\n\n readonly activeBadges = computed<Badge[]>(() =>\n this.#registry.getActiveBadges(this.dmsObject(), {\n bucket: this.bucket(),\n idFilter: this.badgeIds()\n })\n );\n}\n","@for (b of activeBadges(); track $index) {\n <yuv-badge-chip [badge]=\"b\" />\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["marker","i2"],"mappings":"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"}
@@ -98,10 +98,10 @@ class YuuvisBreadcrumbComponent {
98
98
  onItemClick(item) {
99
99
  this.navigate.emit(item);
100
100
  }
101
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: YuuvisBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
102
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: YuuvisBreadcrumbComponent, isStandalone: true, selector: "yuv-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { navigate: "navigate" }, host: { classAttribute: "yuv-breadcrumb" }, ngImport: i0, template: "<nav [attr.aria-label]=\"'yuv.framework.breadcrumb.nav-label' | translate\">\n <ol class=\"yuv-breadcrumb__list\">\n @for (item of items(); track item.id) {\n @if ($last) {\n <li class=\"yuv-breadcrumb__item yuv-breadcrumb__item--current\" aria-current=\"page\">\n {{ item.name }}\n </li>\n } @else {\n <li class=\"yuv-breadcrumb__item\">\n <a\n class=\"yuv-breadcrumb__link\"\n role=\"link\"\n tabindex=\"0\"\n (click)=\"onItemClick(item)\"\n (keydown.enter)=\"onItemClick(item)\"\n >\n {{ item.name }}\n </a>\n <span class=\"yuv-breadcrumb__separator\" aria-hidden=\"true\">/</span>\n </li>\n }\n }\n </ol>\n</nav>\n", styles: [":host{display:block}.yuv-breadcrumb__list{display:flex;flex-wrap:wrap;align-items:center;list-style:none;margin:0;padding:0}.yuv-breadcrumb__item{display:flex;align-items:center}.yuv-breadcrumb__item--current{color:var(--yuv-breadcrumb-current-color, currentColor);font-weight:500}.yuv-breadcrumb__separator{margin:0 .375rem;color:var(--yuv-breadcrumb-separator-color, currentColor);opacity:.4;-webkit-user-select:none;user-select:none}.yuv-breadcrumb__link{color:var(--yuv-breadcrumb-link-color, inherit);text-decoration:none;border-radius:2px;cursor:pointer}.yuv-breadcrumb__link:hover{text-decoration:underline}.yuv-breadcrumb__link:focus-visible{outline:2px solid currentColor;outline-offset:2px}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
101
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: YuuvisBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
102
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: YuuvisBreadcrumbComponent, isStandalone: true, selector: "yuv-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { navigate: "navigate" }, host: { classAttribute: "yuv-breadcrumb" }, ngImport: i0, template: "<nav [attr.aria-label]=\"'yuv.framework.breadcrumb.nav-label' | translate\">\n <ol class=\"yuv-breadcrumb__list\">\n @for (item of items(); track item.id) {\n @if ($last) {\n <li class=\"yuv-breadcrumb__item yuv-breadcrumb__item--current\" aria-current=\"page\">\n {{ item.name }}\n </li>\n } @else {\n <li class=\"yuv-breadcrumb__item\">\n <a\n class=\"yuv-breadcrumb__link\"\n role=\"link\"\n tabindex=\"0\"\n (click)=\"onItemClick(item)\"\n (keydown.enter)=\"onItemClick(item)\"\n >\n {{ item.name }}\n </a>\n <span class=\"yuv-breadcrumb__separator\" aria-hidden=\"true\">/</span>\n </li>\n }\n }\n </ol>\n</nav>\n", styles: [":host{display:block}.yuv-breadcrumb__list{display:flex;flex-wrap:wrap;align-items:center;list-style:none;margin:0;padding:0}.yuv-breadcrumb__item{display:flex;align-items:center}.yuv-breadcrumb__item--current{color:var(--yuv-breadcrumb-current-color, currentColor);font-weight:500}.yuv-breadcrumb__separator{margin:0 .375rem;color:var(--yuv-breadcrumb-separator-color, currentColor);opacity:.4;-webkit-user-select:none;user-select:none}.yuv-breadcrumb__link{color:var(--yuv-breadcrumb-link-color, inherit);text-decoration:none;border-radius:2px;cursor:pointer}.yuv-breadcrumb__link:hover{text-decoration:underline}.yuv-breadcrumb__link:focus-visible{outline:2px solid currentColor;outline-offset:2px}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
103
103
  }
104
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: YuuvisBreadcrumbComponent, decorators: [{
104
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: YuuvisBreadcrumbComponent, decorators: [{
105
105
  type: Component,
106
106
  args: [{ selector: 'yuv-breadcrumb', imports: [TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, host: {
107
107
  class: 'yuv-breadcrumb'
@@ -1 +1 @@
1
- {"version":3,"file":"yuuvis-client-framework-breadcrumb.mjs","sources":["../../../../../libs/yuuvis/client-framework/breadcrumb/src/lib/breadcrumb/breadcrumb.component.ts","../../../../../libs/yuuvis/client-framework/breadcrumb/src/lib/breadcrumb/breadcrumb.component.html","../../../../../libs/yuuvis/client-framework/breadcrumb/src/yuuvis-client-framework-breadcrumb.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { TranslatePipe } from '@yuuvis/client-core';\nimport { BreadcrumbItem } from '../models';\n\n/**\n * A generic, accessible breadcrumb navigation component.\n *\n * Renders a flat list of navigation items where the last item always represents\n * the current location (non-clickable) and all preceding items are interactive links.\n * Each link is individually focusable via standard Tab navigation.\n *\n * Key behaviors\n * - Items are rendered left-to-right, separated by a `/` divider\n * - The **last item** is always the current page — displayed as plain text (no link, no click handler)\n * - All **preceding items** are rendered as `<a>` links that emit the `navigate` output on click or Enter\n * - The component performs **no routing** — the parent handles all navigation logic via the emitted `BreadcrumbItem`\n * - Empty `items` array renders nothing (the host element stays in the DOM but is visually empty)\n *\n * Usage\n *\n * The parent builds the `BreadcrumbItem[]` and passes it as input. Typically this\n * array mirrors the object hierarchy the user navigated through (e.g. Case → Phase → Document).\n *\n * ```ts\n * // Parent component\n * breadcrumbItems: BreadcrumbItem[] = [\n * { id: 'case-42', name: 'Case #42' }, // ← clickable link\n * { id: 'phase-3', name: 'Review' }, // ← clickable link\n * { id: 'doc-7', name: 'Contract.pdf' } // ← current location (non-clickable)\n * ];\n *\n * onBreadcrumbNavigate(item: BreadcrumbItem): void {\n * // item.id is the domain-specific key — use it to navigate\n * this.router.navigate(['/objects', item.id]);\n * }\n * ```\n *\n * ```html\n * <yuv-breadcrumb\n * [items]=\"breadcrumbItems\"\n * (navigate)=\"onBreadcrumbNavigate($event)\" />\n * ```\n *\n * Renders visually as:\n * ```\n * Case #42 / Review / Contract.pdf\n * [link] [link] [current]\n * ```\n */\n@Component({\n selector: 'yuv-breadcrumb',\n imports: [TranslatePipe],\n templateUrl: './breadcrumb.component.html',\n styleUrl: './breadcrumb.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'yuv-breadcrumb'\n }\n})\nexport class YuuvisBreadcrumbComponent {\n // #region Angular stuff (inputs, outputs)\n\n /**\n * Ordered list of breadcrumb items to display.\n *\n * Each `BreadcrumbItem` has `{ id: string; name: string }` — where `id` is a unique key\n * (typically an object/route ID) and `name` is the display label rendered in the trail.\n *\n * Position determines rendering behavior:\n * - All items except the last → clickable `<a>` links\n * - Last item → non-clickable text (current location)\n *\n * Defaults to an empty array, which renders nothing.\n *\n * @example\n * ```ts\n * // Case → Document trail\n * [items]=\"[\n * { id: 'case-42', name: 'Case #42' },\n * { id: 'doc-7', name: 'Invoice.pdf' }\n * ]\"\n * ```\n */\n items = input<BreadcrumbItem[]>([]);\n\n /**\n * Emitted when the user activates a clickable breadcrumb item (click or Enter key).\n *\n * The emitted value is the full `BreadcrumbItem` object (`{ id, name }`) that was activated.\n * Never emitted for the last item since it is non-clickable.\n * The parent is responsible for performing the actual navigation using `item.id`.\n *\n * @example\n * ```ts\n * onBreadcrumbNavigate(item: BreadcrumbItem): void {\n * // item = { id: 'case-42', name: 'Case #42' }\n * this.router.navigate(['/objects', item.id]);\n * }\n * ```\n */\n navigate = output<BreadcrumbItem>();\n\n // #endregion\n\n // #region UI Responses\n\n /**\n * Handles click on a breadcrumb link and forwards the item to the parent via `navigate` output.\n * Called only for non-last items (the template guards against calling this for the current location).\n */\n protected onItemClick(item: BreadcrumbItem): void {\n this.navigate.emit(item);\n }\n\n // #endregion\n}\n","<nav [attr.aria-label]=\"'yuv.framework.breadcrumb.nav-label' | translate\">\n <ol class=\"yuv-breadcrumb__list\">\n @for (item of items(); track item.id) {\n @if ($last) {\n <li class=\"yuv-breadcrumb__item yuv-breadcrumb__item--current\" aria-current=\"page\">\n {{ item.name }}\n </li>\n } @else {\n <li class=\"yuv-breadcrumb__item\">\n <a\n class=\"yuv-breadcrumb__link\"\n role=\"link\"\n tabindex=\"0\"\n (click)=\"onItemClick(item)\"\n (keydown.enter)=\"onItemClick(item)\"\n >\n {{ item.name }}\n </a>\n <span class=\"yuv-breadcrumb__separator\" aria-hidden=\"true\">/</span>\n </li>\n }\n }\n </ol>\n</nav>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CG;MAWU,yBAAyB,CAAA;AAVtC,IAAA,WAAA,GAAA;;AAaE;;;;;;;;;;;;;;;;;;;;AAoBG;AACH,QAAA,IAAA,CAAA,KAAK,GAAG,KAAK,CAAmB,EAAE,4EAAC;AAEnC;;;;;;;;;;;;;;AAcG;QACH,IAAA,CAAA,QAAQ,GAAG,MAAM,EAAkB;AAepC,IAAA;;;AATC;;;AAGG;AACO,IAAA,WAAW,CAAC,IAAoB,EAAA;AACxC,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1B;8GArDW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAzB,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC3DtC,8wBAwBA,EAAA,MAAA,EAAA,CAAA,gsBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,ED2BY,aAAa,EAAA,IAAA,EAAA,WAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAQZ,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAVrC,SAAS;+BACE,gBAAgB,EAAA,OAAA,EACjB,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC;AACJ,wBAAA,KAAK,EAAE;AACR,qBAAA,EAAA,QAAA,EAAA,8wBAAA,EAAA,MAAA,EAAA,CAAA,gsBAAA,CAAA,EAAA;;;AEzDH;;AAEG;;;;"}
1
+ {"version":3,"file":"yuuvis-client-framework-breadcrumb.mjs","sources":["../../../../../libs/yuuvis/client-framework/breadcrumb/src/lib/breadcrumb/breadcrumb.component.ts","../../../../../libs/yuuvis/client-framework/breadcrumb/src/lib/breadcrumb/breadcrumb.component.html","../../../../../libs/yuuvis/client-framework/breadcrumb/src/yuuvis-client-framework-breadcrumb.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { TranslatePipe } from '@yuuvis/client-core';\nimport { BreadcrumbItem } from '../models';\n\n/**\n * A generic, accessible breadcrumb navigation component.\n *\n * Renders a flat list of navigation items where the last item always represents\n * the current location (non-clickable) and all preceding items are interactive links.\n * Each link is individually focusable via standard Tab navigation.\n *\n * Key behaviors\n * - Items are rendered left-to-right, separated by a `/` divider\n * - The **last item** is always the current page — displayed as plain text (no link, no click handler)\n * - All **preceding items** are rendered as `<a>` links that emit the `navigate` output on click or Enter\n * - The component performs **no routing** — the parent handles all navigation logic via the emitted `BreadcrumbItem`\n * - Empty `items` array renders nothing (the host element stays in the DOM but is visually empty)\n *\n * Usage\n *\n * The parent builds the `BreadcrumbItem[]` and passes it as input. Typically this\n * array mirrors the object hierarchy the user navigated through (e.g. Case → Phase → Document).\n *\n * ```ts\n * // Parent component\n * breadcrumbItems: BreadcrumbItem[] = [\n * { id: 'case-42', name: 'Case #42' }, // ← clickable link\n * { id: 'phase-3', name: 'Review' }, // ← clickable link\n * { id: 'doc-7', name: 'Contract.pdf' } // ← current location (non-clickable)\n * ];\n *\n * onBreadcrumbNavigate(item: BreadcrumbItem): void {\n * // item.id is the domain-specific key — use it to navigate\n * this.router.navigate(['/objects', item.id]);\n * }\n * ```\n *\n * ```html\n * <yuv-breadcrumb\n * [items]=\"breadcrumbItems\"\n * (navigate)=\"onBreadcrumbNavigate($event)\" />\n * ```\n *\n * Renders visually as:\n * ```\n * Case #42 / Review / Contract.pdf\n * [link] [link] [current]\n * ```\n */\n@Component({\n selector: 'yuv-breadcrumb',\n imports: [TranslatePipe],\n templateUrl: './breadcrumb.component.html',\n styleUrl: './breadcrumb.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'yuv-breadcrumb'\n }\n})\nexport class YuuvisBreadcrumbComponent {\n // #region Angular stuff (inputs, outputs)\n\n /**\n * Ordered list of breadcrumb items to display.\n *\n * Each `BreadcrumbItem` has `{ id: string; name: string }` — where `id` is a unique key\n * (typically an object/route ID) and `name` is the display label rendered in the trail.\n *\n * Position determines rendering behavior:\n * - All items except the last → clickable `<a>` links\n * - Last item → non-clickable text (current location)\n *\n * Defaults to an empty array, which renders nothing.\n *\n * @example\n * ```ts\n * // Case → Document trail\n * [items]=\"[\n * { id: 'case-42', name: 'Case #42' },\n * { id: 'doc-7', name: 'Invoice.pdf' }\n * ]\"\n * ```\n */\n items = input<BreadcrumbItem[]>([]);\n\n /**\n * Emitted when the user activates a clickable breadcrumb item (click or Enter key).\n *\n * The emitted value is the full `BreadcrumbItem` object (`{ id, name }`) that was activated.\n * Never emitted for the last item since it is non-clickable.\n * The parent is responsible for performing the actual navigation using `item.id`.\n *\n * @example\n * ```ts\n * onBreadcrumbNavigate(item: BreadcrumbItem): void {\n * // item = { id: 'case-42', name: 'Case #42' }\n * this.router.navigate(['/objects', item.id]);\n * }\n * ```\n */\n navigate = output<BreadcrumbItem>();\n\n // #endregion\n\n // #region UI Responses\n\n /**\n * Handles click on a breadcrumb link and forwards the item to the parent via `navigate` output.\n * Called only for non-last items (the template guards against calling this for the current location).\n */\n protected onItemClick(item: BreadcrumbItem): void {\n this.navigate.emit(item);\n }\n\n // #endregion\n}\n","<nav [attr.aria-label]=\"'yuv.framework.breadcrumb.nav-label' | translate\">\n <ol class=\"yuv-breadcrumb__list\">\n @for (item of items(); track item.id) {\n @if ($last) {\n <li class=\"yuv-breadcrumb__item yuv-breadcrumb__item--current\" aria-current=\"page\">\n {{ item.name }}\n </li>\n } @else {\n <li class=\"yuv-breadcrumb__item\">\n <a\n class=\"yuv-breadcrumb__link\"\n role=\"link\"\n tabindex=\"0\"\n (click)=\"onItemClick(item)\"\n (keydown.enter)=\"onItemClick(item)\"\n >\n {{ item.name }}\n </a>\n <span class=\"yuv-breadcrumb__separator\" aria-hidden=\"true\">/</span>\n </li>\n }\n }\n </ol>\n</nav>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CG;MAWU,yBAAyB,CAAA;AAVtC,IAAA,WAAA,GAAA;;AAaE;;;;;;;;;;;;;;;;;;;;AAoBG;AACH,QAAA,IAAA,CAAA,KAAK,GAAG,KAAK,CAAmB,EAAE,4EAAC;AAEnC;;;;;;;;;;;;;;AAcG;QACH,IAAA,CAAA,QAAQ,GAAG,MAAM,EAAkB;AAepC,IAAA;;;AATC;;;AAGG;AACO,IAAA,WAAW,CAAC,IAAoB,EAAA;AACxC,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1B;+GArDW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;mGAAzB,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC3DtC,8wBAwBA,EAAA,MAAA,EAAA,CAAA,gsBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,ED2BY,aAAa,EAAA,IAAA,EAAA,WAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAQZ,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAVrC,SAAS;+BACE,gBAAgB,EAAA,OAAA,EACjB,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC;AACJ,wBAAA,KAAK,EAAE;AACR,qBAAA,EAAA,QAAA,EAAA,8wBAAA,EAAA,MAAA,EAAA,CAAA,gsBAAA,CAAA,EAAA;;;AEzDH;;AAEG;;;;"}
@@ -1,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, DestroyRef, input, output, Component } from '@angular/core';
3
3
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
- import { marker } from '@colsen1991/ngx-translate-extract-marker';
4
+ import { _ } from '@ngx-translate/core';
5
5
  import { ClipboardService, TranslateService, TranslatePipe } from '@yuuvis/client-core';
6
6
  import { YmtButtonDirective } from '@yuuvis/material';
7
7
 
8
- marker('yuv.clipboard.text.copy.single');
9
- marker('yuv.clipboard.text.copy.multiple');
10
- marker('yuv.clipboard.text.cut.single');
11
- marker('yuv.clipboard.text.cut.multiple');
8
+ _('yuv.clipboard.text.copy.single');
9
+ _('yuv.clipboard.text.copy.multiple');
10
+ _('yuv.clipboard.text.cut.single');
11
+ _('yuv.clipboard.text.cut.multiple');
12
12
  class ClipboardComponent {
13
13
  constructor() {
14
14
  this.#clipboard = inject(ClipboardService);
@@ -36,10 +36,10 @@ class ClipboardComponent {
36
36
  }
37
37
  });
38
38
  }
39
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ClipboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
40
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ClipboardComponent, isStandalone: true, selector: "yuv-clipboard", inputs: { enablePaste: { classPropertyName: "enablePaste", publicName: "enablePaste", isSignal: true, isRequired: false, transformFunction: null }, bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { paste: "paste" }, host: { properties: { "attr.inert": "clipboardData?.objects?.length ? null : true" } }, ngImport: i0, template: "@if (clipboardData?.objects?.length) {\n <div class=\"clipboard\">\n <p class=\"clipboard__label\"> {{ label }}</p>\n <button ymtButton=\"secondary\" button-size=\"small\" (click)=\"clearClipboard()\">{{ 'yuv.clipboard.button.cancel' | translate }}</button>\n @if (enablePaste()) {\n <button ymtButton=\"primary\" button-size=\"small\" (click)=\"paste.emit()\">{{ 'yuv.clipboard.button.paste' | translate }}</button>\n }\n </div>\n}\n", styles: [":host{display:flex;justify-content:stretch}:host .clipboard{display:flex;align-items:center;flex:1;line-height:1;background-color:var(--ymt-surface-container-high);border-radius:var(--ymt-corner-s);padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-xs);color:var(--ymt-on-surface)}:host .clipboard__label{margin:0;flex:1;font:var(--ymt-font-body)}\n"], dependencies: [{ kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
39
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ClipboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
40
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: ClipboardComponent, isStandalone: true, selector: "yuv-clipboard", inputs: { enablePaste: { classPropertyName: "enablePaste", publicName: "enablePaste", isSignal: true, isRequired: false, transformFunction: null }, bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { paste: "paste" }, host: { properties: { "attr.inert": "clipboardData?.objects?.length ? null : true" } }, ngImport: i0, template: "@if (clipboardData?.objects?.length) {\n <div class=\"clipboard\">\n <p class=\"clipboard__label\"> {{ label }}</p>\n <button ymtButton=\"secondary\" button-size=\"small\" (click)=\"clearClipboard()\">{{ 'yuv.clipboard.button.cancel' | translate }}</button>\n @if (enablePaste()) {\n <button ymtButton=\"primary\" button-size=\"small\" (click)=\"paste.emit()\">{{ 'yuv.clipboard.button.paste' | translate }}</button>\n }\n </div>\n}\n", styles: [":host{display:flex;justify-content:stretch}:host .clipboard{display:flex;align-items:center;flex:1;line-height:1;background-color:var(--ymt-surface-container-high);border-radius:var(--ymt-corner-s);padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-xs);color:var(--ymt-on-surface)}:host .clipboard__label{margin:0;flex:1;font:var(--ymt-font-body)}\n"], dependencies: [{ kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
41
41
  }
42
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ClipboardComponent, decorators: [{
42
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ClipboardComponent, decorators: [{
43
43
  type: Component,
44
44
  args: [{ selector: 'yuv-clipboard', standalone: true, imports: [TranslatePipe, YmtButtonDirective], host: {
45
45
  '[attr.inert]': 'clipboardData?.objects?.length ? null : true'
@@ -1 +1 @@
1
- {"version":3,"file":"yuuvis-client-framework-clipboard.mjs","sources":["../../../../../libs/yuuvis/client-framework/clipboard/src/lib/clipboard.component.ts","../../../../../libs/yuuvis/client-framework/clipboard/src/lib/clipboard.component.html","../../../../../libs/yuuvis/client-framework/clipboard/src/yuuvis-client-framework-clipboard.ts"],"sourcesContent":["import { Component, DestroyRef, inject, input, OnInit, output } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { marker } from '@colsen1991/ngx-translate-extract-marker';\nimport { ClipboardData, ClipboardService, TranslatePipe, TranslateService } from '@yuuvis/client-core';\nimport { YmtButtonDirective } from '@yuuvis/material';\n\nmarker('yuv.clipboard.text.copy.single');\nmarker('yuv.clipboard.text.copy.multiple');\nmarker('yuv.clipboard.text.cut.single');\nmarker('yuv.clipboard.text.cut.multiple');\n\n@Component({\n selector: 'yuv-clipboard',\n standalone: true,\n imports: [TranslatePipe, YmtButtonDirective],\n templateUrl: './clipboard.component.html',\n styleUrl: './clipboard.component.scss',\n host: {\n '[attr.inert]': 'clipboardData?.objects?.length ? null : true'\n }\n})\nexport class ClipboardComponent implements OnInit {\n #clipboard = inject(ClipboardService);\n #destroyRef = inject(DestroyRef);\n translate = inject(TranslateService);\n\n clipboardData: ClipboardData | undefined = undefined;\n\n label?: string;\n enablePaste = input<boolean>(false);\n\n bucket = input<string>();\n paste = output();\n\n clearClipboard() {\n this.#clipboard.clear(this.bucket());\n }\n\n ngOnInit() {\n this.#clipboard\n .clipboard$(this.bucket())\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe((cd: ClipboardData | undefined) => {\n this.clipboardData = cd;\n if (cd?.mode && cd.objects?.length) {\n const key = `yuv.clipboard.text.${cd?.mode}.${cd.objects.length === 1 ? 'single' : 'multiple'}`;\n this.label = this.translate.instant(key, { count: cd?.objects.length });\n }\n });\n }\n}\n","@if (clipboardData?.objects?.length) {\n <div class=\"clipboard\">\n <p class=\"clipboard__label\"> {{ label }}</p>\n <button ymtButton=\"secondary\" button-size=\"small\" (click)=\"clearClipboard()\">{{ 'yuv.clipboard.button.cancel' | translate }}</button>\n @if (enablePaste()) {\n <button ymtButton=\"primary\" button-size=\"small\" (click)=\"paste.emit()\">{{ 'yuv.clipboard.button.paste' | translate }}</button>\n }\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"yuuvis-client-framework-clipboard.mjs","sources":["../../../../../libs/yuuvis/client-framework/clipboard/src/lib/clipboard.component.ts","../../../../../libs/yuuvis/client-framework/clipboard/src/lib/clipboard.component.html","../../../../../libs/yuuvis/client-framework/clipboard/src/yuuvis-client-framework-clipboard.ts"],"sourcesContent":["import { Component, DestroyRef, inject, input, OnInit, output } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { _ as marker } from '@ngx-translate/core';\nimport { ClipboardData, ClipboardService, TranslatePipe, TranslateService } from '@yuuvis/client-core';\nimport { YmtButtonDirective } from '@yuuvis/material';\n\nmarker('yuv.clipboard.text.copy.single');\nmarker('yuv.clipboard.text.copy.multiple');\nmarker('yuv.clipboard.text.cut.single');\nmarker('yuv.clipboard.text.cut.multiple');\n\n@Component({\n selector: 'yuv-clipboard',\n standalone: true,\n imports: [TranslatePipe, YmtButtonDirective],\n templateUrl: './clipboard.component.html',\n styleUrl: './clipboard.component.scss',\n host: {\n '[attr.inert]': 'clipboardData?.objects?.length ? null : true'\n }\n})\nexport class ClipboardComponent implements OnInit {\n #clipboard = inject(ClipboardService);\n #destroyRef = inject(DestroyRef);\n translate = inject(TranslateService);\n\n clipboardData: ClipboardData | undefined = undefined;\n\n label?: string;\n enablePaste = input<boolean>(false);\n\n bucket = input<string>();\n paste = output();\n\n clearClipboard() {\n this.#clipboard.clear(this.bucket());\n }\n\n ngOnInit() {\n this.#clipboard\n .clipboard$(this.bucket())\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe((cd: ClipboardData | undefined) => {\n this.clipboardData = cd;\n if (cd?.mode && cd.objects?.length) {\n const key = `yuv.clipboard.text.${cd?.mode}.${cd.objects.length === 1 ? 'single' : 'multiple'}`;\n this.label = this.translate.instant(key, { count: cd?.objects.length });\n }\n });\n }\n}\n","@if (clipboardData?.objects?.length) {\n <div class=\"clipboard\">\n <p class=\"clipboard__label\"> {{ label }}</p>\n <button ymtButton=\"secondary\" button-size=\"small\" (click)=\"clearClipboard()\">{{ 'yuv.clipboard.button.cancel' | translate }}</button>\n @if (enablePaste()) {\n <button ymtButton=\"primary\" button-size=\"small\" (click)=\"paste.emit()\">{{ 'yuv.clipboard.button.paste' | translate }}</button>\n }\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["marker"],"mappings":";;;;;;;AAMAA,CAAM,CAAC,gCAAgC,CAAC;AACxCA,CAAM,CAAC,kCAAkC,CAAC;AAC1CA,CAAM,CAAC,+BAA+B,CAAC;AACvCA,CAAM,CAAC,iCAAiC,CAAC;MAY5B,kBAAkB,CAAA;AAV/B,IAAA,WAAA,GAAA;AAWE,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACrC,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;AAChC,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;QAEpC,IAAA,CAAA,aAAa,GAA8B,SAAS;AAGpD,QAAA,IAAA,CAAA,WAAW,GAAG,KAAK,CAAU,KAAK,kFAAC;QAEnC,IAAA,CAAA,MAAM,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;QACxB,IAAA,CAAA,KAAK,GAAG,MAAM,EAAE;AAkBjB,IAAA;AA5BC,IAAA,UAAU;AACV,IAAA,WAAW;IAWX,cAAc,GAAA;QACZ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC;IAEA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC;AACF,aAAA,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE;AACxB,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC;AACzC,aAAA,SAAS,CAAC,CAAC,EAA6B,KAAI;AAC3C,YAAA,IAAI,CAAC,aAAa,GAAG,EAAE;YACvB,IAAI,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE;gBAClC,MAAM,GAAG,GAAG,CAAA,mBAAA,EAAsB,EAAE,EAAE,IAAI,CAAA,CAAA,EAAI,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,GAAG,QAAQ,GAAG,UAAU,CAAA,CAAE;gBAC/F,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YACzE;AACF,QAAA,CAAC,CAAC;IACN;+GA5BW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,YAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECrB/B,ucASA,EAAA,MAAA,EAAA,CAAA,gWAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDK2B,kBAAkB,kLAAjC,aAAa,EAAA,IAAA,EAAA,WAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;4FAOZ,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAV9B,SAAS;+BACE,eAAe,EAAA,UAAA,EACb,IAAI,EAAA,OAAA,EACP,CAAC,aAAa,EAAE,kBAAkB,CAAC,EAAA,IAAA,EAGtC;AACJ,wBAAA,cAAc,EAAE;AACjB,qBAAA,EAAA,QAAA,EAAA,ucAAA,EAAA,MAAA,EAAA,CAAA,gWAAA,CAAA,EAAA;;;AEnBH;;AAEG;;;;"}