@memberjunction/ng-resource-permissions 5.42.0 → 5.44.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.
- package/dist/lib/resource-share-dialog.component.d.ts +2 -0
- package/dist/lib/resource-share-dialog.component.d.ts.map +1 -1
- package/dist/lib/resource-share-dialog.component.js +46 -51
- package/dist/lib/resource-share-dialog.component.js.map +1 -1
- package/dist/lib/user-sharing-center.component.d.ts +5 -1
- package/dist/lib/user-sharing-center.component.d.ts.map +1 -1
- package/dist/lib/user-sharing-center.component.js +130 -129
- package/dist/lib/user-sharing-center.component.js.map +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +10 -4
- package/dist/module.js.map +1 -1
- package/package.json +12 -10
- package/dist/__tests__/exports.test.d.ts +0 -2
- package/dist/__tests__/exports.test.d.ts.map +0 -1
- package/dist/__tests__/exports.test.js +0 -17
- package/dist/__tests__/exports.test.js.map +0 -1
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.js +0 -7
- package/dist/__tests__/index.test.js.map +0 -1
|
@@ -27,6 +27,8 @@ export declare class GenericShareDialogComponent implements OnChanges {
|
|
|
27
27
|
IsLoading: boolean;
|
|
28
28
|
Error: string | null;
|
|
29
29
|
UserSearchFilter: string;
|
|
30
|
+
/** Message for the no-results empty-state, echoing the current search term. */
|
|
31
|
+
get NoUsersFoundMessage(): string;
|
|
30
32
|
constructor(cdr: ChangeDetectorRef);
|
|
31
33
|
ngOnChanges(changes: SimpleChanges): void;
|
|
32
34
|
private resetDialog;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-share-dialog.component.d.ts","sourceRoot":"","sources":["../../src/lib/resource-share-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAqB,MAAM,eAAe,CAAC;AAEvI,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAEH,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,EAC/B,MAAM,0BAA0B,CAAC;;AAElC;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACtC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC7B;AAED;;;;;GAKG;AACH,qBAOa,2BAA4B,YAAW,SAAS;
|
|
1
|
+
{"version":3,"file":"resource-share-dialog.component.d.ts","sourceRoot":"","sources":["../../src/lib/resource-share-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAqB,MAAM,eAAe,CAAC;AAEvI,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAEH,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,EAC/B,MAAM,0BAA0B,CAAC;;AAElC;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACtC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC7B;AAED;;;;;GAKG;AACH,qBAOa,2BAA4B,YAAW,SAAS;IAqB7C,OAAO,CAAC,GAAG;IApBd,OAAO,UAAS;IAChB,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAQ;IAC5C,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAQ;IAC3C,MAAM,0CAAiD;IAEjE,SAAgB,MAAM,uBAAyB;IAExC,UAAU,EAAE,4BAA4B,EAAE,CAAM;IAChD,cAAc,EAAE,YAAY,EAAE,CAAM;IAC3C,OAAO,CAAC,QAAQ,CAAsB;IAE/B,SAAS,UAAS;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,gBAAgB,SAAM;IAE7B,+EAA+E;IAC/E,IAAW,mBAAmB,IAAI,MAAM,CAEvC;gBAEmB,GAAG,EAAE,iBAAiB;IAE1C,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAOzC,OAAO,CAAC,WAAW;YAQL,QAAQ;IA4BtB,OAAO,CAAC,oBAAoB;IAY5B,IAAW,sBAAsB,IAAI,YAAY,EAAE,CAQlD;IAED,IAAW,UAAU,IAAI,OAAO,CAI/B;IAED,IAAW,YAAY,IAAI,4BAA4B,EAAE,CAExD;IAED,IAAW,aAAa,IAAI,4BAA4B,EAAE,CAEzD;IAED,2EAA2E;IACpE,UAAU,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO;IAIlD,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD,eAAe,CAAC,KAAK,EAAE,4BAA4B,GAAG,IAAI;IAU1D,UAAU,CAAC,KAAK,EAAE,4BAA4B,GAAG,IAAI;IAMrD,QAAQ,CAAC,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAKxE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAmD7B,QAAQ,IAAI,IAAI;IAIhB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM;yCAjMzC,2BAA2B;2CAA3B,2BAA2B;CAyMvC"}
|
|
@@ -8,18 +8,16 @@ import * as i2 from "@memberjunction/ng-ui-components";
|
|
|
8
8
|
const _forTrack0 = ($index, $item) => $item.User.ID;
|
|
9
9
|
const _forTrack1 = ($index, $item) => $item.ID;
|
|
10
10
|
function GenericShareDialogComponent_Conditional_0_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
11
|
-
i0.ɵɵelementStart(0, "
|
|
12
|
-
i0.ɵɵ
|
|
13
|
-
i0.ɵɵ
|
|
14
|
-
i0.ɵɵtext(3);
|
|
15
|
-
i0.ɵɵelementEnd()();
|
|
11
|
+
i0.ɵɵelementStart(0, "mj-alert", 5);
|
|
12
|
+
i0.ɵɵtext(1);
|
|
13
|
+
i0.ɵɵelementEnd();
|
|
16
14
|
} if (rf & 2) {
|
|
17
15
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
18
|
-
i0.ɵɵadvance(
|
|
16
|
+
i0.ɵɵadvance();
|
|
19
17
|
i0.ɵɵtextInterpolate(ctx_r1.Error);
|
|
20
18
|
} }
|
|
21
19
|
function GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
22
|
-
i0.ɵɵelementStart(0, "span",
|
|
20
|
+
i0.ɵɵelementStart(0, "span", 26);
|
|
23
21
|
i0.ɵɵtext(1);
|
|
24
22
|
i0.ɵɵelementEnd();
|
|
25
23
|
} if (rf & 2) {
|
|
@@ -29,16 +27,16 @@ function GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Conditio
|
|
|
29
27
|
} }
|
|
30
28
|
function GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
31
29
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
32
|
-
i0.ɵɵelementStart(0, "button",
|
|
30
|
+
i0.ɵɵelementStart(0, "button", 23);
|
|
33
31
|
i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Template_button_click_0_listener() { const user_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.addUserShare(user_r4)); });
|
|
34
|
-
i0.ɵɵelementStart(1, "span",
|
|
32
|
+
i0.ɵɵelementStart(1, "span", 24);
|
|
35
33
|
i0.ɵɵtext(2);
|
|
36
34
|
i0.ɵɵelementEnd();
|
|
37
|
-
i0.ɵɵelementStart(3, "span",
|
|
35
|
+
i0.ɵɵelementStart(3, "span", 25);
|
|
38
36
|
i0.ɵɵtext(4);
|
|
39
37
|
i0.ɵɵelementEnd();
|
|
40
|
-
i0.ɵɵconditionalCreate(5, GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Conditional_5_Template, 2, 1, "span",
|
|
41
|
-
i0.ɵɵelement(6, "i",
|
|
38
|
+
i0.ɵɵconditionalCreate(5, GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Conditional_5_Template, 2, 1, "span", 26);
|
|
39
|
+
i0.ɵɵelement(6, "i", 27);
|
|
42
40
|
i0.ɵɵelementEnd();
|
|
43
41
|
} if (rf & 2) {
|
|
44
42
|
const user_r4 = ctx.$implicit;
|
|
@@ -53,7 +51,7 @@ function GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Template
|
|
|
53
51
|
} }
|
|
54
52
|
function GenericShareDialogComponent_Conditional_0_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
55
53
|
i0.ɵɵelementStart(0, "div", 10);
|
|
56
|
-
i0.ɵɵrepeaterCreate(1, GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Template, 7, 4, "button",
|
|
54
|
+
i0.ɵɵrepeaterCreate(1, GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Template, 7, 4, "button", 22, _forTrack1);
|
|
57
55
|
i0.ɵɵelementEnd();
|
|
58
56
|
} if (rf & 2) {
|
|
59
57
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -61,22 +59,19 @@ function GenericShareDialogComponent_Conditional_0_Conditional_12_Template(rf, c
|
|
|
61
59
|
i0.ɵɵrepeater(ctx_r1.FilteredAvailableUsers);
|
|
62
60
|
} }
|
|
63
61
|
function GenericShareDialogComponent_Conditional_0_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
64
|
-
i0.ɵɵ
|
|
65
|
-
i0.ɵɵtext(1);
|
|
66
|
-
i0.ɵɵelementEnd();
|
|
62
|
+
i0.ɵɵelement(0, "mj-empty-state", 11);
|
|
67
63
|
} if (rf & 2) {
|
|
68
64
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
69
|
-
i0.ɵɵ
|
|
70
|
-
i0.ɵɵtextInterpolate1(" No users found matching \"", ctx_r1.UserSearchFilter, "\" ");
|
|
65
|
+
i0.ɵɵproperty("Title", ctx_r1.NoUsersFoundMessage);
|
|
71
66
|
} }
|
|
72
67
|
function GenericShareDialogComponent_Conditional_0_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
73
|
-
i0.ɵɵelementStart(0, "div", 13)(1, "span",
|
|
74
|
-
i0.ɵɵelement(2, "i",
|
|
68
|
+
i0.ɵɵelementStart(0, "div", 13)(1, "span", 28);
|
|
69
|
+
i0.ɵɵelement(2, "i", 29);
|
|
75
70
|
i0.ɵɵelementEnd();
|
|
76
|
-
i0.ɵɵelementStart(3, "div",
|
|
71
|
+
i0.ɵɵelementStart(3, "div", 30)(4, "span", 31);
|
|
77
72
|
i0.ɵɵtext(5);
|
|
78
73
|
i0.ɵɵelementEnd();
|
|
79
|
-
i0.ɵɵelementStart(6, "span",
|
|
74
|
+
i0.ɵɵelementStart(6, "span", 32);
|
|
80
75
|
i0.ɵɵtext(7, "Owner");
|
|
81
76
|
i0.ɵɵelementEnd()()();
|
|
82
77
|
} if (rf & 2) {
|
|
@@ -85,12 +80,12 @@ function GenericShareDialogComponent_Conditional_0_Conditional_17_Template(rf, c
|
|
|
85
80
|
i0.ɵɵtextInterpolate(ctx_r1.Context == null ? null : ctx_r1.Context.OwnerDisplayName);
|
|
86
81
|
} }
|
|
87
82
|
function GenericShareDialogComponent_Conditional_0_For_19_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
88
|
-
i0.ɵɵelementStart(0, "span",
|
|
83
|
+
i0.ɵɵelementStart(0, "span", 34);
|
|
89
84
|
i0.ɵɵtext(1, "New");
|
|
90
85
|
i0.ɵɵelementEnd();
|
|
91
86
|
} }
|
|
92
87
|
function GenericShareDialogComponent_Conditional_0_For_19_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
93
|
-
i0.ɵɵelementStart(0, "span",
|
|
88
|
+
i0.ɵɵelementStart(0, "span", 35);
|
|
94
89
|
i0.ɵɵtext(1);
|
|
95
90
|
i0.ɵɵelementEnd();
|
|
96
91
|
} if (rf & 2) {
|
|
@@ -100,7 +95,7 @@ function GenericShareDialogComponent_Conditional_0_For_19_Conditional_7_Template
|
|
|
100
95
|
} }
|
|
101
96
|
function GenericShareDialogComponent_Conditional_0_For_19_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
102
97
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
103
|
-
i0.ɵɵelementStart(0, "button",
|
|
98
|
+
i0.ɵɵelementStart(0, "button", 40);
|
|
104
99
|
i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_For_19_For_10_Template_button_click_0_listener() { const level_r8 = i0.ɵɵrestoreView(_r7).$implicit; const share_r6 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.setLevel(share_r6, level_r8)); });
|
|
105
100
|
i0.ɵɵtext(1);
|
|
106
101
|
i0.ɵɵelementEnd();
|
|
@@ -114,21 +109,21 @@ function GenericShareDialogComponent_Conditional_0_For_19_For_10_Template(rf, ct
|
|
|
114
109
|
} }
|
|
115
110
|
function GenericShareDialogComponent_Conditional_0_For_19_Template(rf, ctx) { if (rf & 1) {
|
|
116
111
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
117
|
-
i0.ɵɵelementStart(0, "div",
|
|
112
|
+
i0.ɵɵelementStart(0, "div", 33)(1, "span", 24);
|
|
118
113
|
i0.ɵɵtext(2);
|
|
119
114
|
i0.ɵɵelementEnd();
|
|
120
|
-
i0.ɵɵelementStart(3, "div",
|
|
115
|
+
i0.ɵɵelementStart(3, "div", 30)(4, "span", 31);
|
|
121
116
|
i0.ɵɵtext(5);
|
|
122
|
-
i0.ɵɵconditionalCreate(6, GenericShareDialogComponent_Conditional_0_For_19_Conditional_6_Template, 2, 0, "span",
|
|
117
|
+
i0.ɵɵconditionalCreate(6, GenericShareDialogComponent_Conditional_0_For_19_Conditional_6_Template, 2, 0, "span", 34);
|
|
123
118
|
i0.ɵɵelementEnd();
|
|
124
|
-
i0.ɵɵconditionalCreate(7, GenericShareDialogComponent_Conditional_0_For_19_Conditional_7_Template, 2, 1, "span",
|
|
119
|
+
i0.ɵɵconditionalCreate(7, GenericShareDialogComponent_Conditional_0_For_19_Conditional_7_Template, 2, 1, "span", 35);
|
|
125
120
|
i0.ɵɵelementEnd();
|
|
126
|
-
i0.ɵɵelementStart(8, "div",
|
|
127
|
-
i0.ɵɵrepeaterCreate(9, GenericShareDialogComponent_Conditional_0_For_19_For_10_Template, 2, 4, "button",
|
|
121
|
+
i0.ɵɵelementStart(8, "div", 36);
|
|
122
|
+
i0.ɵɵrepeaterCreate(9, GenericShareDialogComponent_Conditional_0_For_19_For_10_Template, 2, 4, "button", 37, i0.ɵɵrepeaterTrackByIdentity);
|
|
128
123
|
i0.ɵɵelementEnd();
|
|
129
|
-
i0.ɵɵelementStart(11, "button",
|
|
124
|
+
i0.ɵɵelementStart(11, "button", 38);
|
|
130
125
|
i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_For_19_Template_button_click_11_listener() { const share_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.removeUserShare(share_r6)); });
|
|
131
|
-
i0.ɵɵelement(12, "i",
|
|
126
|
+
i0.ɵɵelement(12, "i", 39);
|
|
132
127
|
i0.ɵɵelementEnd()();
|
|
133
128
|
} if (rf & 2) {
|
|
134
129
|
const share_r6 = ctx.$implicit;
|
|
@@ -146,23 +141,19 @@ function GenericShareDialogComponent_Conditional_0_For_19_Template(rf, ctx) { if
|
|
|
146
141
|
i0.ɵɵrepeater(ctx_r1.Levels);
|
|
147
142
|
} }
|
|
148
143
|
function GenericShareDialogComponent_Conditional_0_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
149
|
-
i0.ɵɵ
|
|
150
|
-
i0.ɵɵelement(1, "i", 42);
|
|
151
|
-
i0.ɵɵelementStart(2, "span");
|
|
152
|
-
i0.ɵɵtext(3, "Not shared with anyone yet");
|
|
153
|
-
i0.ɵɵelementEnd()();
|
|
144
|
+
i0.ɵɵelement(0, "mj-empty-state", 15);
|
|
154
145
|
} }
|
|
155
146
|
function GenericShareDialogComponent_Conditional_0_Conditional_21_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
156
147
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
157
|
-
i0.ɵɵelementStart(0, "div",
|
|
148
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "span", 42);
|
|
158
149
|
i0.ɵɵtext(2);
|
|
159
150
|
i0.ɵɵelementEnd();
|
|
160
|
-
i0.ɵɵelementStart(3, "span",
|
|
151
|
+
i0.ɵɵelementStart(3, "span", 43);
|
|
161
152
|
i0.ɵɵtext(4);
|
|
162
153
|
i0.ɵɵelementEnd();
|
|
163
|
-
i0.ɵɵelementStart(5, "button",
|
|
154
|
+
i0.ɵɵelementStart(5, "button", 44);
|
|
164
155
|
i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_Conditional_21_For_2_Template_button_click_5_listener() { const share_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.undoRemove(share_r10)); });
|
|
165
|
-
i0.ɵɵelement(6, "i",
|
|
156
|
+
i0.ɵɵelement(6, "i", 45);
|
|
166
157
|
i0.ɵɵtext(7, " Undo ");
|
|
167
158
|
i0.ɵɵelementEnd()();
|
|
168
159
|
} if (rf & 2) {
|
|
@@ -175,7 +166,7 @@ function GenericShareDialogComponent_Conditional_0_Conditional_21_For_2_Template
|
|
|
175
166
|
} }
|
|
176
167
|
function GenericShareDialogComponent_Conditional_0_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
177
168
|
i0.ɵɵelementStart(0, "div", 16);
|
|
178
|
-
i0.ɵɵrepeaterCreate(1, GenericShareDialogComponent_Conditional_0_Conditional_21_For_2_Template, 8, 2, "div",
|
|
169
|
+
i0.ɵɵrepeaterCreate(1, GenericShareDialogComponent_Conditional_0_Conditional_21_For_2_Template, 8, 2, "div", 41, _forTrack0);
|
|
179
170
|
i0.ɵɵelementEnd();
|
|
180
171
|
} if (rf & 2) {
|
|
181
172
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -184,12 +175,12 @@ function GenericShareDialogComponent_Conditional_0_Conditional_21_Template(rf, c
|
|
|
184
175
|
} }
|
|
185
176
|
function GenericShareDialogComponent_Conditional_0_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
186
177
|
i0.ɵɵelementStart(0, "span", 18);
|
|
187
|
-
i0.ɵɵelement(1, "i",
|
|
178
|
+
i0.ɵɵelement(1, "i", 46);
|
|
188
179
|
i0.ɵɵtext(2, " Unsaved changes ");
|
|
189
180
|
i0.ɵɵelementEnd();
|
|
190
181
|
} }
|
|
191
182
|
function GenericShareDialogComponent_Conditional_0_Conditional_28_Template(rf, ctx) { if (rf & 1) {
|
|
192
|
-
i0.ɵɵelement(0, "i",
|
|
183
|
+
i0.ɵɵelement(0, "i", 47);
|
|
193
184
|
i0.ɵɵtext(1, " Saving... ");
|
|
194
185
|
} }
|
|
195
186
|
function GenericShareDialogComponent_Conditional_0_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -205,21 +196,21 @@ function GenericShareDialogComponent_Conditional_0_Template(rf, ctx) { if (rf &
|
|
|
205
196
|
i0.ɵɵtext(5);
|
|
206
197
|
i0.ɵɵelementEnd()()();
|
|
207
198
|
i0.ɵɵelementStart(6, "div", 4);
|
|
208
|
-
i0.ɵɵconditionalCreate(7, GenericShareDialogComponent_Conditional_0_Conditional_7_Template,
|
|
199
|
+
i0.ɵɵconditionalCreate(7, GenericShareDialogComponent_Conditional_0_Conditional_7_Template, 2, 1, "mj-alert", 5);
|
|
209
200
|
i0.ɵɵelementStart(8, "div", 6)(9, "div", 7);
|
|
210
201
|
i0.ɵɵelement(10, "i", 8);
|
|
211
202
|
i0.ɵɵelementStart(11, "input", 9);
|
|
212
203
|
i0.ɵɵtwoWayListener("ngModelChange", function GenericShareDialogComponent_Conditional_0_Template_input_ngModelChange_11_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.UserSearchFilter, $event) || (ctx_r1.UserSearchFilter = $event); return i0.ɵɵresetView($event); });
|
|
213
204
|
i0.ɵɵelementEnd()();
|
|
214
205
|
i0.ɵɵconditionalCreate(12, GenericShareDialogComponent_Conditional_0_Conditional_12_Template, 3, 0, "div", 10);
|
|
215
|
-
i0.ɵɵconditionalCreate(13, GenericShareDialogComponent_Conditional_0_Conditional_13_Template,
|
|
206
|
+
i0.ɵɵconditionalCreate(13, GenericShareDialogComponent_Conditional_0_Conditional_13_Template, 1, 1, "mj-empty-state", 11);
|
|
216
207
|
i0.ɵɵelementEnd();
|
|
217
208
|
i0.ɵɵelementStart(14, "div", 6)(15, "div", 12);
|
|
218
209
|
i0.ɵɵtext(16, "People with access");
|
|
219
210
|
i0.ɵɵelementEnd();
|
|
220
211
|
i0.ɵɵconditionalCreate(17, GenericShareDialogComponent_Conditional_0_Conditional_17_Template, 8, 1, "div", 13);
|
|
221
212
|
i0.ɵɵrepeaterCreate(18, GenericShareDialogComponent_Conditional_0_For_19_Template, 13, 8, "div", 14, _forTrack0);
|
|
222
|
-
i0.ɵɵconditionalCreate(20, GenericShareDialogComponent_Conditional_0_Conditional_20_Template,
|
|
213
|
+
i0.ɵɵconditionalCreate(20, GenericShareDialogComponent_Conditional_0_Conditional_20_Template, 1, 0, "mj-empty-state", 15);
|
|
223
214
|
i0.ɵɵconditionalCreate(21, GenericShareDialogComponent_Conditional_0_Conditional_21_Template, 3, 0, "div", 16);
|
|
224
215
|
i0.ɵɵelementEnd();
|
|
225
216
|
i0.ɵɵelementStart(22, "div", 17);
|
|
@@ -280,6 +271,10 @@ export class GenericShareDialogComponent {
|
|
|
280
271
|
IsLoading = false;
|
|
281
272
|
Error = null;
|
|
282
273
|
UserSearchFilter = '';
|
|
274
|
+
/** Message for the no-results empty-state, echoing the current search term. */
|
|
275
|
+
get NoUsersFoundMessage() {
|
|
276
|
+
return `No users found matching "${this.UserSearchFilter}"`;
|
|
277
|
+
}
|
|
283
278
|
constructor(cdr) {
|
|
284
279
|
this.cdr = cdr;
|
|
285
280
|
}
|
|
@@ -436,15 +431,15 @@ export class GenericShareDialogComponent {
|
|
|
436
431
|
return name.substring(0, 2).toUpperCase();
|
|
437
432
|
}
|
|
438
433
|
static ɵfac = function GenericShareDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || GenericShareDialogComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
439
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: GenericShareDialogComponent, selectors: [["mj-resource-share-dialog"]], inputs: { Visible: "Visible", Context: "Context", Adapter: "Adapter" }, outputs: { Result: "Result" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 1, vars: 1, consts: [[1, "mj-share-dialog-window", 3, "Visible", "Width", "MinHeight", "Resizable", "Draggable"], [1, "mj-share-dialog-window", 3, "Close", "Visible", "Width", "MinHeight", "Resizable", "Draggable"], [1, "share-dialog-header"], [1, "fa-solid", "fa-share-nodes"], [1, "share-dialog-body"], [
|
|
434
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: GenericShareDialogComponent, selectors: [["mj-resource-share-dialog"]], inputs: { Visible: "Visible", Context: "Context", Adapter: "Adapter" }, outputs: { Result: "Result" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 1, vars: 1, consts: [[1, "mj-share-dialog-window", 3, "Visible", "Width", "MinHeight", "Resizable", "Draggable"], [1, "mj-share-dialog-window", 3, "Close", "Visible", "Width", "MinHeight", "Resizable", "Draggable"], [1, "share-dialog-header"], [1, "fa-solid", "fa-share-nodes"], [1, "share-dialog-body"], ["Variant", "error"], [1, "share-section"], [1, "share-search-box"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Add people by name or email...", 3, "ngModelChange", "ngModel", "disabled"], [1, "share-user-dropdown"], ["Variant", "no-results", "Icon", "fa-solid fa-user-slash", "Size", "compact", 3, "Title"], [1, "share-section-label"], [1, "share-person", "share-owner"], [1, "share-person", 3, "share-person-new", "share-person-modified"], ["Icon", "fa-solid fa-user-lock", "Title", "Not shared with anyone yet", "Size", "compact"], [1, "share-removed-section"], [1, "share-footer"], [1, "share-changes-hint"], [1, "share-footer-actions"], ["type", "button", 1, "share-btn", "share-btn-secondary", 3, "click"], ["type", "button", 1, "share-btn", "share-btn-primary", 3, "click", "disabled"], ["type", "button", 1, "share-user-option", 3, "disabled"], ["type", "button", 1, "share-user-option", 3, "click", "disabled"], [1, "share-avatar"], [1, "share-user-name"], [1, "share-user-email"], [1, "fa-solid", "fa-plus"], [1, "share-avatar", "share-avatar-owner"], [1, "fa-solid", "fa-crown"], [1, "share-person-info"], [1, "share-person-name"], [1, "share-person-role"], [1, "share-person"], [1, "share-badge-new"], [1, "share-person-email"], ["role", "group", "aria-label", "Permission level", 1, "share-level-select"], ["type", "button", 1, "share-level-btn", 3, "active", "title"], ["type", "button", "title", "Remove", 1, "share-remove-btn", 3, "click"], [1, "fa-solid", "fa-times"], ["type", "button", 1, "share-level-btn", 3, "click", "title"], [1, "share-removed-item"], [1, "share-avatar", "share-avatar-removed"], [1, "share-removed-name"], ["type", "button", 1, "share-undo-btn", 3, "click"], [1, "fa-solid", "fa-undo"], [1, "fa-solid", "fa-circle"], [1, "fa-solid", "fa-spinner", "fa-spin"]], template: function GenericShareDialogComponent_Template(rf, ctx) { if (rf & 1) {
|
|
440
435
|
i0.ɵɵconditionalCreate(0, GenericShareDialogComponent_Conditional_0_Template, 30, 17, "mj-window", 0);
|
|
441
436
|
} if (rf & 2) {
|
|
442
437
|
i0.ɵɵconditional(ctx.Visible ? 0 : -1);
|
|
443
|
-
} }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJWindowComponent, i2.MJWindowTitlebarComponent], styles: ["/* Generic Resource Share Dialog - Compact Design */\n\n/* Window container \u2014 overrides the default `<mj-window>` surface styling with a\n * larger radius + accent shadow so the dialog reads as an \"action surface\". */\n.mj-share-dialog-window .mj-window {\n border-radius: 12px !important;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;\n overflow: hidden !important;\n}\n\n/* Branded titlebar: accent background so the header reads as chrome rather than\n * another surface panel. Text uses `--mj-text-inverse` because the background is\n * `--mj-brand-primary` \u2014 `--mj-text-inverse` is defined as \"legible on a\n * colored/dark accent\", not \"light mode-only white\". */\n.mj-share-dialog-window .mj-window-titlebar {\n background: var(--mj-brand-primary) !important;\n border: none !important;\n padding: 16px 20px !important;\n cursor: move;\n}\n\n/* The default title slot isn't rendered (we pass no `Title` input), but hide\n * it defensively in case a future refactor sets one \u2014 we already show our own\n * branded header via `<mj-window-titlebar>`. */\n.mj-share-dialog-window .mj-window-title {\n display: none !important;\n}\n\n/* Close button: tint against the accent titlebar to match the inverse text color. */\n.mj-share-dialog-window .mj-window-close {\n background: color-mix(in srgb, var(--mj-bg-surface) 15%, transparent) !important;\n border: none !important;\n color: var(--mj-text-inverse) !important;\n border-radius: 4px !important;\n}\n\n.mj-share-dialog-window .mj-window-close:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 25%, transparent) !important;\n color: var(--mj-text-inverse) !important;\n}\n\n.mj-share-dialog-window .mj-window-body {\n padding: 0 !important;\n background: var(--mj-bg-surface) !important;\n}\n\n/* Header */\n.share-dialog-header {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n font-weight: 500;\n}\n\n.share-dialog-header i {\n font-size: 18px;\n opacity: 0.9;\n}\n\n/* Body */\n.share-dialog-body {\n padding: 0;\n}\n\n/* Alert */\n.share-alert {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-size: 13px;\n}\n\n.share-alert-error {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n border-bottom: 1px solid var(--mj-border-error);\n}\n\n/* Sections */\n.share-section {\n padding: 16px 20px;\n}\n\n.share-section:not(:last-child) {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.share-section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n\n/* Search Box */\n.share-search-box {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid transparent;\n transition: all 0.15s;\n}\n\n.share-search-box:focus-within {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.share-search-box i {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.share-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n outline: none;\n}\n\n.share-search-box input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* User Dropdown */\n.share-user-dropdown {\n margin-top: 8px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n}\n\n/* User Option */\n.share-user-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.share-user-option:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.share-user-option:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-user-option .share-user-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-user-option .share-user-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-right: auto;\n}\n\n.share-user-option i.fa-plus {\n color: var(--mj-brand-primary);\n font-size: 12px;\n opacity: 0;\n transition: opacity 0.1s;\n}\n\n.share-user-option:hover i.fa-plus {\n opacity: 1;\n}\n\n.share-no-results {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n/* Avatar */\n.share-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.share-avatar-owner {\n background: var(--mj-status-warning);\n font-size: 14px;\n}\n\n.share-avatar-removed {\n background: var(--mj-border-strong);\n}\n\n/* Person Row */\n.share-person {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n\n.share-person:not(:last-child) {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.share-person-new {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-modified {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-info {\n flex: 1;\n min-width: 0;\n}\n\n.share-person-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-person-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.share-person-role {\n font-size: 12px;\n color: var(--mj-status-warning);\n font-weight: 500;\n}\n\n.share-badge-new {\n padding: 2px 6px;\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 4px;\n}\n\n/* Level selector (segmented control) */\n.share-level-select {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n}\n\n.share-level-btn {\n padding: 4px 12px;\n border: none;\n background: transparent;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.1s, color 0.1s;\n}\n\n.share-level-btn:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.share-level-btn:hover:not(.active) {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-primary);\n}\n\n.share-level-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n/* Legacy checkbox classes (kept but unused now). */\n.share-permissions {\n display: flex;\n gap: 4px;\n}\n\n.share-perm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.1s;\n position: relative;\n}\n\n.share-perm input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n}\n\n.share-perm i {\n font-size: 12px;\n color: var(--mj-border-strong);\n transition: color 0.1s;\n}\n\n.share-perm:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.share-perm input:checked + i {\n color: var(--mj-brand-primary);\n}\n\n.share-perm input:disabled + i {\n color: var(--mj-brand-primary);\n opacity: 0.7;\n}\n\n/* Remove Button */\n.share-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.1s;\n}\n\n.share-remove-btn:hover {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n}\n\n/* Empty State */\n.share-empty {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 20px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n justify-content: center;\n}\n\n.share-empty i {\n font-size: 16px;\n}\n\n/* Removed Section */\n.share-removed-section {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-warning);\n border-radius: 8px;\n border: 1px solid var(--mj-border-warning);\n}\n\n.share-removed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n}\n\n.share-removed-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n text-decoration: line-through;\n}\n\n.share-undo-btn {\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: var(--mj-status-warning);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.share-undo-btn:hover {\n text-decoration: underline;\n}\n\n/* Footer */\n.share-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.share-changes-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.share-changes-hint i {\n font-size: 6px;\n}\n\n.share-footer-actions {\n display: flex;\n gap: 10px;\n margin-left: auto;\n}\n\n.share-btn {\n padding: 8px 18px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.share-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.share-btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.share-btn-primary {\n background: var(--mj-brand-primary);\n border: none;\n color: var(--mj-text-inverse);\n}\n\n.share-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Owner row specific styling */\n.share-owner {\n background: var(--mj-bg-warning);\n margin: 0 -20px;\n padding: 10px 20px;\n border-radius: 0;\n}\n"], encapsulation: 2 });
|
|
438
|
+
} }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJEmptyStateComponent, i2.MJWindowComponent, i2.MJWindowTitlebarComponent, i2.MJAlertComponent], styles: ["/* Generic Resource Share Dialog - Compact Design */\n\n/* Window container \u2014 overrides the default `<mj-window>` surface styling with a\n * larger radius + accent shadow so the dialog reads as an \"action surface\". */\n.mj-share-dialog-window .mj-window {\n border-radius: 12px !important;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;\n overflow: hidden !important;\n}\n\n/* Branded titlebar: accent background so the header reads as chrome rather than\n * another surface panel. Text uses `--mj-text-inverse` because the background is\n * `--mj-brand-primary` \u2014 `--mj-text-inverse` is defined as \"legible on a\n * colored/dark accent\", not \"light mode-only white\". */\n.mj-share-dialog-window .mj-window-titlebar {\n background: var(--mj-brand-primary) !important;\n border: none !important;\n padding: 16px 20px !important;\n cursor: move;\n}\n\n/* The default title slot isn't rendered (we pass no `Title` input), but hide\n * it defensively in case a future refactor sets one \u2014 we already show our own\n * branded header via `<mj-window-titlebar>`. */\n.mj-share-dialog-window .mj-window-title {\n display: none !important;\n}\n\n/* Close button: tint against the accent titlebar to match the inverse text color. */\n.mj-share-dialog-window .mj-window-close {\n background: color-mix(in srgb, var(--mj-bg-surface) 15%, transparent) !important;\n border: none !important;\n color: var(--mj-text-inverse) !important;\n border-radius: 4px !important;\n}\n\n.mj-share-dialog-window .mj-window-close:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 25%, transparent) !important;\n color: var(--mj-text-inverse) !important;\n}\n\n.mj-share-dialog-window .mj-window-body {\n padding: 0 !important;\n background: var(--mj-bg-surface) !important;\n}\n\n/* Header */\n.share-dialog-header {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n font-weight: 500;\n}\n\n.share-dialog-header i {\n font-size: 18px;\n opacity: 0.9;\n}\n\n/* Body */\n.share-dialog-body {\n padding: 0;\n}\n\n/* Sections */\n.share-section {\n padding: 16px 20px;\n}\n\n.share-section:not(:last-child) {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.share-section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n\n/* Search Box */\n.share-search-box {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid transparent;\n transition: all 0.15s;\n}\n\n.share-search-box:focus-within {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.share-search-box i {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.share-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n outline: none;\n}\n\n.share-search-box input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* User Dropdown */\n.share-user-dropdown {\n margin-top: 8px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n}\n\n/* User Option */\n.share-user-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.share-user-option:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.share-user-option:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-user-option .share-user-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-user-option .share-user-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-right: auto;\n}\n\n.share-user-option i.fa-plus {\n color: var(--mj-brand-primary);\n font-size: 12px;\n opacity: 0;\n transition: opacity 0.1s;\n}\n\n.share-user-option:hover i.fa-plus {\n opacity: 1;\n}\n\n/* Avatar */\n.share-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.share-avatar-owner {\n background: var(--mj-status-warning);\n font-size: 14px;\n}\n\n.share-avatar-removed {\n background: var(--mj-border-strong);\n}\n\n/* Person Row */\n.share-person {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n\n.share-person:not(:last-child) {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.share-person-new {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-modified {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-info {\n flex: 1;\n min-width: 0;\n}\n\n.share-person-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-person-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.share-person-role {\n font-size: 12px;\n color: var(--mj-status-warning);\n font-weight: 500;\n}\n\n.share-badge-new {\n padding: 2px 6px;\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 4px;\n}\n\n/* Level selector (segmented control) */\n.share-level-select {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n}\n\n.share-level-btn {\n padding: 4px 12px;\n border: none;\n background: transparent;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.1s, color 0.1s;\n}\n\n.share-level-btn:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.share-level-btn:hover:not(.active) {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-primary);\n}\n\n.share-level-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n/* Legacy checkbox classes (kept but unused now). */\n.share-permissions {\n display: flex;\n gap: 4px;\n}\n\n.share-perm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.1s;\n position: relative;\n}\n\n.share-perm input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n}\n\n.share-perm i {\n font-size: 12px;\n color: var(--mj-border-strong);\n transition: color 0.1s;\n}\n\n.share-perm:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.share-perm input:checked + i {\n color: var(--mj-brand-primary);\n}\n\n.share-perm input:disabled + i {\n color: var(--mj-brand-primary);\n opacity: 0.7;\n}\n\n/* Remove Button */\n.share-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.1s;\n}\n\n.share-remove-btn:hover {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n}\n\n/* Removed Section */\n.share-removed-section {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-warning);\n border-radius: 8px;\n border: 1px solid var(--mj-border-warning);\n}\n\n.share-removed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n}\n\n.share-removed-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n text-decoration: line-through;\n}\n\n.share-undo-btn {\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: var(--mj-status-warning);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.share-undo-btn:hover {\n text-decoration: underline;\n}\n\n/* Footer */\n.share-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.share-changes-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.share-changes-hint i {\n font-size: 6px;\n}\n\n.share-footer-actions {\n display: flex;\n gap: 10px;\n margin-left: auto;\n}\n\n.share-btn {\n padding: 8px 18px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.share-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.share-btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.share-btn-primary {\n background: var(--mj-brand-primary);\n border: none;\n color: var(--mj-text-inverse);\n}\n\n.share-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Owner row specific styling */\n.share-owner {\n background: var(--mj-bg-warning);\n margin: 0 -20px;\n padding: 10px 20px;\n border-radius: 0;\n}\n"], encapsulation: 2 });
|
|
444
439
|
}
|
|
445
440
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(GenericShareDialogComponent, [{
|
|
446
441
|
type: Component,
|
|
447
|
-
args: [{ standalone: false, selector: 'mj-resource-share-dialog', encapsulation: ViewEncapsulation.None, template: "@if (Visible) {\n <mj-window\n [Visible]=\"true\"\n [Width]=\"560\"\n [MinHeight]=\"200\"\n [Resizable]=\"false\"\n [Draggable]=\"true\"\n (Close)=\"onCancel()\"\n class=\"mj-share-dialog-window\">\n <mj-window-titlebar>\n <div class=\"share-dialog-header\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Share \"{{ Context?.ResourceName }}\"</span>\n </div>\n </mj-window-titlebar>\n <div class=\"share-dialog-body\">\n @if (Error) {\n <div class=\"share-alert share-alert-error\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ Error }}</span>\n </div>\n }\n <!-- Add Users Section -->\n <div class=\"share-section\">\n <div class=\"share-search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Add people by name or email...\"\n [(ngModel)]=\"UserSearchFilter\"\n [disabled]=\"IsLoading\">\n </div>\n @if (FilteredAvailableUsers.length > 0) {\n <div class=\"share-user-dropdown\">\n @for (user of FilteredAvailableUsers; track user.ID) {\n <button type=\"button\" class=\"share-user-option\" (click)=\"addUserShare(user)\" [disabled]=\"IsLoading\">\n <span class=\"share-avatar\">{{ getUserInitials(user) }}</span>\n <span class=\"share-user-name\">{{ user.Name }}</span>\n @if (user.Email) {\n <span class=\"share-user-email\">{{ user.Email }}</span>\n }\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n </div>\n }\n @if (UserSearchFilter && FilteredAvailableUsers.length === 0) {\n <div class=\"share-no-results\">\n No users found matching \"{{ UserSearchFilter }}\"\n </div>\n }\n </div>\n <!-- People with Access -->\n <div class=\"share-section\">\n <div class=\"share-section-label\">People with access</div>\n @if (Context?.OwnerDisplayName) {\n <div class=\"share-person share-owner\">\n <span class=\"share-avatar share-avatar-owner\">\n <i class=\"fa-solid fa-crown\"></i>\n </span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">{{ Context?.OwnerDisplayName }}</span>\n <span class=\"share-person-role\">Owner</span>\n </div>\n </div>\n }\n @for (share of ActiveShares; track share.User.ID) {\n <div class=\"share-person\" [class.share-person-new]=\"share.IsNew\" [class.share-person-modified]=\"isModified(share)\">\n <span class=\"share-avatar\">{{ getUserInitials(share.User) }}</span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">\n {{ share.User.Name }}\n @if (share.IsNew) {\n <span class=\"share-badge-new\">New</span>\n }\n </span>\n @if (share.User.Email) {\n <span class=\"share-person-email\">{{ share.User.Email }}</span>\n }\n </div>\n <div class=\"share-level-select\" role=\"group\" aria-label=\"Permission level\">\n @for (level of Levels; track level) {\n <button type=\"button\"\n class=\"share-level-btn\"\n [class.active]=\"share.Level === level\"\n (click)=\"setLevel(share, level)\"\n [title]=\"level + ' access'\">\n {{ level }}\n </button>\n }\n </div>\n <button type=\"button\" class=\"share-remove-btn\" (click)=\"removeUserShare(share)\" title=\"Remove\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n @if (ActiveShares.length === 0) {\n <div class=\"share-empty\">\n <i class=\"fa-solid fa-user-lock\"></i>\n <span>Not shared with anyone yet</span>\n </div>\n }\n @if (RemovedShares.length > 0) {\n <div class=\"share-removed-section\">\n @for (share of RemovedShares; track share.User.ID) {\n <div class=\"share-removed-item\">\n <span class=\"share-avatar share-avatar-removed\">{{ getUserInitials(share.User) }}</span>\n <span class=\"share-removed-name\">{{ share.User.Name }}</span>\n <button type=\"button\" class=\"share-undo-btn\" (click)=\"undoRemove(share)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"share-footer\">\n @if (HasChanges) {\n <span class=\"share-changes-hint\">\n <i class=\"fa-solid fa-circle\"></i> Unsaved changes\n </span>\n }\n <div class=\"share-footer-actions\">\n <button type=\"button\" class=\"share-btn share-btn-secondary\" (click)=\"onCancel()\">\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"share-btn share-btn-primary\"\n (click)=\"onSave()\"\n [disabled]=\"!HasChanges || IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n Save\n }\n </button>\n </div>\n </div>\n </div>\n </mj-window>\n}\n", styles: ["/* Generic Resource Share Dialog - Compact Design */\n\n/* Window container \u2014 overrides the default `<mj-window>` surface styling with a\n * larger radius + accent shadow so the dialog reads as an \"action surface\". */\n.mj-share-dialog-window .mj-window {\n border-radius: 12px !important;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;\n overflow: hidden !important;\n}\n\n/* Branded titlebar: accent background so the header reads as chrome rather than\n * another surface panel. Text uses `--mj-text-inverse` because the background is\n * `--mj-brand-primary` \u2014 `--mj-text-inverse` is defined as \"legible on a\n * colored/dark accent\", not \"light mode-only white\". */\n.mj-share-dialog-window .mj-window-titlebar {\n background: var(--mj-brand-primary) !important;\n border: none !important;\n padding: 16px 20px !important;\n cursor: move;\n}\n\n/* The default title slot isn't rendered (we pass no `Title` input), but hide\n * it defensively in case a future refactor sets one \u2014 we already show our own\n * branded header via `<mj-window-titlebar>`. */\n.mj-share-dialog-window .mj-window-title {\n display: none !important;\n}\n\n/* Close button: tint against the accent titlebar to match the inverse text color. */\n.mj-share-dialog-window .mj-window-close {\n background: color-mix(in srgb, var(--mj-bg-surface) 15%, transparent) !important;\n border: none !important;\n color: var(--mj-text-inverse) !important;\n border-radius: 4px !important;\n}\n\n.mj-share-dialog-window .mj-window-close:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 25%, transparent) !important;\n color: var(--mj-text-inverse) !important;\n}\n\n.mj-share-dialog-window .mj-window-body {\n padding: 0 !important;\n background: var(--mj-bg-surface) !important;\n}\n\n/* Header */\n.share-dialog-header {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n font-weight: 500;\n}\n\n.share-dialog-header i {\n font-size: 18px;\n opacity: 0.9;\n}\n\n/* Body */\n.share-dialog-body {\n padding: 0;\n}\n\n/* Alert */\n.share-alert {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-size: 13px;\n}\n\n.share-alert-error {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n border-bottom: 1px solid var(--mj-border-error);\n}\n\n/* Sections */\n.share-section {\n padding: 16px 20px;\n}\n\n.share-section:not(:last-child) {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.share-section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n\n/* Search Box */\n.share-search-box {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid transparent;\n transition: all 0.15s;\n}\n\n.share-search-box:focus-within {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.share-search-box i {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.share-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n outline: none;\n}\n\n.share-search-box input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* User Dropdown */\n.share-user-dropdown {\n margin-top: 8px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n}\n\n/* User Option */\n.share-user-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.share-user-option:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.share-user-option:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-user-option .share-user-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-user-option .share-user-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-right: auto;\n}\n\n.share-user-option i.fa-plus {\n color: var(--mj-brand-primary);\n font-size: 12px;\n opacity: 0;\n transition: opacity 0.1s;\n}\n\n.share-user-option:hover i.fa-plus {\n opacity: 1;\n}\n\n.share-no-results {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n/* Avatar */\n.share-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.share-avatar-owner {\n background: var(--mj-status-warning);\n font-size: 14px;\n}\n\n.share-avatar-removed {\n background: var(--mj-border-strong);\n}\n\n/* Person Row */\n.share-person {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n\n.share-person:not(:last-child) {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.share-person-new {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-modified {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-info {\n flex: 1;\n min-width: 0;\n}\n\n.share-person-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-person-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.share-person-role {\n font-size: 12px;\n color: var(--mj-status-warning);\n font-weight: 500;\n}\n\n.share-badge-new {\n padding: 2px 6px;\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 4px;\n}\n\n/* Level selector (segmented control) */\n.share-level-select {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n}\n\n.share-level-btn {\n padding: 4px 12px;\n border: none;\n background: transparent;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.1s, color 0.1s;\n}\n\n.share-level-btn:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.share-level-btn:hover:not(.active) {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-primary);\n}\n\n.share-level-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n/* Legacy checkbox classes (kept but unused now). */\n.share-permissions {\n display: flex;\n gap: 4px;\n}\n\n.share-perm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.1s;\n position: relative;\n}\n\n.share-perm input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n}\n\n.share-perm i {\n font-size: 12px;\n color: var(--mj-border-strong);\n transition: color 0.1s;\n}\n\n.share-perm:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.share-perm input:checked + i {\n color: var(--mj-brand-primary);\n}\n\n.share-perm input:disabled + i {\n color: var(--mj-brand-primary);\n opacity: 0.7;\n}\n\n/* Remove Button */\n.share-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.1s;\n}\n\n.share-remove-btn:hover {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n}\n\n/* Empty State */\n.share-empty {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 20px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n justify-content: center;\n}\n\n.share-empty i {\n font-size: 16px;\n}\n\n/* Removed Section */\n.share-removed-section {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-warning);\n border-radius: 8px;\n border: 1px solid var(--mj-border-warning);\n}\n\n.share-removed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n}\n\n.share-removed-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n text-decoration: line-through;\n}\n\n.share-undo-btn {\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: var(--mj-status-warning);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.share-undo-btn:hover {\n text-decoration: underline;\n}\n\n/* Footer */\n.share-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.share-changes-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.share-changes-hint i {\n font-size: 6px;\n}\n\n.share-footer-actions {\n display: flex;\n gap: 10px;\n margin-left: auto;\n}\n\n.share-btn {\n padding: 8px 18px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.share-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.share-btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.share-btn-primary {\n background: var(--mj-brand-primary);\n border: none;\n color: var(--mj-text-inverse);\n}\n\n.share-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Owner row specific styling */\n.share-owner {\n background: var(--mj-bg-warning);\n margin: 0 -20px;\n padding: 10px 20px;\n border-radius: 0;\n}\n"] }]
|
|
442
|
+
args: [{ standalone: false, selector: 'mj-resource-share-dialog', encapsulation: ViewEncapsulation.None, template: "@if (Visible) {\n <mj-window\n [Visible]=\"true\"\n [Width]=\"560\"\n [MinHeight]=\"200\"\n [Resizable]=\"false\"\n [Draggable]=\"true\"\n (Close)=\"onCancel()\"\n class=\"mj-share-dialog-window\">\n <mj-window-titlebar>\n <div class=\"share-dialog-header\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Share \"{{ Context?.ResourceName }}\"</span>\n </div>\n </mj-window-titlebar>\n <div class=\"share-dialog-body\">\n @if (Error) {\n <mj-alert Variant=\"error\">{{ Error }}</mj-alert>\n }\n <!-- Add Users Section -->\n <div class=\"share-section\">\n <div class=\"share-search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Add people by name or email...\"\n [(ngModel)]=\"UserSearchFilter\"\n [disabled]=\"IsLoading\">\n </div>\n @if (FilteredAvailableUsers.length > 0) {\n <div class=\"share-user-dropdown\">\n @for (user of FilteredAvailableUsers; track user.ID) {\n <button type=\"button\" class=\"share-user-option\" (click)=\"addUserShare(user)\" [disabled]=\"IsLoading\">\n <span class=\"share-avatar\">{{ getUserInitials(user) }}</span>\n <span class=\"share-user-name\">{{ user.Name }}</span>\n @if (user.Email) {\n <span class=\"share-user-email\">{{ user.Email }}</span>\n }\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n </div>\n }\n @if (UserSearchFilter && FilteredAvailableUsers.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-user-slash\"\n [Title]=\"NoUsersFoundMessage\"\n Size=\"compact\" />\n }\n </div>\n <!-- People with Access -->\n <div class=\"share-section\">\n <div class=\"share-section-label\">People with access</div>\n @if (Context?.OwnerDisplayName) {\n <div class=\"share-person share-owner\">\n <span class=\"share-avatar share-avatar-owner\">\n <i class=\"fa-solid fa-crown\"></i>\n </span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">{{ Context?.OwnerDisplayName }}</span>\n <span class=\"share-person-role\">Owner</span>\n </div>\n </div>\n }\n @for (share of ActiveShares; track share.User.ID) {\n <div class=\"share-person\" [class.share-person-new]=\"share.IsNew\" [class.share-person-modified]=\"isModified(share)\">\n <span class=\"share-avatar\">{{ getUserInitials(share.User) }}</span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">\n {{ share.User.Name }}\n @if (share.IsNew) {\n <span class=\"share-badge-new\">New</span>\n }\n </span>\n @if (share.User.Email) {\n <span class=\"share-person-email\">{{ share.User.Email }}</span>\n }\n </div>\n <div class=\"share-level-select\" role=\"group\" aria-label=\"Permission level\">\n @for (level of Levels; track level) {\n <button type=\"button\"\n class=\"share-level-btn\"\n [class.active]=\"share.Level === level\"\n (click)=\"setLevel(share, level)\"\n [title]=\"level + ' access'\">\n {{ level }}\n </button>\n }\n </div>\n <button type=\"button\" class=\"share-remove-btn\" (click)=\"removeUserShare(share)\" title=\"Remove\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n @if (ActiveShares.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-user-lock\"\n Title=\"Not shared with anyone yet\"\n Size=\"compact\" />\n }\n @if (RemovedShares.length > 0) {\n <div class=\"share-removed-section\">\n @for (share of RemovedShares; track share.User.ID) {\n <div class=\"share-removed-item\">\n <span class=\"share-avatar share-avatar-removed\">{{ getUserInitials(share.User) }}</span>\n <span class=\"share-removed-name\">{{ share.User.Name }}</span>\n <button type=\"button\" class=\"share-undo-btn\" (click)=\"undoRemove(share)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"share-footer\">\n @if (HasChanges) {\n <span class=\"share-changes-hint\">\n <i class=\"fa-solid fa-circle\"></i> Unsaved changes\n </span>\n }\n <div class=\"share-footer-actions\">\n <button type=\"button\" class=\"share-btn share-btn-secondary\" (click)=\"onCancel()\">\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"share-btn share-btn-primary\"\n (click)=\"onSave()\"\n [disabled]=\"!HasChanges || IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n Save\n }\n </button>\n </div>\n </div>\n </div>\n </mj-window>\n}\n", styles: ["/* Generic Resource Share Dialog - Compact Design */\n\n/* Window container \u2014 overrides the default `<mj-window>` surface styling with a\n * larger radius + accent shadow so the dialog reads as an \"action surface\". */\n.mj-share-dialog-window .mj-window {\n border-radius: 12px !important;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;\n overflow: hidden !important;\n}\n\n/* Branded titlebar: accent background so the header reads as chrome rather than\n * another surface panel. Text uses `--mj-text-inverse` because the background is\n * `--mj-brand-primary` \u2014 `--mj-text-inverse` is defined as \"legible on a\n * colored/dark accent\", not \"light mode-only white\". */\n.mj-share-dialog-window .mj-window-titlebar {\n background: var(--mj-brand-primary) !important;\n border: none !important;\n padding: 16px 20px !important;\n cursor: move;\n}\n\n/* The default title slot isn't rendered (we pass no `Title` input), but hide\n * it defensively in case a future refactor sets one \u2014 we already show our own\n * branded header via `<mj-window-titlebar>`. */\n.mj-share-dialog-window .mj-window-title {\n display: none !important;\n}\n\n/* Close button: tint against the accent titlebar to match the inverse text color. */\n.mj-share-dialog-window .mj-window-close {\n background: color-mix(in srgb, var(--mj-bg-surface) 15%, transparent) !important;\n border: none !important;\n color: var(--mj-text-inverse) !important;\n border-radius: 4px !important;\n}\n\n.mj-share-dialog-window .mj-window-close:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 25%, transparent) !important;\n color: var(--mj-text-inverse) !important;\n}\n\n.mj-share-dialog-window .mj-window-body {\n padding: 0 !important;\n background: var(--mj-bg-surface) !important;\n}\n\n/* Header */\n.share-dialog-header {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n font-weight: 500;\n}\n\n.share-dialog-header i {\n font-size: 18px;\n opacity: 0.9;\n}\n\n/* Body */\n.share-dialog-body {\n padding: 0;\n}\n\n/* Sections */\n.share-section {\n padding: 16px 20px;\n}\n\n.share-section:not(:last-child) {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.share-section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n\n/* Search Box */\n.share-search-box {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid transparent;\n transition: all 0.15s;\n}\n\n.share-search-box:focus-within {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.share-search-box i {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.share-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n outline: none;\n}\n\n.share-search-box input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* User Dropdown */\n.share-user-dropdown {\n margin-top: 8px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n}\n\n/* User Option */\n.share-user-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.share-user-option:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.share-user-option:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-user-option .share-user-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-user-option .share-user-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-right: auto;\n}\n\n.share-user-option i.fa-plus {\n color: var(--mj-brand-primary);\n font-size: 12px;\n opacity: 0;\n transition: opacity 0.1s;\n}\n\n.share-user-option:hover i.fa-plus {\n opacity: 1;\n}\n\n/* Avatar */\n.share-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.share-avatar-owner {\n background: var(--mj-status-warning);\n font-size: 14px;\n}\n\n.share-avatar-removed {\n background: var(--mj-border-strong);\n}\n\n/* Person Row */\n.share-person {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n\n.share-person:not(:last-child) {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.share-person-new {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-modified {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-info {\n flex: 1;\n min-width: 0;\n}\n\n.share-person-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-person-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.share-person-role {\n font-size: 12px;\n color: var(--mj-status-warning);\n font-weight: 500;\n}\n\n.share-badge-new {\n padding: 2px 6px;\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 4px;\n}\n\n/* Level selector (segmented control) */\n.share-level-select {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n}\n\n.share-level-btn {\n padding: 4px 12px;\n border: none;\n background: transparent;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.1s, color 0.1s;\n}\n\n.share-level-btn:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.share-level-btn:hover:not(.active) {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-primary);\n}\n\n.share-level-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n/* Legacy checkbox classes (kept but unused now). */\n.share-permissions {\n display: flex;\n gap: 4px;\n}\n\n.share-perm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.1s;\n position: relative;\n}\n\n.share-perm input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n}\n\n.share-perm i {\n font-size: 12px;\n color: var(--mj-border-strong);\n transition: color 0.1s;\n}\n\n.share-perm:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.share-perm input:checked + i {\n color: var(--mj-brand-primary);\n}\n\n.share-perm input:disabled + i {\n color: var(--mj-brand-primary);\n opacity: 0.7;\n}\n\n/* Remove Button */\n.share-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.1s;\n}\n\n.share-remove-btn:hover {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n}\n\n/* Removed Section */\n.share-removed-section {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-warning);\n border-radius: 8px;\n border: 1px solid var(--mj-border-warning);\n}\n\n.share-removed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n}\n\n.share-removed-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n text-decoration: line-through;\n}\n\n.share-undo-btn {\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: var(--mj-status-warning);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.share-undo-btn:hover {\n text-decoration: underline;\n}\n\n/* Footer */\n.share-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.share-changes-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.share-changes-hint i {\n font-size: 6px;\n}\n\n.share-footer-actions {\n display: flex;\n gap: 10px;\n margin-left: auto;\n}\n\n.share-btn {\n padding: 8px 18px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.share-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.share-btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.share-btn-primary {\n background: var(--mj-brand-primary);\n border: none;\n color: var(--mj-text-inverse);\n}\n\n.share-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Owner row specific styling */\n.share-owner {\n background: var(--mj-bg-warning);\n margin: 0 -20px;\n padding: 10px 20px;\n border-radius: 0;\n}\n"] }]
|
|
448
443
|
}], () => [{ type: i0.ChangeDetectorRef }], { Visible: [{
|
|
449
444
|
type: Input
|
|
450
445
|
}], Context: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-share-dialog.component.js","sourceRoot":"","sources":["../../src/lib/resource-share-dialog.component.ts","../../src/lib/resource-share-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ChangeDetectorRef, ViewEncapsulation } from '@angular/core';\nimport { RunView } from '@memberjunction/core';\nimport { MJUserEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport {\n RESOURCE_SHARE_LEVELS,\n ResourceShareAdapter,\n ResourceShareContext,\n ResourceShareLevel,\n ResourceSharePermissionModel\n} from './resource-share-adapter';\n\n/**\n * Result emitted when {@link GenericShareDialogComponent} closes.\n */\nexport interface ResourceShareDialogResult {\n Action: 'save' | 'cancel';\n}\n\n/**\n * Resource-type-agnostic share dialog. Every resource's sharing UX collapses to\n * three tiers — View / Edit / Owner — so the dialog exposes a single level\n * selector per grantee rather than a grab bag of `Can*` checkboxes. Adapters\n * translate the level to whatever shape their backing entity actually persists.\n */\n@Component({\n standalone: false,\n selector: 'mj-resource-share-dialog',\n templateUrl: './resource-share-dialog.component.html',\n styleUrls: ['./resource-share-dialog.component.css'],\n encapsulation: ViewEncapsulation.None\n})\nexport class GenericShareDialogComponent implements OnChanges {\n @Input() Visible = false;\n @Input() Context: ResourceShareContext | null = null;\n @Input() Adapter: ResourceShareAdapter | null = null;\n @Output() Result = new EventEmitter<ResourceShareDialogResult>();\n\n public readonly Levels = RESOURCE_SHARE_LEVELS;\n\n public UserShares: ResourceSharePermissionModel[] = [];\n public AvailableUsers: MJUserEntity[] = [];\n private allUsers: MJUserEntity[] = [];\n\n public IsLoading = false;\n public Error: string | null = null;\n public UserSearchFilter = '';\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['Visible'] && this.Visible && this.Context && this.Adapter) {\n this.resetDialog();\n this.loadData();\n }\n }\n\n private resetDialog(): void {\n this.Error = null;\n this.IsLoading = false;\n this.UserShares = [];\n this.AvailableUsers = [];\n this.UserSearchFilter = '';\n }\n\n private async loadData(): Promise<void> {\n if (!this.Context || !this.Adapter) return;\n\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n const rv = new RunView();\n const usersResult = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: 'IsActive = 1',\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n this.allUsers = usersResult.Success ? usersResult.Results : [];\n\n this.UserShares = await this.Adapter.LoadShares(this.Context);\n this.UserShares.forEach((s) => (s._InitialLevel = s.Level));\n this.updateAvailableUsers();\n } catch (error) {\n console.error('Error loading share data:', error);\n this.Error = 'Failed to load sharing data. Please try again.';\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private updateAvailableUsers(): void {\n if (!this.Context) return;\n const sharedUserIds = new Set(\n this.UserShares.filter((s) => !s.MarkedForRemoval).map((s) => s.User.ID)\n );\n const ownerId = this.Context.OwnerUserID;\n this.AvailableUsers = this.allUsers.filter((user) => {\n if (ownerId && UUIDsEqual(user.ID, ownerId)) return false;\n return !sharedUserIds.has(user.ID);\n });\n }\n\n public get FilteredAvailableUsers(): MJUserEntity[] {\n if (!this.UserSearchFilter.trim()) {\n return this.AvailableUsers.slice(0, 10);\n }\n const filter = this.UserSearchFilter.toLowerCase();\n return this.AvailableUsers\n .filter((u) => u.Name.toLowerCase().includes(filter) || (u.Email && u.Email.toLowerCase().includes(filter)))\n .slice(0, 10);\n }\n\n public get HasChanges(): boolean {\n return this.UserShares.some(\n (s) => s.IsNew || s.MarkedForRemoval || s.Level !== s._InitialLevel\n );\n }\n\n public get ActiveShares(): ResourceSharePermissionModel[] {\n return this.UserShares.filter((s) => !s.MarkedForRemoval);\n }\n\n public get RemovedShares(): ResourceSharePermissionModel[] {\n return this.UserShares.filter((s) => s.MarkedForRemoval);\n }\n\n /** Highlight rows whose level has been changed from their loaded state. */\n public isModified(share: ResourceSharePermissionModel): boolean {\n return !share.IsNew && share.Level !== share._InitialLevel;\n }\n\n public async addUserShare(user: MJUserEntity): Promise<void> {\n if (!this.Context || !this.Adapter) return;\n const row = await this.Adapter.CreateShare(this.Context, user);\n row._InitialLevel = row.Level;\n this.UserShares.push(row);\n this.updateAvailableUsers();\n this.UserSearchFilter = '';\n this.cdr.detectChanges();\n }\n\n public removeUserShare(share: ResourceSharePermissionModel): void {\n if (share.IsNew) {\n this.UserShares = this.UserShares.filter((s) => s !== share);\n } else {\n share.MarkedForRemoval = true;\n }\n this.updateAvailableUsers();\n this.cdr.detectChanges();\n }\n\n public undoRemove(share: ResourceSharePermissionModel): void {\n share.MarkedForRemoval = false;\n this.updateAvailableUsers();\n this.cdr.detectChanges();\n }\n\n public setLevel(share: ResourceSharePermissionModel, level: ResourceShareLevel): void {\n share.Level = level;\n this.cdr.detectChanges();\n }\n\n public async onSave(): Promise<void> {\n if (!this.Adapter || !this.Context) return;\n if (!this.HasChanges) {\n this.onCancel();\n return;\n }\n this.IsLoading = true;\n this.Error = null;\n this.cdr.detectChanges();\n\n try {\n for (const share of this.UserShares.filter((s) => s.MarkedForRemoval && !s.IsNew)) {\n const deleted = await share.PermissionEntity.Delete();\n if (!deleted) {\n throw new Error(\n `Failed to remove share for ${share.User.Name}: ${\n share.PermissionEntity.LatestResult?.Message ?? 'unknown error'\n }`\n );\n }\n }\n\n const dirtyRows = this.UserShares.filter(\n (s) => !s.MarkedForRemoval && (s.IsNew || s.Level !== s._InitialLevel)\n );\n for (const share of dirtyRows) {\n this.Adapter.SyncLevelToEntity(share);\n const saved = await share.PermissionEntity.Save();\n if (!saved) {\n throw new Error(\n `Failed to save share for ${share.User.Name}: ${\n share.PermissionEntity.LatestResult?.Message ?? 'unknown error'\n }`\n );\n }\n }\n\n if (this.Adapter.AfterSave) {\n await this.Adapter.AfterSave(this.Context);\n }\n\n this.Result.emit({ Action: 'save' });\n } catch (error) {\n console.error('Error saving shares:', error);\n this.Error = error instanceof Error ? error.message : 'Failed to save sharing settings.';\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public onCancel(): void {\n this.Result.emit({ Action: 'cancel' });\n }\n\n public getUserInitials(user: MJUserEntity): string {\n const name = user.Name || user.Email || '?';\n const parts = name.split(' ');\n if (parts.length >= 2) {\n return (parts[0][0] + parts[1][0]).toUpperCase();\n }\n return name.substring(0, 2).toUpperCase();\n }\n}\n","@if (Visible) {\n <mj-window\n [Visible]=\"true\"\n [Width]=\"560\"\n [MinHeight]=\"200\"\n [Resizable]=\"false\"\n [Draggable]=\"true\"\n (Close)=\"onCancel()\"\n class=\"mj-share-dialog-window\">\n <mj-window-titlebar>\n <div class=\"share-dialog-header\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Share \"{{ Context?.ResourceName }}\"</span>\n </div>\n </mj-window-titlebar>\n <div class=\"share-dialog-body\">\n @if (Error) {\n <div class=\"share-alert share-alert-error\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ Error }}</span>\n </div>\n }\n <!-- Add Users Section -->\n <div class=\"share-section\">\n <div class=\"share-search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Add people by name or email...\"\n [(ngModel)]=\"UserSearchFilter\"\n [disabled]=\"IsLoading\">\n </div>\n @if (FilteredAvailableUsers.length > 0) {\n <div class=\"share-user-dropdown\">\n @for (user of FilteredAvailableUsers; track user.ID) {\n <button type=\"button\" class=\"share-user-option\" (click)=\"addUserShare(user)\" [disabled]=\"IsLoading\">\n <span class=\"share-avatar\">{{ getUserInitials(user) }}</span>\n <span class=\"share-user-name\">{{ user.Name }}</span>\n @if (user.Email) {\n <span class=\"share-user-email\">{{ user.Email }}</span>\n }\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n </div>\n }\n @if (UserSearchFilter && FilteredAvailableUsers.length === 0) {\n <div class=\"share-no-results\">\n No users found matching \"{{ UserSearchFilter }}\"\n </div>\n }\n </div>\n <!-- People with Access -->\n <div class=\"share-section\">\n <div class=\"share-section-label\">People with access</div>\n @if (Context?.OwnerDisplayName) {\n <div class=\"share-person share-owner\">\n <span class=\"share-avatar share-avatar-owner\">\n <i class=\"fa-solid fa-crown\"></i>\n </span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">{{ Context?.OwnerDisplayName }}</span>\n <span class=\"share-person-role\">Owner</span>\n </div>\n </div>\n }\n @for (share of ActiveShares; track share.User.ID) {\n <div class=\"share-person\" [class.share-person-new]=\"share.IsNew\" [class.share-person-modified]=\"isModified(share)\">\n <span class=\"share-avatar\">{{ getUserInitials(share.User) }}</span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">\n {{ share.User.Name }}\n @if (share.IsNew) {\n <span class=\"share-badge-new\">New</span>\n }\n </span>\n @if (share.User.Email) {\n <span class=\"share-person-email\">{{ share.User.Email }}</span>\n }\n </div>\n <div class=\"share-level-select\" role=\"group\" aria-label=\"Permission level\">\n @for (level of Levels; track level) {\n <button type=\"button\"\n class=\"share-level-btn\"\n [class.active]=\"share.Level === level\"\n (click)=\"setLevel(share, level)\"\n [title]=\"level + ' access'\">\n {{ level }}\n </button>\n }\n </div>\n <button type=\"button\" class=\"share-remove-btn\" (click)=\"removeUserShare(share)\" title=\"Remove\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n @if (ActiveShares.length === 0) {\n <div class=\"share-empty\">\n <i class=\"fa-solid fa-user-lock\"></i>\n <span>Not shared with anyone yet</span>\n </div>\n }\n @if (RemovedShares.length > 0) {\n <div class=\"share-removed-section\">\n @for (share of RemovedShares; track share.User.ID) {\n <div class=\"share-removed-item\">\n <span class=\"share-avatar share-avatar-removed\">{{ getUserInitials(share.User) }}</span>\n <span class=\"share-removed-name\">{{ share.User.Name }}</span>\n <button type=\"button\" class=\"share-undo-btn\" (click)=\"undoRemove(share)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"share-footer\">\n @if (HasChanges) {\n <span class=\"share-changes-hint\">\n <i class=\"fa-solid fa-circle\"></i> Unsaved changes\n </span>\n }\n <div class=\"share-footer-actions\">\n <button type=\"button\" class=\"share-btn share-btn-secondary\" (click)=\"onCancel()\">\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"share-btn share-btn-primary\"\n (click)=\"onSave()\"\n [disabled]=\"!HasChanges || IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n Save\n }\n </button>\n </div>\n </div>\n </div>\n </mj-window>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"resource-share-dialog.component.js","sourceRoot":"","sources":["../../src/lib/resource-share-dialog.component.ts","../../src/lib/resource-share-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ChangeDetectorRef, ViewEncapsulation } from '@angular/core';\nimport { RunView } from '@memberjunction/core';\nimport { MJUserEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport {\n RESOURCE_SHARE_LEVELS,\n ResourceShareAdapter,\n ResourceShareContext,\n ResourceShareLevel,\n ResourceSharePermissionModel\n} from './resource-share-adapter';\n\n/**\n * Result emitted when {@link GenericShareDialogComponent} closes.\n */\nexport interface ResourceShareDialogResult {\n Action: 'save' | 'cancel';\n}\n\n/**\n * Resource-type-agnostic share dialog. Every resource's sharing UX collapses to\n * three tiers — View / Edit / Owner — so the dialog exposes a single level\n * selector per grantee rather than a grab bag of `Can*` checkboxes. Adapters\n * translate the level to whatever shape their backing entity actually persists.\n */\n@Component({\n standalone: false,\n selector: 'mj-resource-share-dialog',\n templateUrl: './resource-share-dialog.component.html',\n styleUrls: ['./resource-share-dialog.component.css'],\n encapsulation: ViewEncapsulation.None\n})\nexport class GenericShareDialogComponent implements OnChanges {\n @Input() Visible = false;\n @Input() Context: ResourceShareContext | null = null;\n @Input() Adapter: ResourceShareAdapter | null = null;\n @Output() Result = new EventEmitter<ResourceShareDialogResult>();\n\n public readonly Levels = RESOURCE_SHARE_LEVELS;\n\n public UserShares: ResourceSharePermissionModel[] = [];\n public AvailableUsers: MJUserEntity[] = [];\n private allUsers: MJUserEntity[] = [];\n\n public IsLoading = false;\n public Error: string | null = null;\n public UserSearchFilter = '';\n\n /** Message for the no-results empty-state, echoing the current search term. */\n public get NoUsersFoundMessage(): string {\n return `No users found matching \"${this.UserSearchFilter}\"`;\n }\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['Visible'] && this.Visible && this.Context && this.Adapter) {\n this.resetDialog();\n this.loadData();\n }\n }\n\n private resetDialog(): void {\n this.Error = null;\n this.IsLoading = false;\n this.UserShares = [];\n this.AvailableUsers = [];\n this.UserSearchFilter = '';\n }\n\n private async loadData(): Promise<void> {\n if (!this.Context || !this.Adapter) return;\n\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n const rv = new RunView();\n const usersResult = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: 'IsActive = 1',\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n this.allUsers = usersResult.Success ? usersResult.Results : [];\n\n this.UserShares = await this.Adapter.LoadShares(this.Context);\n this.UserShares.forEach((s) => (s._InitialLevel = s.Level));\n this.updateAvailableUsers();\n } catch (error) {\n console.error('Error loading share data:', error);\n this.Error = 'Failed to load sharing data. Please try again.';\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private updateAvailableUsers(): void {\n if (!this.Context) return;\n const sharedUserIds = new Set(\n this.UserShares.filter((s) => !s.MarkedForRemoval).map((s) => s.User.ID)\n );\n const ownerId = this.Context.OwnerUserID;\n this.AvailableUsers = this.allUsers.filter((user) => {\n if (ownerId && UUIDsEqual(user.ID, ownerId)) return false;\n return !sharedUserIds.has(user.ID);\n });\n }\n\n public get FilteredAvailableUsers(): MJUserEntity[] {\n if (!this.UserSearchFilter.trim()) {\n return this.AvailableUsers.slice(0, 10);\n }\n const filter = this.UserSearchFilter.toLowerCase();\n return this.AvailableUsers\n .filter((u) => u.Name.toLowerCase().includes(filter) || (u.Email && u.Email.toLowerCase().includes(filter)))\n .slice(0, 10);\n }\n\n public get HasChanges(): boolean {\n return this.UserShares.some(\n (s) => s.IsNew || s.MarkedForRemoval || s.Level !== s._InitialLevel\n );\n }\n\n public get ActiveShares(): ResourceSharePermissionModel[] {\n return this.UserShares.filter((s) => !s.MarkedForRemoval);\n }\n\n public get RemovedShares(): ResourceSharePermissionModel[] {\n return this.UserShares.filter((s) => s.MarkedForRemoval);\n }\n\n /** Highlight rows whose level has been changed from their loaded state. */\n public isModified(share: ResourceSharePermissionModel): boolean {\n return !share.IsNew && share.Level !== share._InitialLevel;\n }\n\n public async addUserShare(user: MJUserEntity): Promise<void> {\n if (!this.Context || !this.Adapter) return;\n const row = await this.Adapter.CreateShare(this.Context, user);\n row._InitialLevel = row.Level;\n this.UserShares.push(row);\n this.updateAvailableUsers();\n this.UserSearchFilter = '';\n this.cdr.detectChanges();\n }\n\n public removeUserShare(share: ResourceSharePermissionModel): void {\n if (share.IsNew) {\n this.UserShares = this.UserShares.filter((s) => s !== share);\n } else {\n share.MarkedForRemoval = true;\n }\n this.updateAvailableUsers();\n this.cdr.detectChanges();\n }\n\n public undoRemove(share: ResourceSharePermissionModel): void {\n share.MarkedForRemoval = false;\n this.updateAvailableUsers();\n this.cdr.detectChanges();\n }\n\n public setLevel(share: ResourceSharePermissionModel, level: ResourceShareLevel): void {\n share.Level = level;\n this.cdr.detectChanges();\n }\n\n public async onSave(): Promise<void> {\n if (!this.Adapter || !this.Context) return;\n if (!this.HasChanges) {\n this.onCancel();\n return;\n }\n this.IsLoading = true;\n this.Error = null;\n this.cdr.detectChanges();\n\n try {\n for (const share of this.UserShares.filter((s) => s.MarkedForRemoval && !s.IsNew)) {\n const deleted = await share.PermissionEntity.Delete();\n if (!deleted) {\n throw new Error(\n `Failed to remove share for ${share.User.Name}: ${\n share.PermissionEntity.LatestResult?.Message ?? 'unknown error'\n }`\n );\n }\n }\n\n const dirtyRows = this.UserShares.filter(\n (s) => !s.MarkedForRemoval && (s.IsNew || s.Level !== s._InitialLevel)\n );\n for (const share of dirtyRows) {\n this.Adapter.SyncLevelToEntity(share);\n const saved = await share.PermissionEntity.Save();\n if (!saved) {\n throw new Error(\n `Failed to save share for ${share.User.Name}: ${\n share.PermissionEntity.LatestResult?.Message ?? 'unknown error'\n }`\n );\n }\n }\n\n if (this.Adapter.AfterSave) {\n await this.Adapter.AfterSave(this.Context);\n }\n\n this.Result.emit({ Action: 'save' });\n } catch (error) {\n console.error('Error saving shares:', error);\n this.Error = error instanceof Error ? error.message : 'Failed to save sharing settings.';\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public onCancel(): void {\n this.Result.emit({ Action: 'cancel' });\n }\n\n public getUserInitials(user: MJUserEntity): string {\n const name = user.Name || user.Email || '?';\n const parts = name.split(' ');\n if (parts.length >= 2) {\n return (parts[0][0] + parts[1][0]).toUpperCase();\n }\n return name.substring(0, 2).toUpperCase();\n }\n}\n","@if (Visible) {\n <mj-window\n [Visible]=\"true\"\n [Width]=\"560\"\n [MinHeight]=\"200\"\n [Resizable]=\"false\"\n [Draggable]=\"true\"\n (Close)=\"onCancel()\"\n class=\"mj-share-dialog-window\">\n <mj-window-titlebar>\n <div class=\"share-dialog-header\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Share \"{{ Context?.ResourceName }}\"</span>\n </div>\n </mj-window-titlebar>\n <div class=\"share-dialog-body\">\n @if (Error) {\n <mj-alert Variant=\"error\">{{ Error }}</mj-alert>\n }\n <!-- Add Users Section -->\n <div class=\"share-section\">\n <div class=\"share-search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Add people by name or email...\"\n [(ngModel)]=\"UserSearchFilter\"\n [disabled]=\"IsLoading\">\n </div>\n @if (FilteredAvailableUsers.length > 0) {\n <div class=\"share-user-dropdown\">\n @for (user of FilteredAvailableUsers; track user.ID) {\n <button type=\"button\" class=\"share-user-option\" (click)=\"addUserShare(user)\" [disabled]=\"IsLoading\">\n <span class=\"share-avatar\">{{ getUserInitials(user) }}</span>\n <span class=\"share-user-name\">{{ user.Name }}</span>\n @if (user.Email) {\n <span class=\"share-user-email\">{{ user.Email }}</span>\n }\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n </div>\n }\n @if (UserSearchFilter && FilteredAvailableUsers.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-user-slash\"\n [Title]=\"NoUsersFoundMessage\"\n Size=\"compact\" />\n }\n </div>\n <!-- People with Access -->\n <div class=\"share-section\">\n <div class=\"share-section-label\">People with access</div>\n @if (Context?.OwnerDisplayName) {\n <div class=\"share-person share-owner\">\n <span class=\"share-avatar share-avatar-owner\">\n <i class=\"fa-solid fa-crown\"></i>\n </span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">{{ Context?.OwnerDisplayName }}</span>\n <span class=\"share-person-role\">Owner</span>\n </div>\n </div>\n }\n @for (share of ActiveShares; track share.User.ID) {\n <div class=\"share-person\" [class.share-person-new]=\"share.IsNew\" [class.share-person-modified]=\"isModified(share)\">\n <span class=\"share-avatar\">{{ getUserInitials(share.User) }}</span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">\n {{ share.User.Name }}\n @if (share.IsNew) {\n <span class=\"share-badge-new\">New</span>\n }\n </span>\n @if (share.User.Email) {\n <span class=\"share-person-email\">{{ share.User.Email }}</span>\n }\n </div>\n <div class=\"share-level-select\" role=\"group\" aria-label=\"Permission level\">\n @for (level of Levels; track level) {\n <button type=\"button\"\n class=\"share-level-btn\"\n [class.active]=\"share.Level === level\"\n (click)=\"setLevel(share, level)\"\n [title]=\"level + ' access'\">\n {{ level }}\n </button>\n }\n </div>\n <button type=\"button\" class=\"share-remove-btn\" (click)=\"removeUserShare(share)\" title=\"Remove\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n @if (ActiveShares.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-user-lock\"\n Title=\"Not shared with anyone yet\"\n Size=\"compact\" />\n }\n @if (RemovedShares.length > 0) {\n <div class=\"share-removed-section\">\n @for (share of RemovedShares; track share.User.ID) {\n <div class=\"share-removed-item\">\n <span class=\"share-avatar share-avatar-removed\">{{ getUserInitials(share.User) }}</span>\n <span class=\"share-removed-name\">{{ share.User.Name }}</span>\n <button type=\"button\" class=\"share-undo-btn\" (click)=\"undoRemove(share)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"share-footer\">\n @if (HasChanges) {\n <span class=\"share-changes-hint\">\n <i class=\"fa-solid fa-circle\"></i> Unsaved changes\n </span>\n }\n <div class=\"share-footer-actions\">\n <button type=\"button\" class=\"share-btn share-btn-secondary\" (click)=\"onCancel()\">\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"share-btn share-btn-primary\"\n (click)=\"onSave()\"\n [disabled]=\"!HasChanges || IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n Save\n }\n </button>\n </div>\n </div>\n </div>\n </mj-window>\n}\n"]}
|
|
@@ -90,7 +90,11 @@ export declare class UserSharingCenterComponent extends BaseAngularComponent imp
|
|
|
90
90
|
OnRowClick(row: NormalizedPermission): void;
|
|
91
91
|
OnClose(): void;
|
|
92
92
|
OnRevoke(row: NormalizedPermission, event: Event): Promise<void>;
|
|
93
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Apply the expand/collapse state emitted by the accordion panel for a domain
|
|
95
|
+
* group. OnPush, so an explicit detectChanges() is required to reflect the change.
|
|
96
|
+
*/
|
|
97
|
+
OnGroupExpandedChange(group: SharingCenterDomainGroup, expanded: boolean): void;
|
|
94
98
|
ActionsLabel(actions: PermissionAction[]): string;
|
|
95
99
|
TrackByDomain(_idx: number, g: SharingCenterDomainGroup): string;
|
|
96
100
|
TrackByRow(_idx: number, r: NormalizedPermission): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-sharing-center.component.d.ts","sourceRoot":"","sources":["../../src/lib/user-sharing-center.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,YAAY,EAEZ,MAAM,EAGT,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIH,oBAAoB,EACpB,gBAAgB,EACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAErE,4DAA4D;AAC5D,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,oBAAoB,EAAE,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GAAI,YAAY,MAAM,KAAG,MAAM,GAAG,IAe1E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAQa,0BAA2B,SAAQ,oBAAqB,YAAW,MAAM;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IAIzD,4EAA4E;IACnE,SAAS,EAAE,gBAAgB,CAAoB;IAExD;;;OAGG;IACM,eAAe,UAAQ;IAEhC,yDAAyD;IAChD,kBAAkB,SAAmB;IAE9C;;;;OAIG;IACM,qBAAqB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAgC;IAIrG,+CAA+C;IACrC,eAAe,iCAAwC;IAEjE,+DAA+D;IACrD,eAAe,qCAA4C;IAErE,8FAA8F;IACpF,cAAc,qBAA4B;IAEpD,8DAA8D;IACpD,iBAAiB,qCAA4C;IAEvE,iFAAiF;IACvE,aAAa,uBAA8B;IAIrD,YAAY,EAAE,wBAAwB,EAAE,CAAM;IAC9C,UAAU,EAAE,wBAAwB,EAAE,CAAM;IAE5C,eAAe,UAAS;IACxB,aAAa,UAAS;IAEtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE7B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,+DAA+D;IAClD,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5D,8CAA8C;IACjC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAYrC,UAAU,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,UAAU,CAAC,GAAG,EAAE,oBAAoB,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAIT,QAAQ,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCtE,
|
|
1
|
+
{"version":3,"file":"user-sharing-center.component.d.ts","sourceRoot":"","sources":["../../src/lib/user-sharing-center.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,YAAY,EAEZ,MAAM,EAGT,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIH,oBAAoB,EACpB,gBAAgB,EACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAErE,4DAA4D;AAC5D,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,oBAAoB,EAAE,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GAAI,YAAY,MAAM,KAAG,MAAM,GAAG,IAe1E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAQa,0BAA2B,SAAQ,oBAAqB,YAAW,MAAM;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IAIzD,4EAA4E;IACnE,SAAS,EAAE,gBAAgB,CAAoB;IAExD;;;OAGG;IACM,eAAe,UAAQ;IAEhC,yDAAyD;IAChD,kBAAkB,SAAmB;IAE9C;;;;OAIG;IACM,qBAAqB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAgC;IAIrG,+CAA+C;IACrC,eAAe,iCAAwC;IAEjE,+DAA+D;IACrD,eAAe,qCAA4C;IAErE,8FAA8F;IACpF,cAAc,qBAA4B;IAEpD,8DAA8D;IACpD,iBAAiB,qCAA4C;IAEvE,iFAAiF;IACvE,aAAa,uBAA8B;IAIrD,YAAY,EAAE,wBAAwB,EAAE,CAAM;IAC9C,UAAU,EAAE,wBAAwB,EAAE,CAAM;IAE5C,eAAe,UAAS;IACxB,aAAa,UAAS;IAEtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE7B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,+DAA+D;IAClD,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5D,8CAA8C;IACjC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAYrC,UAAU,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,UAAU,CAAC,GAAG,EAAE,oBAAoB,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAIT,QAAQ,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCtE;;;OAGG;IACH,qBAAqB,CAAC,KAAK,EAAE,wBAAwB,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAK/E,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,MAAM;IAIjD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,wBAAwB,GAAG,MAAM;IAIhE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,oBAAoB,GAAG,MAAM;YAM3C,OAAO;YAYP,gBAAgB;YAiBhB,cAAc;IAiB5B,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,aAAa;yCA1NZ,0BAA0B;2CAA1B,0BAA0B;CAiPtC"}
|