@mohamedatia/fly-design-system 2.3.2 → 2.4.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.
|
@@ -29,6 +29,22 @@ const WINDOW_DATA = new InjectionToken('WINDOW_DATA');
|
|
|
29
29
|
*/
|
|
30
30
|
const LAUNCH_CONTEXT = new InjectionToken('LAUNCH_CONTEXT');
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Generic share / ACL panel models — hosts map domain DTOs to these shapes.
|
|
34
|
+
*
|
|
35
|
+
* v2.0.0: introduces the {@link SharePrincipal} discriminated union to replace the v1
|
|
36
|
+
* "set-which-is-set" discriminator on {@link SharePermissionEntry} (`grantedToUserId` /
|
|
37
|
+
* `grantedToOuId` / `grantedToAppId`). The new shape compiles invalid combinations away
|
|
38
|
+
* (a permission row carries exactly one principal, never overlapping ids) and reserves
|
|
39
|
+
* a `role` kind for the planned apps-chart role-as-principal flow.
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Stable identifiers for platform-managed system charts. Hosts that don't recognise the
|
|
43
|
+
* value just fall through to the default selection — these constants are advisory.
|
|
44
|
+
*/
|
|
45
|
+
const SHARE_ORG_CHART_SYSTEM_KEY_DEFAULT = 'default-company';
|
|
46
|
+
const SHARE_ORG_CHART_SYSTEM_KEY_APPS = 'apps';
|
|
47
|
+
|
|
32
48
|
/** Discriminator string values — re-exported so hosts can build kind menus dynamically. */
|
|
33
49
|
const AUDIENCE_TERM_KINDS = [
|
|
34
50
|
'users',
|
|
@@ -804,6 +820,17 @@ class SharePanelComponent {
|
|
|
804
820
|
loadOuTree;
|
|
805
821
|
/** Chart selector options; first entry should be the default chart (`id: null`). */
|
|
806
822
|
loadChartOptions;
|
|
823
|
+
/**
|
|
824
|
+
* Initial chart selection. Resolution order:
|
|
825
|
+
* <list type="number">
|
|
826
|
+
* <item>{@link defaultChartId} when explicitly provided (string or null).</item>
|
|
827
|
+
* <item>First option matching {@link defaultChartSystemKey} (e.g. <c>'apps'</c>).</item>
|
|
828
|
+
* <item>Host order — <c>options[0]?.id ?? null</c>.</item>
|
|
829
|
+
* </list>
|
|
830
|
+
*/
|
|
831
|
+
defaultChartSystemKey;
|
|
832
|
+
/** Hard-coded chart id to pre-select. Takes priority over {@link defaultChartSystemKey}. */
|
|
833
|
+
defaultChartId;
|
|
807
834
|
/**
|
|
808
835
|
* Labels from the default (official) OU tree for stable display names on OU grants
|
|
809
836
|
* when the picker shows an alternative chart.
|
|
@@ -909,8 +936,7 @@ class SharePanelComponent {
|
|
|
909
936
|
.subscribe({
|
|
910
937
|
next: (opts) => {
|
|
911
938
|
this.chartOptions.set(opts);
|
|
912
|
-
const
|
|
913
|
-
const initial = first ? first.id : null;
|
|
939
|
+
const initial = this.resolveInitialChartId(opts);
|
|
914
940
|
this.selectedOrgChartId.set(initial);
|
|
915
941
|
this.selectedChartId$.next(initial);
|
|
916
942
|
},
|
|
@@ -921,6 +947,24 @@ class SharePanelComponent {
|
|
|
921
947
|
},
|
|
922
948
|
});
|
|
923
949
|
}
|
|
950
|
+
/**
|
|
951
|
+
* Picks the chart id to seed the OU picker with. Honours explicit
|
|
952
|
+
* {@link defaultChartId} first (null is a valid id), then {@link defaultChartSystemKey},
|
|
953
|
+
* then falls back to host order.
|
|
954
|
+
*/
|
|
955
|
+
resolveInitialChartId(opts) {
|
|
956
|
+
if (this.defaultChartId !== undefined) {
|
|
957
|
+
const exists = opts.some((o) => o.id === this.defaultChartId);
|
|
958
|
+
return exists ? this.defaultChartId : (opts[0]?.id ?? null);
|
|
959
|
+
}
|
|
960
|
+
const key = this.defaultChartSystemKey;
|
|
961
|
+
if (key) {
|
|
962
|
+
const match = opts.find((o) => o.systemKey === key);
|
|
963
|
+
if (match)
|
|
964
|
+
return match.id;
|
|
965
|
+
}
|
|
966
|
+
return opts[0]?.id ?? null;
|
|
967
|
+
}
|
|
924
968
|
onOrgChartSelectChange(chartId) {
|
|
925
969
|
this.selectedOrgChartId.set(chartId);
|
|
926
970
|
this.selectedChartId$.next(chartId);
|
|
@@ -1080,7 +1124,7 @@ class SharePanelComponent {
|
|
|
1080
1124
|
}
|
|
1081
1125
|
}
|
|
1082
1126
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SharePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1083
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: SharePanelComponent, isStandalone: true, selector: "fly-share-panel", inputs: { targetName: "targetName", titleKey: "titleKey", loadPermissions: "loadPermissions", searchUsers: "searchUsers", loadOuTree: "loadOuTree", loadChartOptions: "loadChartOptions", loadOuLabelMap: "loadOuLabelMap", grantToUser: "grantToUser", grantToOu: "grantToOu", updatePermission: "updatePermission", revokePermission: "revokePermission", showApplyToChildren: "showApplyToChildren", supportsDeny: "supportsDeny", permissionLevels: "permissionLevels", everyoneLabelKey: "everyoneLabelKey", loadRoleOus: "loadRoleOus" }, outputs: { close: "close" }, ngImport: i0, template: "<div class=\"fac-overlay\" (click)=\"close.emit()\">\r\n <div class=\"fac-panel\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"fac-header\">\r\n <h3>{{ titleKey | translate }}</h3>\r\n <span class=\"fac-target-name\">{{ targetName }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"fac-close\"\r\n (click)=\"close.emit()\"\r\n [attr.aria-label]=\"'files.share.close' | translate\">\r\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fac-add-section\">\r\n <div class=\"fac-search-row\">\r\n <input\r\n type=\"text\"\r\n class=\"fac-input\"\r\n [(ngModel)]=\"searchQuery\"\r\n (input)=\"onSearchInput()\"\r\n [placeholder]=\"'files.share.search_placeholder' | translate\"\r\n [attr.aria-label]=\"'files.share.search_users' | translate\"\r\n />\r\n <select class=\"fac-select\" [(ngModel)]=\"newLevel\">\r\n @for (opt of levelOptions; track opt.value) {\r\n <option [value]=\"opt.value\">{{ opt.labelKey | translate }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n @if (searchResults().length > 0) {\r\n <div class=\"fac-search-results\">\r\n @for (result of searchResults(); track result.id) {\r\n <div class=\"fac-search-item\" (click)=\"onGrantToUser(result)\">\r\n <i class=\"pi pi-user\" aria-hidden=\"true\"></i>\r\n <span>{{ result.firstName }} {{ result.lastName }}</span>\r\n <span class=\"fac-email\">{{ result.email }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (chartOptions().length > 0) {\r\n <div class=\"fac-chart-row\">\r\n <label for=\"fac-org-chart-select\" class=\"fac-section-label\">{{\r\n 'files.share.org_chart' | translate\r\n }}</label>\r\n <select\r\n id=\"fac-org-chart-select\"\r\n class=\"fac-select\"\r\n [ngModel]=\"selectedOrgChartId()\"\r\n (ngModelChange)=\"onOrgChartSelectChange($event)\">\r\n @for (opt of chartOptions(); track $index) {\r\n <option [ngValue]=\"opt.id\">{{ opt.name }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n\r\n @if (showOuPicker()) {\r\n <div class=\"fac-ou-section\">\r\n <div class=\"fac-section-label\">{{ 'files.share.share_with_ou' | translate }}</div>\r\n @for (ou of ouTree(); track ou.id) {\r\n <button\r\n type=\"button\"\r\n class=\"fac-ou-item\"\r\n [style.padding-inline-start.px]=\"ouIndentStartPx(ou)\"\r\n (click)=\"onGrantToOu(ou)\"\r\n [attr.aria-label]=\"('files.share.share_with_ou_named' | translate) + ' ' + ou.displayName\"\r\n >\r\n <i class=\"pi pi-sitemap\" aria-hidden=\"true\"></i>\r\n <span dir=\"auto\">{{ ou.displayName }}</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (loadRoleOus && roleOus().length > 0) {\r\n <div class=\"fac-role-section\">\r\n <div class=\"fac-section-label\">{{ 'files.share.share_with_role' | translate }}</div>\r\n <input\r\n type=\"text\"\r\n class=\"fac-input\"\r\n [(ngModel)]=\"roleSearchQuery\"\r\n [placeholder]=\"'files.share.role_search_placeholder' | translate\"\r\n [attr.aria-label]=\"'files.share.search_roles' | translate\"\r\n [hidden]=\"!showRolePicker()\" />\r\n @if (showRolePicker()) {\r\n <div class=\"fac-role-list\">\r\n @for (role of filteredRoles(); track role.ouId) {\r\n <button\r\n type=\"button\"\r\n class=\"fac-role-item\"\r\n (click)=\"onGrantToRole(role)\"\r\n [attr.aria-label]=\"('files.share.share_with_role_named' | translate) + ' ' + role.displayName\">\r\n <i class=\"pi pi-id-card\" aria-hidden=\"true\"></i>\r\n <span dir=\"auto\">{{ role.displayName }}</span>\r\n <span class=\"fac-role-app\">{{ role.appId }}</span>\r\n </button>\r\n }\r\n @if (filteredRoles().length === 0) {\r\n <div class=\"fac-empty\">{{ 'files.share.no_roles_match' | translate }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"fac-toggle-row\">\r\n <button type=\"button\" class=\"fac-link\" (click)=\"showOuPicker.set(!showOuPicker())\">\r\n {{ showOuPicker() ? ('files.share.hide_ous' | translate) : ('files.share.show_ous' | translate) }}\r\n </button>\r\n @if (loadRoleOus && roleOus().length > 0) {\r\n <button type=\"button\" class=\"fac-link\" (click)=\"showRolePicker.set(!showRolePicker())\">\r\n {{ showRolePicker() ? ('files.share.hide_roles' | translate) : ('files.share.show_roles' | translate) }}\r\n </button>\r\n }\r\n @if (showApplyToChildren) {\r\n <label class=\"fac-checkbox-label\">\r\n <input type=\"checkbox\" [(ngModel)]=\"applyToChildren\" />\r\n {{ 'files.share.apply_children' | translate }}\r\n </label>\r\n }\r\n @if (supportsDeny) {\r\n <label class=\"fac-checkbox-label fac-deny-toggle\"\r\n [title]=\"'files.share.deny_help' | translate\">\r\n <input type=\"checkbox\" [(ngModel)]=\"addAsDeny\" />\r\n <i class=\"pi pi-ban\" aria-hidden=\"true\"></i>\r\n {{ 'files.share.add_as_deny' | translate }}\r\n </label>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"fac-perms-section\">\r\n <div class=\"fac-section-label\">{{ 'files.share.current_permissions' | translate }}</div>\r\n @if (loading()) {\r\n <div class=\"fac-loading\"><i class=\"pi pi-spin pi-spinner\" aria-hidden=\"true\"></i></div>\r\n } @else if (permissions().length === 0) {\r\n <div class=\"fac-empty\">{{ 'files.share.no_permissions' | translate }}</div>\r\n } @else {\r\n @for (perm of permissions(); track perm.id) {\r\n <div class=\"fac-perm-row\" [class.fac-perm-row-deny]=\"perm.isDeny\">\r\n <div class=\"fac-perm-info\">\r\n <i [class]=\"getPermIcon(perm)\" aria-hidden=\"true\"></i>\r\n <span class=\"fac-perm-name\" dir=\"auto\">{{ getPermLabel(perm) }}</span>\r\n @if (perm.isDeny) {\r\n <span class=\"fac-badge deny\">{{ 'files.share.denied' | translate }}</span>\r\n }\r\n @if (perm.isInherited) {\r\n <span class=\"fac-badge inherited\">{{ 'files.share.inherited' | translate }}</span>\r\n }\r\n </div>\r\n <div class=\"fac-perm-actions\">\r\n @if (!perm.isDeny) {\r\n <select\r\n class=\"fac-select sm\"\r\n [ngModel]=\"perm.level\"\r\n (ngModelChange)=\"onUpdateLevel(perm, $event)\"\r\n [disabled]=\"perm.isInherited === true\"\r\n >\r\n @for (opt of levelOptions; track opt.value) {\r\n <option [value]=\"opt.value\">{{ opt.labelKey | translate }}</option>\r\n }\r\n </select>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"fac-icon-btn danger\"\r\n (click)=\"onRevokePermission(perm)\"\r\n [disabled]=\"perm.isInherited === true\"\r\n [title]=\"'files.share.revoke' | translate\"\r\n >\r\n <i class=\"pi pi-trash\" aria-hidden=\"true\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".fac-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:2000;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.fac-panel{background:var(--surface-card, #1e1e1e);border:1px solid var(--surface-border);border-radius:12px;width:600px;max-width:min(600px,96vw);max-height:85vh;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 16px 48px #0006}.fac-header{display:flex;align-items:center;gap:10px;padding:16px 20px;border-bottom:1px solid var(--surface-border)}.fac-header h3{margin:0;font-size:16px;font-weight:600}.fac-target-name{flex:1;font-size:13px;color:var(--text-color-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fac-close{background:none;border:none;color:var(--text-color-secondary);cursor:pointer;font-size:16px;padding:4px}.fac-close:hover{color:var(--text-color)}.fac-add-section{padding:16px 20px;border-bottom:1px solid var(--surface-border)}.fac-search-row{display:flex;gap:8px}.fac-chart-row{display:flex;flex-direction:column;gap:6px;margin-top:12px}.fac-chart-row .fac-select{width:100%}.fac-input{flex:1;background:#ffffff14;border:1px solid rgba(255,255,255,.15);border-radius:8px;padding:8px 12px;color:inherit;font-size:13px;outline:none}.fac-input:focus{border-color:var(--primary-color, #e8732a)}.fac-select{background:#ffffff14;border:1px solid rgba(255,255,255,.15);border-radius:8px;padding:8px 10px;color:inherit;font-size:13px;outline:none}.fac-select.sm{padding:4px 8px;font-size:12px}.fac-search-results{margin-top:8px;max-height:150px;overflow-y:auto;border:1px solid var(--surface-border);border-radius:8px}.fac-search-item{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;font-size:13px}.fac-search-item:hover{background:var(--surface-hover)}.fac-search-item i{color:var(--text-color-secondary)}.fac-email{color:var(--text-color-secondary);font-size:12px;margin-inline-start:auto}.fac-ou-section{margin-top:10px;max-height:220px;overflow-y:auto}.fac-ou-item{display:flex;align-items:center;gap:8px;padding:6px 12px;padding-inline-start:12px;cursor:pointer;font-size:13px;border-radius:6px}.fac-ou-item:hover{background:var(--surface-hover)}.fac-ou-item i{color:var(--text-color-secondary)}.fac-section-label{font-size:11px;font-weight:700;text-transform:uppercase;color:var(--text-color-secondary);letter-spacing:.5px;margin-bottom:8px}.fac-toggle-row{display:flex;align-items:center;justify-content:space-between;margin-top:10px}.fac-link{background:none;border:none;color:var(--primary-color, #e8732a);cursor:pointer;font-size:12px;padding:0}.fac-link:hover{text-decoration:underline}.fac-checkbox-label{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-color-secondary);cursor:pointer}.fac-checkbox-label input{accent-color:var(--primary-color, #e8732a)}.fac-perms-section{flex:1;overflow-y:auto;padding:16px 20px}.fac-loading,.fac-empty{text-align:center;padding:20px;color:var(--text-color-secondary);font-size:13px}.fac-perm-row{display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-bottom:1px solid rgba(255,255,255,.05);gap:8px}.fac-perm-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.fac-perm-info i{color:var(--text-color-secondary);flex-shrink:0}.fac-perm-name{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fac-badge{font-size:10px;padding:2px 6px;border-radius:8px;flex-shrink:0}.fac-badge.inherited{background:#ffffff1a;color:var(--text-color-secondary)}.fac-badge.deny{background:#ff3b302e;color:#ff3b30;text-transform:uppercase;font-weight:600;letter-spacing:.5px}.fac-perm-row-deny{background:#ff3b300f;border-inline-start:3px solid #ff3b30;padding-inline-start:8px;border-radius:6px}.fac-perm-row-deny .fac-perm-info i{color:#ff3b30}.fac-deny-toggle{color:#ff6b6b}.fac-deny-toggle i{color:#ff6b6b;font-size:11px;margin-inline-end:2px}.fac-deny-toggle input{accent-color:#ff3b30}.fac-role-section{margin-top:10px;display:flex;flex-direction:column;gap:6px}.fac-role-list{margin-top:6px;max-height:220px;overflow-y:auto;border:1px solid var(--surface-border);border-radius:8px}.fac-role-item{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;font-size:13px}.fac-role-item:hover{background:var(--surface-hover)}.fac-role-item i{color:var(--text-color-secondary)}.fac-role-app{margin-inline-start:auto;font-size:11px;color:var(--text-color-secondary);text-transform:uppercase;letter-spacing:.5px}.fac-perm-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.fac-icon-btn{background:#ffffff0f;border:none;border-radius:6px;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:inherit;cursor:pointer;font-size:12px}.fac-icon-btn:hover{background:#ffffff24}.fac-icon-btn.danger:hover{background:#ff3b3033;color:#ff3b30}.fac-icon-btn:disabled{opacity:.4;cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1127
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: SharePanelComponent, isStandalone: true, selector: "fly-share-panel", inputs: { targetName: "targetName", titleKey: "titleKey", loadPermissions: "loadPermissions", searchUsers: "searchUsers", loadOuTree: "loadOuTree", loadChartOptions: "loadChartOptions", defaultChartSystemKey: "defaultChartSystemKey", defaultChartId: "defaultChartId", loadOuLabelMap: "loadOuLabelMap", grantToUser: "grantToUser", grantToOu: "grantToOu", updatePermission: "updatePermission", revokePermission: "revokePermission", showApplyToChildren: "showApplyToChildren", supportsDeny: "supportsDeny", permissionLevels: "permissionLevels", everyoneLabelKey: "everyoneLabelKey", loadRoleOus: "loadRoleOus" }, outputs: { close: "close" }, ngImport: i0, template: "<div class=\"fac-overlay\" (click)=\"close.emit()\">\r\n <div class=\"fac-panel\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"fac-header\">\r\n <h3>{{ titleKey | translate }}</h3>\r\n <span class=\"fac-target-name\">{{ targetName }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"fac-close\"\r\n (click)=\"close.emit()\"\r\n [attr.aria-label]=\"'files.share.close' | translate\">\r\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fac-add-section\">\r\n <div class=\"fac-search-row\">\r\n <input\r\n type=\"text\"\r\n class=\"fac-input\"\r\n [(ngModel)]=\"searchQuery\"\r\n (input)=\"onSearchInput()\"\r\n [placeholder]=\"'files.share.search_placeholder' | translate\"\r\n [attr.aria-label]=\"'files.share.search_users' | translate\"\r\n />\r\n <select class=\"fac-select\" [(ngModel)]=\"newLevel\">\r\n @for (opt of levelOptions; track opt.value) {\r\n <option [value]=\"opt.value\">{{ opt.labelKey | translate }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n @if (searchResults().length > 0) {\r\n <div class=\"fac-search-results\">\r\n @for (result of searchResults(); track result.id) {\r\n <div class=\"fac-search-item\" (click)=\"onGrantToUser(result)\">\r\n <i class=\"pi pi-user\" aria-hidden=\"true\"></i>\r\n <span>{{ result.firstName }} {{ result.lastName }}</span>\r\n <span class=\"fac-email\">{{ result.email }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (chartOptions().length > 0) {\r\n <div class=\"fac-chart-row\">\r\n <label for=\"fac-org-chart-select\" class=\"fac-section-label\">{{\r\n 'files.share.org_chart' | translate\r\n }}</label>\r\n <select\r\n id=\"fac-org-chart-select\"\r\n class=\"fac-select\"\r\n [ngModel]=\"selectedOrgChartId()\"\r\n (ngModelChange)=\"onOrgChartSelectChange($event)\">\r\n @for (opt of chartOptions(); track $index) {\r\n <option [ngValue]=\"opt.id\">{{ opt.name }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n\r\n @if (showOuPicker()) {\r\n <div class=\"fac-ou-section\">\r\n <div class=\"fac-section-label\">{{ 'files.share.share_with_ou' | translate }}</div>\r\n @for (ou of ouTree(); track ou.id) {\r\n <button\r\n type=\"button\"\r\n class=\"fac-ou-item\"\r\n [style.padding-inline-start.px]=\"ouIndentStartPx(ou)\"\r\n (click)=\"onGrantToOu(ou)\"\r\n [attr.aria-label]=\"('files.share.share_with_ou_named' | translate) + ' ' + ou.displayName\"\r\n >\r\n <i class=\"pi pi-sitemap\" aria-hidden=\"true\"></i>\r\n <span dir=\"auto\">{{ ou.displayName }}</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (loadRoleOus && roleOus().length > 0) {\r\n <div class=\"fac-role-section\">\r\n <div class=\"fac-section-label\">{{ 'files.share.share_with_role' | translate }}</div>\r\n <input\r\n type=\"text\"\r\n class=\"fac-input\"\r\n [(ngModel)]=\"roleSearchQuery\"\r\n [placeholder]=\"'files.share.role_search_placeholder' | translate\"\r\n [attr.aria-label]=\"'files.share.search_roles' | translate\"\r\n [hidden]=\"!showRolePicker()\" />\r\n @if (showRolePicker()) {\r\n <div class=\"fac-role-list\">\r\n @for (role of filteredRoles(); track role.ouId) {\r\n <button\r\n type=\"button\"\r\n class=\"fac-role-item\"\r\n (click)=\"onGrantToRole(role)\"\r\n [attr.aria-label]=\"('files.share.share_with_role_named' | translate) + ' ' + role.displayName\">\r\n <i class=\"pi pi-id-card\" aria-hidden=\"true\"></i>\r\n <span dir=\"auto\">{{ role.displayName }}</span>\r\n <span class=\"fac-role-app\">{{ role.appId }}</span>\r\n </button>\r\n }\r\n @if (filteredRoles().length === 0) {\r\n <div class=\"fac-empty\">{{ 'files.share.no_roles_match' | translate }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"fac-toggle-row\">\r\n <button type=\"button\" class=\"fac-link\" (click)=\"showOuPicker.set(!showOuPicker())\">\r\n {{ showOuPicker() ? ('files.share.hide_ous' | translate) : ('files.share.show_ous' | translate) }}\r\n </button>\r\n @if (loadRoleOus && roleOus().length > 0) {\r\n <button type=\"button\" class=\"fac-link\" (click)=\"showRolePicker.set(!showRolePicker())\">\r\n {{ showRolePicker() ? ('files.share.hide_roles' | translate) : ('files.share.show_roles' | translate) }}\r\n </button>\r\n }\r\n @if (showApplyToChildren) {\r\n <label class=\"fac-checkbox-label\">\r\n <input type=\"checkbox\" [(ngModel)]=\"applyToChildren\" />\r\n {{ 'files.share.apply_children' | translate }}\r\n </label>\r\n }\r\n @if (supportsDeny) {\r\n <label class=\"fac-checkbox-label fac-deny-toggle\"\r\n [title]=\"'files.share.deny_help' | translate\">\r\n <input type=\"checkbox\" [(ngModel)]=\"addAsDeny\" />\r\n <i class=\"pi pi-ban\" aria-hidden=\"true\"></i>\r\n {{ 'files.share.add_as_deny' | translate }}\r\n </label>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"fac-perms-section\">\r\n <div class=\"fac-section-label\">{{ 'files.share.current_permissions' | translate }}</div>\r\n @if (loading()) {\r\n <div class=\"fac-loading\"><i class=\"pi pi-spin pi-spinner\" aria-hidden=\"true\"></i></div>\r\n } @else if (permissions().length === 0) {\r\n <div class=\"fac-empty\">{{ 'files.share.no_permissions' | translate }}</div>\r\n } @else {\r\n @for (perm of permissions(); track perm.id) {\r\n <div class=\"fac-perm-row\" [class.fac-perm-row-deny]=\"perm.isDeny\">\r\n <div class=\"fac-perm-info\">\r\n <i [class]=\"getPermIcon(perm)\" aria-hidden=\"true\"></i>\r\n <span class=\"fac-perm-name\" dir=\"auto\">{{ getPermLabel(perm) }}</span>\r\n @if (perm.isDeny) {\r\n <span class=\"fac-badge deny\">{{ 'files.share.denied' | translate }}</span>\r\n }\r\n @if (perm.isInherited) {\r\n <span class=\"fac-badge inherited\">{{ 'files.share.inherited' | translate }}</span>\r\n }\r\n </div>\r\n <div class=\"fac-perm-actions\">\r\n @if (!perm.isDeny) {\r\n <select\r\n class=\"fac-select sm\"\r\n [ngModel]=\"perm.level\"\r\n (ngModelChange)=\"onUpdateLevel(perm, $event)\"\r\n [disabled]=\"perm.isInherited === true\"\r\n >\r\n @for (opt of levelOptions; track opt.value) {\r\n <option [value]=\"opt.value\">{{ opt.labelKey | translate }}</option>\r\n }\r\n </select>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"fac-icon-btn danger\"\r\n (click)=\"onRevokePermission(perm)\"\r\n [disabled]=\"perm.isInherited === true\"\r\n [title]=\"'files.share.revoke' | translate\"\r\n >\r\n <i class=\"pi pi-trash\" aria-hidden=\"true\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".fac-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:2000;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.fac-panel{background:var(--surface-card, #1e1e1e);border:1px solid var(--surface-border);border-radius:12px;width:600px;max-width:min(600px,96vw);max-height:85vh;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 16px 48px #0006}.fac-header{display:flex;align-items:center;gap:10px;padding:16px 20px;border-bottom:1px solid var(--surface-border)}.fac-header h3{margin:0;font-size:16px;font-weight:600}.fac-target-name{flex:1;font-size:13px;color:var(--text-color-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fac-close{background:none;border:none;color:var(--text-color-secondary);cursor:pointer;font-size:16px;padding:4px}.fac-close:hover{color:var(--text-color)}.fac-add-section{padding:16px 20px;border-bottom:1px solid var(--surface-border)}.fac-search-row{display:flex;gap:8px}.fac-chart-row{display:flex;flex-direction:column;gap:6px;margin-top:12px}.fac-chart-row .fac-select{width:100%}.fac-input{flex:1;background:#ffffff14;border:1px solid rgba(255,255,255,.15);border-radius:8px;padding:8px 12px;color:inherit;font-size:13px;outline:none}.fac-input:focus{border-color:var(--primary-color, #e8732a)}.fac-select{background:#ffffff14;border:1px solid rgba(255,255,255,.15);border-radius:8px;padding:8px 10px;color:inherit;font-size:13px;outline:none}.fac-select.sm{padding:4px 8px;font-size:12px}.fac-search-results{margin-top:8px;max-height:150px;overflow-y:auto;border:1px solid var(--surface-border);border-radius:8px}.fac-search-item{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;font-size:13px}.fac-search-item:hover{background:var(--surface-hover)}.fac-search-item i{color:var(--text-color-secondary)}.fac-email{color:var(--text-color-secondary);font-size:12px;margin-inline-start:auto}.fac-ou-section{margin-top:10px;max-height:220px;overflow-y:auto}.fac-ou-item{display:flex;align-items:center;gap:8px;padding:6px 12px;padding-inline-start:12px;cursor:pointer;font-size:13px;border-radius:6px}.fac-ou-item:hover{background:var(--surface-hover)}.fac-ou-item i{color:var(--text-color-secondary)}.fac-section-label{font-size:11px;font-weight:700;text-transform:uppercase;color:var(--text-color-secondary);letter-spacing:.5px;margin-bottom:8px}.fac-toggle-row{display:flex;align-items:center;justify-content:space-between;margin-top:10px}.fac-link{background:none;border:none;color:var(--primary-color, #e8732a);cursor:pointer;font-size:12px;padding:0}.fac-link:hover{text-decoration:underline}.fac-checkbox-label{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-color-secondary);cursor:pointer}.fac-checkbox-label input{accent-color:var(--primary-color, #e8732a)}.fac-perms-section{flex:1;overflow-y:auto;padding:16px 20px}.fac-loading,.fac-empty{text-align:center;padding:20px;color:var(--text-color-secondary);font-size:13px}.fac-perm-row{display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-bottom:1px solid rgba(255,255,255,.05);gap:8px}.fac-perm-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.fac-perm-info i{color:var(--text-color-secondary);flex-shrink:0}.fac-perm-name{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fac-badge{font-size:10px;padding:2px 6px;border-radius:8px;flex-shrink:0}.fac-badge.inherited{background:#ffffff1a;color:var(--text-color-secondary)}.fac-badge.deny{background:#ff3b302e;color:#ff3b30;text-transform:uppercase;font-weight:600;letter-spacing:.5px}.fac-perm-row-deny{background:#ff3b300f;border-inline-start:3px solid #ff3b30;padding-inline-start:8px;border-radius:6px}.fac-perm-row-deny .fac-perm-info i{color:#ff3b30}.fac-deny-toggle{color:#ff6b6b}.fac-deny-toggle i{color:#ff6b6b;font-size:11px;margin-inline-end:2px}.fac-deny-toggle input{accent-color:#ff3b30}.fac-role-section{margin-top:10px;display:flex;flex-direction:column;gap:6px}.fac-role-list{margin-top:6px;max-height:220px;overflow-y:auto;border:1px solid var(--surface-border);border-radius:8px}.fac-role-item{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;font-size:13px}.fac-role-item:hover{background:var(--surface-hover)}.fac-role-item i{color:var(--text-color-secondary)}.fac-role-app{margin-inline-start:auto;font-size:11px;color:var(--text-color-secondary);text-transform:uppercase;letter-spacing:.5px}.fac-perm-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.fac-icon-btn{background:#ffffff0f;border:none;border-radius:6px;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:inherit;cursor:pointer;font-size:12px}.fac-icon-btn:hover{background:#ffffff24}.fac-icon-btn.danger:hover{background:#ff3b3033;color:#ff3b30}.fac-icon-btn:disabled{opacity:.4;cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1084
1128
|
}
|
|
1085
1129
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SharePanelComponent, decorators: [{
|
|
1086
1130
|
type: Component,
|
|
@@ -1101,6 +1145,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
1101
1145
|
}], loadChartOptions: [{
|
|
1102
1146
|
type: Input,
|
|
1103
1147
|
args: [{ required: true }]
|
|
1148
|
+
}], defaultChartSystemKey: [{
|
|
1149
|
+
type: Input
|
|
1150
|
+
}], defaultChartId: [{
|
|
1151
|
+
type: Input
|
|
1104
1152
|
}], loadOuLabelMap: [{
|
|
1105
1153
|
type: Input,
|
|
1106
1154
|
args: [{ required: true }]
|
|
@@ -1175,6 +1223,25 @@ class AudienceBuilderComponent {
|
|
|
1175
1223
|
searchUsers;
|
|
1176
1224
|
loadOuTree;
|
|
1177
1225
|
loadChartOptions;
|
|
1226
|
+
/**
|
|
1227
|
+
* Initial chart selection for the OU picker. Resolution order:
|
|
1228
|
+
* <list type="number">
|
|
1229
|
+
* <item>If <see cref="defaultChartId"/> is explicitly provided (string or null), use it.</item>
|
|
1230
|
+
* <item>Else if <see cref="defaultChartSystemKey"/> is set, pick the first option whose
|
|
1231
|
+
* <c>systemKey</c> matches (e.g. <c>'apps'</c> → the platform Apps chart).</item>
|
|
1232
|
+
* <item>Else fall back to <c>options[0]?.id ?? null</c> (host-defined default order).</item>
|
|
1233
|
+
* </list>
|
|
1234
|
+
* Hosts that already know the tenant-scoped chart Guid use {@link defaultChartId};
|
|
1235
|
+
* hosts that only know the semantic kind (typically <c>'apps'</c>) use
|
|
1236
|
+
* {@link defaultChartSystemKey}.
|
|
1237
|
+
*/
|
|
1238
|
+
defaultChartSystemKey;
|
|
1239
|
+
/**
|
|
1240
|
+
* Hard-coded chart id to pre-select. Takes priority over {@link defaultChartSystemKey}.
|
|
1241
|
+
* Use <c>null</c> to force the default/official chart (id null) even when other charts
|
|
1242
|
+
* are listed first.
|
|
1243
|
+
*/
|
|
1244
|
+
defaultChartId;
|
|
1178
1245
|
/**
|
|
1179
1246
|
* Optional apps-chart role-OU index. When supplied, the picker exposes a "Roles" tab
|
|
1180
1247
|
* surfacing role chips; without it, that tab is hidden even if `'roles'` is in
|
|
@@ -1280,7 +1347,7 @@ class AudienceBuilderComponent {
|
|
|
1280
1347
|
.subscribe({
|
|
1281
1348
|
next: (opts) => {
|
|
1282
1349
|
this.chartOptions.set(opts);
|
|
1283
|
-
const initial = opts
|
|
1350
|
+
const initial = this.resolveInitialChartId(opts);
|
|
1284
1351
|
this.selectedChartId.set(initial);
|
|
1285
1352
|
this.selectedChartId$.next(initial);
|
|
1286
1353
|
},
|
|
@@ -1379,6 +1446,26 @@ class AudienceBuilderComponent {
|
|
|
1379
1446
|
const d = ou.depth ?? 0;
|
|
1380
1447
|
return 12 + d * 18;
|
|
1381
1448
|
}
|
|
1449
|
+
/**
|
|
1450
|
+
* Picks the chart id to seed the OU picker with. Honours explicit {@link defaultChartId}
|
|
1451
|
+
* first (even when null, since null is a valid id meaning "default chart"), then
|
|
1452
|
+
* {@link defaultChartSystemKey}, then falls back to host order. Lookup uses
|
|
1453
|
+
* <see cref="hasOwnProperty"/> on the input keys to distinguish "host did not set this
|
|
1454
|
+
* input" from "host set it to null" — Angular reflects an unset input as <c>undefined</c>.
|
|
1455
|
+
*/
|
|
1456
|
+
resolveInitialChartId(opts) {
|
|
1457
|
+
if (this.defaultChartId !== undefined) {
|
|
1458
|
+
const exists = opts.some((o) => o.id === this.defaultChartId);
|
|
1459
|
+
return exists ? this.defaultChartId : (opts[0]?.id ?? null);
|
|
1460
|
+
}
|
|
1461
|
+
const key = this.defaultChartSystemKey;
|
|
1462
|
+
if (key) {
|
|
1463
|
+
const match = opts.find((o) => o.systemKey === key);
|
|
1464
|
+
if (match)
|
|
1465
|
+
return match.id;
|
|
1466
|
+
}
|
|
1467
|
+
return opts[0]?.id ?? null;
|
|
1468
|
+
}
|
|
1382
1469
|
// ── App-everyone picker ──────────────────────────────────────────────────────
|
|
1383
1470
|
pickAppEveryone(appId) {
|
|
1384
1471
|
this.addToActiveBucket((existing) => this.upsertAppEveryoneTerm(existing, appId));
|
|
@@ -1676,7 +1763,7 @@ class AudienceBuilderComponent {
|
|
|
1676
1763
|
return this.validateFilter(candidate) === null;
|
|
1677
1764
|
}
|
|
1678
1765
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AudienceBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1679
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AudienceBuilderComponent, isStandalone: true, selector: "fly-audience-builder", inputs: { value: "value", showExcludes: "showExcludes", supportedKinds: "supportedKinds", selfUserId: "selfUserId", appEveryoneOptions: "appEveryoneOptions", searchUsers: "searchUsers", loadOuTree: "loadOuTree", loadChartOptions: "loadChartOptions", loadRoleOus: "loadRoleOus" }, outputs: { audienceChange: "audienceChange", validityChange: "validityChange" }, providers: [
|
|
1766
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AudienceBuilderComponent, isStandalone: true, selector: "fly-audience-builder", inputs: { value: "value", showExcludes: "showExcludes", supportedKinds: "supportedKinds", selfUserId: "selfUserId", appEveryoneOptions: "appEveryoneOptions", searchUsers: "searchUsers", loadOuTree: "loadOuTree", loadChartOptions: "loadChartOptions", defaultChartSystemKey: "defaultChartSystemKey", defaultChartId: "defaultChartId", loadRoleOus: "loadRoleOus" }, outputs: { audienceChange: "audienceChange", validityChange: "validityChange" }, providers: [
|
|
1680
1767
|
{
|
|
1681
1768
|
provide: NG_VALUE_ACCESSOR,
|
|
1682
1769
|
useExisting: forwardRef(() => AudienceBuilderComponent),
|
|
@@ -1722,6 +1809,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
1722
1809
|
}], loadChartOptions: [{
|
|
1723
1810
|
type: Input,
|
|
1724
1811
|
args: [{ required: true }]
|
|
1812
|
+
}], defaultChartSystemKey: [{
|
|
1813
|
+
type: Input
|
|
1814
|
+
}], defaultChartId: [{
|
|
1815
|
+
type: Input
|
|
1725
1816
|
}], loadRoleOus: [{
|
|
1726
1817
|
type: Input
|
|
1727
1818
|
}], audienceChange: [{
|
|
@@ -2429,6 +2520,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
2429
2520
|
* own preset pickers. `OuTerm.chartId` and `OuTerm.includeDescendants` are now
|
|
2430
2521
|
* REQUIRED (no longer optional) so wire round-trips are deterministic — emit explicit
|
|
2431
2522
|
* `null` / `boolean` rather than `undefined`. New `AudienceErrorCodes` mirror added.
|
|
2523
|
+
* v2.4.0: SharePanelComponent + AudienceBuilderComponent — `defaultChartSystemKey` and
|
|
2524
|
+
* `defaultChartId` inputs let hosts pre-select a specific chart in the OU picker
|
|
2525
|
+
* without knowing the tenant-scoped Guid. `ShareOrgChartOption` gains an optional
|
|
2526
|
+
* `systemKey` field so platform-managed charts (`'apps'`, `'default-company'`) are
|
|
2527
|
+
* identifiable across tenants. New `SHARE_ORG_CHART_SYSTEM_KEY_APPS` /
|
|
2528
|
+
* `SHARE_ORG_CHART_SYSTEM_KEY_DEFAULT` constants exported.
|
|
2432
2529
|
* See docs/ExternalAppsGuide/03-frontend-app.md.
|
|
2433
2530
|
*/
|
|
2434
2531
|
/**
|
|
@@ -2447,5 +2544,5 @@ const AUDIENCE_ERROR_CODES = {
|
|
|
2447
2544
|
* Generated bundle index. Do not edit.
|
|
2448
2545
|
*/
|
|
2449
2546
|
|
|
2450
|
-
export { AUDIENCE_ERROR_CODES, AUDIENCE_LIMITS, AUDIENCE_PRESETS, AUDIENCE_TERM_KINDS, AudienceBuilderComponent, AuthService, ContextMenuComponent, DEFAULT_FLY_THEME_MODE, DialogResult, FLY_THEME_MODE_IDS, FlyBlockUiComponent, FlyFileUploadComponent, FlyImageUploadComponent, FlyThemeService, I18nService, LAUNCH_CONTEXT, MessageBoxButtons, MessageBoxComponent, MessageBoxIcon, MessageBoxService, MockAuthService, RTL_LOCALE_SET, SHARE_PANEL_DEFAULT_FILE_LEVELS, SharePanelComponent, StandaloneWindowManagerService, TranslatePipe, WINDOW_DATA, WindowManagerService, isRtlLocale, normalizeFlyTheme };
|
|
2547
|
+
export { AUDIENCE_ERROR_CODES, AUDIENCE_LIMITS, AUDIENCE_PRESETS, AUDIENCE_TERM_KINDS, AudienceBuilderComponent, AuthService, ContextMenuComponent, DEFAULT_FLY_THEME_MODE, DialogResult, FLY_THEME_MODE_IDS, FlyBlockUiComponent, FlyFileUploadComponent, FlyImageUploadComponent, FlyThemeService, I18nService, LAUNCH_CONTEXT, MessageBoxButtons, MessageBoxComponent, MessageBoxIcon, MessageBoxService, MockAuthService, RTL_LOCALE_SET, SHARE_ORG_CHART_SYSTEM_KEY_APPS, SHARE_ORG_CHART_SYSTEM_KEY_DEFAULT, SHARE_PANEL_DEFAULT_FILE_LEVELS, SharePanelComponent, StandaloneWindowManagerService, TranslatePipe, WINDOW_DATA, WindowManagerService, isRtlLocale, normalizeFlyTheme };
|
|
2451
2548
|
//# sourceMappingURL=mohamedatia-fly-design-system.mjs.map
|