@memberjunction/ng-resource-permissions 5.43.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.
@@ -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;IAgB7C,OAAO,CAAC,GAAG;IAfd,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;gBAET,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;yCA5LzC,2BAA2B;2CAA3B,2BAA2B;CAoMvC"}
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, "div", 5);
12
- i0.ɵɵelement(1, "i", 22);
13
- i0.ɵɵelementStart(2, "span");
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(3);
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", 27);
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", 24);
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", 25);
32
+ i0.ɵɵelementStart(1, "span", 24);
35
33
  i0.ɵɵtext(2);
36
34
  i0.ɵɵelementEnd();
37
- i0.ɵɵelementStart(3, "span", 26);
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", 27);
41
- i0.ɵɵelement(6, "i", 28);
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", 23, _forTrack1);
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.ɵɵelementStart(0, "div", 11);
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.ɵɵadvance();
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", 29);
74
- i0.ɵɵelement(2, "i", 30);
68
+ i0.ɵɵelementStart(0, "div", 13)(1, "span", 28);
69
+ i0.ɵɵelement(2, "i", 29);
75
70
  i0.ɵɵelementEnd();
76
- i0.ɵɵelementStart(3, "div", 31)(4, "span", 32);
71
+ i0.ɵɵelementStart(3, "div", 30)(4, "span", 31);
77
72
  i0.ɵɵtext(5);
78
73
  i0.ɵɵelementEnd();
79
- i0.ɵɵelementStart(6, "span", 33);
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", 35);
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", 36);
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", 41);
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", 34)(1, "span", 25);
112
+ i0.ɵɵelementStart(0, "div", 33)(1, "span", 24);
118
113
  i0.ɵɵtext(2);
119
114
  i0.ɵɵelementEnd();
120
- i0.ɵɵelementStart(3, "div", 31)(4, "span", 32);
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", 35);
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", 36);
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", 37);
127
- i0.ɵɵrepeaterCreate(9, GenericShareDialogComponent_Conditional_0_For_19_For_10_Template, 2, 4, "button", 38, i0.ɵɵrepeaterTrackByIdentity);
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", 39);
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", 40);
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.ɵɵelementStart(0, "div", 15);
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", 43)(1, "span", 44);
148
+ i0.ɵɵelementStart(0, "div", 41)(1, "span", 42);
158
149
  i0.ɵɵtext(2);
159
150
  i0.ɵɵelementEnd();
160
- i0.ɵɵelementStart(3, "span", 45);
151
+ i0.ɵɵelementStart(3, "span", 43);
161
152
  i0.ɵɵtext(4);
162
153
  i0.ɵɵelementEnd();
163
- i0.ɵɵelementStart(5, "button", 46);
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", 47);
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", 43, _forTrack0);
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", 48);
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", 49);
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, 4, 1, "div", 5);
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, 2, 1, "div", 11);
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, 4, 0, "div", 15);
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"], [1, "share-alert", "share-alert-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"], [1, "share-no-results"], [1, "share-section-label"], [1, "share-person", "share-owner"], [1, "share-person", 3, "share-person-new", "share-person-modified"], [1, "share-empty"], [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"], [1, "fa-solid", "fa-exclamation-triangle"], ["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, "fa-solid", "fa-user-lock"], [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) {
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
- ToggleGroup(group: SharingCenterDomainGroup): void;
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,WAAW,CAAC,KAAK,EAAE,wBAAwB,GAAG,IAAI;IAKlD,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;yCAtNZ,0BAA0B;2CAA1B,0BAA0B;CA6OtC"}
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"}