@memberjunction/ng-resource-permissions 6.1.4 → 6.2.0-edge.1

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.
@@ -17,8 +17,19 @@ function GenericShareDialogComponent_Conditional_0_Conditional_7_Template(rf, ct
17
17
  i0.ɵɵadvance();
18
18
  i0.ɵɵtextInterpolate(ctx_r1.Error);
19
19
  } }
20
- function GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
21
- i0.ɵɵelementStart(0, "span", 26);
20
+ function GenericShareDialogComponent_Conditional_0_Conditional_8_Template(rf, ctx) { if (rf & 1) {
21
+ i0.ɵɵelementStart(0, "div", 6);
22
+ i0.ɵɵelement(1, "i", 23);
23
+ i0.ɵɵelementStart(2, "span");
24
+ i0.ɵɵtext(3);
25
+ i0.ɵɵelementEnd()();
26
+ } if (rf & 2) {
27
+ const ctx_r1 = i0.ɵɵnextContext(2);
28
+ i0.ɵɵadvance(3);
29
+ i0.ɵɵtextInterpolate(ctx_r1.Notice);
30
+ } }
31
+ function GenericShareDialogComponent_Conditional_0_Conditional_13_For_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
32
+ i0.ɵɵelementStart(0, "span", 28);
22
33
  i0.ɵɵtext(1);
23
34
  i0.ɵɵelementEnd();
24
35
  } if (rf & 2) {
@@ -26,67 +37,67 @@ function GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Conditio
26
37
  i0.ɵɵadvance();
27
38
  i0.ɵɵtextInterpolate(user_r4.Email);
28
39
  } }
29
- function GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
40
+ function GenericShareDialogComponent_Conditional_0_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
30
41
  const _r3 = i0.ɵɵgetCurrentView();
31
- i0.ɵɵelementStart(0, "button", 23);
32
- 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)); });
33
- i0.ɵɵelementStart(1, "span", 24);
42
+ i0.ɵɵelementStart(0, "button", 25);
43
+ i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_Conditional_13_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)); });
44
+ i0.ɵɵelementStart(1, "span", 26);
34
45
  i0.ɵɵtext(2);
35
46
  i0.ɵɵelementEnd();
36
- i0.ɵɵelementStart(3, "span", 25);
47
+ i0.ɵɵelementStart(3, "span", 27);
37
48
  i0.ɵɵtext(4);
38
49
  i0.ɵɵelementEnd();
39
- i0.ɵɵconditionalCreate(5, GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Conditional_5_Template, 2, 1, "span", 26);
40
- i0.ɵɵelement(6, "i", 27);
50
+ i0.ɵɵconditionalCreate(5, GenericShareDialogComponent_Conditional_0_Conditional_13_For_2_Conditional_5_Template, 2, 1, "span", 28);
51
+ i0.ɵɵelement(6, "i", 29);
41
52
  i0.ɵɵelementEnd();
42
53
  } if (rf & 2) {
43
54
  const user_r4 = ctx.$implicit;
44
55
  const ctx_r1 = i0.ɵɵnextContext(3);
45
56
  i0.ɵɵproperty("disabled", ctx_r1.IsLoading);
46
57
  i0.ɵɵadvance(2);
47
- i0.ɵɵtextInterpolate(ctx_r1.getUserInitials(user_r4));
58
+ i0.ɵɵtextInterpolate(ctx_r1.GetUserInitials(user_r4));
48
59
  i0.ɵɵadvance(2);
49
60
  i0.ɵɵtextInterpolate(user_r4.Name);
50
61
  i0.ɵɵadvance();
51
62
  i0.ɵɵconditional(user_r4.Email ? 5 : -1);
52
63
  } }
53
- function GenericShareDialogComponent_Conditional_0_Conditional_12_Template(rf, ctx) { if (rf & 1) {
54
- i0.ɵɵelementStart(0, "div", 10);
55
- i0.ɵɵrepeaterCreate(1, GenericShareDialogComponent_Conditional_0_Conditional_12_For_2_Template, 7, 4, "button", 22, _forTrack1);
64
+ function GenericShareDialogComponent_Conditional_0_Conditional_13_Template(rf, ctx) { if (rf & 1) {
65
+ i0.ɵɵelementStart(0, "div", 11);
66
+ i0.ɵɵrepeaterCreate(1, GenericShareDialogComponent_Conditional_0_Conditional_13_For_2_Template, 7, 4, "button", 24, _forTrack1);
56
67
  i0.ɵɵelementEnd();
57
68
  } if (rf & 2) {
58
69
  const ctx_r1 = i0.ɵɵnextContext(2);
59
70
  i0.ɵɵadvance();
60
71
  i0.ɵɵrepeater(ctx_r1.FilteredAvailableUsers);
61
72
  } }
62
- function GenericShareDialogComponent_Conditional_0_Conditional_13_Template(rf, ctx) { if (rf & 1) {
63
- i0.ɵɵelement(0, "mj-empty-state", 11);
73
+ function GenericShareDialogComponent_Conditional_0_Conditional_14_Template(rf, ctx) { if (rf & 1) {
74
+ i0.ɵɵelement(0, "mj-empty-state", 12);
64
75
  } if (rf & 2) {
65
76
  const ctx_r1 = i0.ɵɵnextContext(2);
66
77
  i0.ɵɵproperty("Title", ctx_r1.NoUsersFoundMessage);
67
78
  } }
68
- function GenericShareDialogComponent_Conditional_0_Conditional_17_Template(rf, ctx) { if (rf & 1) {
69
- i0.ɵɵelementStart(0, "div", 13)(1, "span", 28);
70
- i0.ɵɵelement(2, "i", 29);
79
+ function GenericShareDialogComponent_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
80
+ i0.ɵɵelementStart(0, "div", 14)(1, "span", 30);
81
+ i0.ɵɵelement(2, "i", 31);
71
82
  i0.ɵɵelementEnd();
72
- i0.ɵɵelementStart(3, "div", 30)(4, "span", 31);
83
+ i0.ɵɵelementStart(3, "div", 32)(4, "span", 33);
73
84
  i0.ɵɵtext(5);
74
85
  i0.ɵɵelementEnd();
75
- i0.ɵɵelementStart(6, "span", 32);
86
+ i0.ɵɵelementStart(6, "span", 34);
76
87
  i0.ɵɵtext(7, "Owner");
77
88
  i0.ɵɵelementEnd()()();
78
89
  } if (rf & 2) {
79
90
  const ctx_r1 = i0.ɵɵnextContext(2);
80
91
  i0.ɵɵadvance(5);
81
- i0.ɵɵtextInterpolate(ctx_r1.Context == null ? null : ctx_r1.Context.OwnerDisplayName);
92
+ i0.ɵɵtextInterpolate(ctx_r1.PrimaryContext == null ? null : ctx_r1.PrimaryContext.OwnerDisplayName);
82
93
  } }
83
- function GenericShareDialogComponent_Conditional_0_For_19_Conditional_6_Template(rf, ctx) { if (rf & 1) {
84
- i0.ɵɵelementStart(0, "span", 34);
94
+ function GenericShareDialogComponent_Conditional_0_For_20_Conditional_6_Template(rf, ctx) { if (rf & 1) {
95
+ i0.ɵɵelementStart(0, "span", 36);
85
96
  i0.ɵɵtext(1, "New");
86
97
  i0.ɵɵelementEnd();
87
98
  } }
88
- function GenericShareDialogComponent_Conditional_0_For_19_Conditional_7_Template(rf, ctx) { if (rf & 1) {
89
- i0.ɵɵelementStart(0, "span", 35);
99
+ function GenericShareDialogComponent_Conditional_0_For_20_Conditional_7_Template(rf, ctx) { if (rf & 1) {
100
+ i0.ɵɵelementStart(0, "span", 37);
90
101
  i0.ɵɵtext(1);
91
102
  i0.ɵɵelementEnd();
92
103
  } if (rf & 2) {
@@ -94,97 +105,111 @@ function GenericShareDialogComponent_Conditional_0_For_19_Conditional_7_Template
94
105
  i0.ɵɵadvance();
95
106
  i0.ɵɵtextInterpolate(share_r6.User.Email);
96
107
  } }
97
- function GenericShareDialogComponent_Conditional_0_For_19_For_10_Template(rf, ctx) { if (rf & 1) {
108
+ function GenericShareDialogComponent_Conditional_0_For_20_Conditional_8_Template(rf, ctx) { if (rf & 1) {
109
+ i0.ɵɵelementStart(0, "span", 38);
110
+ i0.ɵɵtext(1);
111
+ i0.ɵɵelementEnd();
112
+ } if (rf & 2) {
113
+ const share_r6 = i0.ɵɵnextContext().$implicit;
114
+ const ctx_r1 = i0.ɵɵnextContext(2);
115
+ i0.ɵɵadvance();
116
+ i0.ɵɵtextInterpolate(ctx_r1.ScopeLabel(share_r6));
117
+ } }
118
+ function GenericShareDialogComponent_Conditional_0_For_20_For_11_Template(rf, ctx) { if (rf & 1) {
98
119
  const _r7 = i0.ɵɵgetCurrentView();
99
- i0.ɵɵelementStart(0, "button", 40);
100
- 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)); });
120
+ i0.ɵɵelementStart(0, "button", 43);
121
+ i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_For_20_For_11_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)); });
101
122
  i0.ɵɵtext(1);
102
123
  i0.ɵɵelementEnd();
103
124
  } if (rf & 2) {
104
125
  const level_r8 = ctx.$implicit;
105
126
  const share_r6 = i0.ɵɵnextContext().$implicit;
106
- i0.ɵɵclassProp("active", share_r6.Level === level_r8);
127
+ const ctx_r1 = i0.ɵɵnextContext(2);
128
+ i0.ɵɵclassProp("active", ctx_r1.IsLevelActive(share_r6, level_r8));
107
129
  i0.ɵɵproperty("title", level_r8 + " access");
108
130
  i0.ɵɵadvance();
109
131
  i0.ɵɵtextInterpolate1(" ", level_r8, " ");
110
132
  } }
111
- function GenericShareDialogComponent_Conditional_0_For_19_Template(rf, ctx) { if (rf & 1) {
133
+ function GenericShareDialogComponent_Conditional_0_For_20_Template(rf, ctx) { if (rf & 1) {
112
134
  const _r5 = i0.ɵɵgetCurrentView();
113
- i0.ɵɵelementStart(0, "div", 33)(1, "span", 24);
135
+ i0.ɵɵelementStart(0, "div", 35)(1, "span", 26);
114
136
  i0.ɵɵtext(2);
115
137
  i0.ɵɵelementEnd();
116
- i0.ɵɵelementStart(3, "div", 30)(4, "span", 31);
138
+ i0.ɵɵelementStart(3, "div", 32)(4, "span", 33);
117
139
  i0.ɵɵtext(5);
118
- i0.ɵɵconditionalCreate(6, GenericShareDialogComponent_Conditional_0_For_19_Conditional_6_Template, 2, 0, "span", 34);
140
+ i0.ɵɵconditionalCreate(6, GenericShareDialogComponent_Conditional_0_For_20_Conditional_6_Template, 2, 0, "span", 36);
119
141
  i0.ɵɵelementEnd();
120
- i0.ɵɵconditionalCreate(7, GenericShareDialogComponent_Conditional_0_For_19_Conditional_7_Template, 2, 1, "span", 35);
142
+ i0.ɵɵconditionalCreate(7, GenericShareDialogComponent_Conditional_0_For_20_Conditional_7_Template, 2, 1, "span", 37);
143
+ i0.ɵɵconditionalCreate(8, GenericShareDialogComponent_Conditional_0_For_20_Conditional_8_Template, 2, 1, "span", 38);
121
144
  i0.ɵɵelementEnd();
122
- i0.ɵɵelementStart(8, "div", 36);
123
- i0.ɵɵrepeaterCreate(9, GenericShareDialogComponent_Conditional_0_For_19_For_10_Template, 2, 4, "button", 37, i0.ɵɵrepeaterTrackByIdentity);
145
+ i0.ɵɵelementStart(9, "div", 39);
146
+ i0.ɵɵrepeaterCreate(10, GenericShareDialogComponent_Conditional_0_For_20_For_11_Template, 2, 4, "button", 40, i0.ɵɵrepeaterTrackByIdentity);
124
147
  i0.ɵɵelementEnd();
125
- i0.ɵɵelementStart(11, "button", 38);
126
- 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)); });
127
- i0.ɵɵelement(12, "i", 39);
148
+ i0.ɵɵelementStart(12, "button", 41);
149
+ i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_For_20_Template_button_click_12_listener() { const share_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.RemoveUserShare(share_r6)); });
150
+ i0.ɵɵelement(13, "i", 42);
128
151
  i0.ɵɵelementEnd()();
129
152
  } if (rf & 2) {
130
153
  const share_r6 = ctx.$implicit;
131
154
  const ctx_r1 = i0.ɵɵnextContext(2);
132
- i0.ɵɵclassProp("share-person-new", share_r6.IsNew)("share-person-modified", ctx_r1.isModified(share_r6));
155
+ i0.ɵɵclassProp("share-person-new", share_r6.IsNew)("share-person-modified", ctx_r1.IsModified(share_r6));
133
156
  i0.ɵɵadvance(2);
134
- i0.ɵɵtextInterpolate(ctx_r1.getUserInitials(share_r6.User));
157
+ i0.ɵɵtextInterpolate(ctx_r1.GetUserInitials(share_r6.User));
135
158
  i0.ɵɵadvance(3);
136
159
  i0.ɵɵtextInterpolate1(" ", share_r6.User.Name, " ");
137
160
  i0.ɵɵadvance();
138
161
  i0.ɵɵconditional(share_r6.IsNew ? 6 : -1);
139
162
  i0.ɵɵadvance();
140
163
  i0.ɵɵconditional(share_r6.User.Email ? 7 : -1);
164
+ i0.ɵɵadvance();
165
+ i0.ɵɵconditional(ctx_r1.ScopeLabel(share_r6) ? 8 : -1);
141
166
  i0.ɵɵadvance(2);
142
167
  i0.ɵɵrepeater(ctx_r1.Levels);
143
168
  } }
144
- function GenericShareDialogComponent_Conditional_0_Conditional_20_Template(rf, ctx) { if (rf & 1) {
145
- i0.ɵɵelement(0, "mj-empty-state", 15);
169
+ function GenericShareDialogComponent_Conditional_0_Conditional_21_Template(rf, ctx) { if (rf & 1) {
170
+ i0.ɵɵelement(0, "mj-empty-state", 16);
146
171
  } }
147
- function GenericShareDialogComponent_Conditional_0_Conditional_21_For_2_Template(rf, ctx) { if (rf & 1) {
172
+ function GenericShareDialogComponent_Conditional_0_Conditional_22_For_2_Template(rf, ctx) { if (rf & 1) {
148
173
  const _r9 = i0.ɵɵgetCurrentView();
149
- i0.ɵɵelementStart(0, "div", 41)(1, "span", 42);
174
+ i0.ɵɵelementStart(0, "div", 44)(1, "span", 45);
150
175
  i0.ɵɵtext(2);
151
176
  i0.ɵɵelementEnd();
152
- i0.ɵɵelementStart(3, "span", 43);
177
+ i0.ɵɵelementStart(3, "span", 46);
153
178
  i0.ɵɵtext(4);
154
179
  i0.ɵɵelementEnd();
155
- i0.ɵɵelementStart(5, "button", 44);
156
- 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)); });
157
- i0.ɵɵelement(6, "i", 45);
180
+ i0.ɵɵelementStart(5, "button", 47);
181
+ i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_Conditional_22_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)); });
182
+ i0.ɵɵelement(6, "i", 48);
158
183
  i0.ɵɵtext(7, " Undo ");
159
184
  i0.ɵɵelementEnd()();
160
185
  } if (rf & 2) {
161
186
  const share_r10 = ctx.$implicit;
162
187
  const ctx_r1 = i0.ɵɵnextContext(3);
163
188
  i0.ɵɵadvance(2);
164
- i0.ɵɵtextInterpolate(ctx_r1.getUserInitials(share_r10.User));
189
+ i0.ɵɵtextInterpolate(ctx_r1.GetUserInitials(share_r10.User));
165
190
  i0.ɵɵadvance(2);
166
191
  i0.ɵɵtextInterpolate(share_r10.User.Name);
167
192
  } }
168
- function GenericShareDialogComponent_Conditional_0_Conditional_21_Template(rf, ctx) { if (rf & 1) {
169
- i0.ɵɵelementStart(0, "div", 16);
170
- i0.ɵɵrepeaterCreate(1, GenericShareDialogComponent_Conditional_0_Conditional_21_For_2_Template, 8, 2, "div", 41, _forTrack0);
193
+ function GenericShareDialogComponent_Conditional_0_Conditional_22_Template(rf, ctx) { if (rf & 1) {
194
+ i0.ɵɵelementStart(0, "div", 17);
195
+ i0.ɵɵrepeaterCreate(1, GenericShareDialogComponent_Conditional_0_Conditional_22_For_2_Template, 8, 2, "div", 44, _forTrack0);
171
196
  i0.ɵɵelementEnd();
172
197
  } if (rf & 2) {
173
198
  const ctx_r1 = i0.ɵɵnextContext(2);
174
199
  i0.ɵɵadvance();
175
200
  i0.ɵɵrepeater(ctx_r1.RemovedShares);
176
201
  } }
177
- function GenericShareDialogComponent_Conditional_0_Conditional_23_Template(rf, ctx) { if (rf & 1) {
178
- i0.ɵɵelementStart(0, "span", 18);
179
- i0.ɵɵelement(1, "i", 46);
202
+ function GenericShareDialogComponent_Conditional_0_Conditional_24_Template(rf, ctx) { if (rf & 1) {
203
+ i0.ɵɵelementStart(0, "span", 19);
204
+ i0.ɵɵelement(1, "i", 49);
180
205
  i0.ɵɵtext(2, " Unsaved changes ");
181
206
  i0.ɵɵelementEnd();
182
207
  } }
183
- function GenericShareDialogComponent_Conditional_0_Conditional_28_Template(rf, ctx) { if (rf & 1) {
184
- i0.ɵɵelement(0, "i", 47);
208
+ function GenericShareDialogComponent_Conditional_0_Conditional_29_Template(rf, ctx) { if (rf & 1) {
209
+ i0.ɵɵelement(0, "i", 50);
185
210
  i0.ɵɵtext(1, " Saving... ");
186
211
  } }
187
- function GenericShareDialogComponent_Conditional_0_Conditional_29_Template(rf, ctx) { if (rf & 1) {
212
+ function GenericShareDialogComponent_Conditional_0_Conditional_30_Template(rf, ctx) { if (rf & 1) {
188
213
  i0.ɵɵtext(0, " Save ");
189
214
  } }
190
215
  function GenericShareDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
@@ -198,60 +223,63 @@ function GenericShareDialogComponent_Conditional_0_Template(rf, ctx) { if (rf &
198
223
  i0.ɵɵelementEnd()()();
199
224
  i0.ɵɵelementStart(6, "div", 4);
200
225
  i0.ɵɵconditionalCreate(7, GenericShareDialogComponent_Conditional_0_Conditional_7_Template, 2, 1, "mj-alert", 5);
201
- i0.ɵɵelementStart(8, "div", 6)(9, "div", 7);
202
- i0.ɵɵelement(10, "i", 8);
203
- i0.ɵɵelementStart(11, "input", 9);
204
- 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); });
226
+ i0.ɵɵconditionalCreate(8, GenericShareDialogComponent_Conditional_0_Conditional_8_Template, 4, 1, "div", 6);
227
+ i0.ɵɵelementStart(9, "div", 7)(10, "div", 8);
228
+ i0.ɵɵelement(11, "i", 9);
229
+ i0.ɵɵelementStart(12, "input", 10);
230
+ i0.ɵɵtwoWayListener("ngModelChange", function GenericShareDialogComponent_Conditional_0_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.UserSearchFilter, $event) || (ctx_r1.UserSearchFilter = $event); return i0.ɵɵresetView($event); });
205
231
  i0.ɵɵelementEnd()();
206
- i0.ɵɵconditionalCreate(12, GenericShareDialogComponent_Conditional_0_Conditional_12_Template, 3, 0, "div", 10);
207
- i0.ɵɵconditionalCreate(13, GenericShareDialogComponent_Conditional_0_Conditional_13_Template, 1, 1, "mj-empty-state", 11);
232
+ i0.ɵɵconditionalCreate(13, GenericShareDialogComponent_Conditional_0_Conditional_13_Template, 3, 0, "div", 11);
233
+ i0.ɵɵconditionalCreate(14, GenericShareDialogComponent_Conditional_0_Conditional_14_Template, 1, 1, "mj-empty-state", 12);
208
234
  i0.ɵɵelementEnd();
209
- i0.ɵɵelementStart(14, "div", 6)(15, "div", 12);
210
- i0.ɵɵtext(16, "People with access");
235
+ i0.ɵɵelementStart(15, "div", 7)(16, "div", 13);
236
+ i0.ɵɵtext(17, "People with access");
211
237
  i0.ɵɵelementEnd();
212
- i0.ɵɵconditionalCreate(17, GenericShareDialogComponent_Conditional_0_Conditional_17_Template, 8, 1, "div", 13);
213
- i0.ɵɵrepeaterCreate(18, GenericShareDialogComponent_Conditional_0_For_19_Template, 13, 8, "div", 14, _forTrack0);
214
- i0.ɵɵconditionalCreate(20, GenericShareDialogComponent_Conditional_0_Conditional_20_Template, 1, 0, "mj-empty-state", 15);
215
- i0.ɵɵconditionalCreate(21, GenericShareDialogComponent_Conditional_0_Conditional_21_Template, 3, 0, "div", 16);
238
+ i0.ɵɵconditionalCreate(18, GenericShareDialogComponent_Conditional_0_Conditional_18_Template, 8, 1, "div", 14);
239
+ i0.ɵɵrepeaterCreate(19, GenericShareDialogComponent_Conditional_0_For_20_Template, 14, 9, "div", 15, _forTrack0);
240
+ i0.ɵɵconditionalCreate(21, GenericShareDialogComponent_Conditional_0_Conditional_21_Template, 1, 0, "mj-empty-state", 16);
241
+ i0.ɵɵconditionalCreate(22, GenericShareDialogComponent_Conditional_0_Conditional_22_Template, 3, 0, "div", 17);
216
242
  i0.ɵɵelementEnd();
217
- i0.ɵɵelementStart(22, "div", 17);
218
- i0.ɵɵconditionalCreate(23, GenericShareDialogComponent_Conditional_0_Conditional_23_Template, 3, 0, "span", 18);
219
- i0.ɵɵelementStart(24, "div", 19)(25, "button", 20);
220
- i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCancel()); });
221
- i0.ɵɵtext(26, " Cancel ");
243
+ i0.ɵɵelementStart(23, "div", 18);
244
+ i0.ɵɵconditionalCreate(24, GenericShareDialogComponent_Conditional_0_Conditional_24_Template, 3, 0, "span", 19);
245
+ i0.ɵɵelementStart(25, "div", 20)(26, "button", 21);
246
+ i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_Template_button_click_26_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCancel()); });
247
+ i0.ɵɵtext(27, " Cancel ");
222
248
  i0.ɵɵelementEnd();
223
- i0.ɵɵelementStart(27, "button", 21);
224
- i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSave()); });
225
- i0.ɵɵconditionalCreate(28, GenericShareDialogComponent_Conditional_0_Conditional_28_Template, 2, 0)(29, GenericShareDialogComponent_Conditional_0_Conditional_29_Template, 1, 0);
249
+ i0.ɵɵelementStart(28, "button", 22);
250
+ i0.ɵɵlistener("click", function GenericShareDialogComponent_Conditional_0_Template_button_click_28_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSave()); });
251
+ i0.ɵɵconditionalCreate(29, GenericShareDialogComponent_Conditional_0_Conditional_29_Template, 2, 0)(30, GenericShareDialogComponent_Conditional_0_Conditional_30_Template, 1, 0);
226
252
  i0.ɵɵelementEnd()()()()();
227
253
  } if (rf & 2) {
228
254
  const ctx_r1 = i0.ɵɵnextContext();
229
255
  i0.ɵɵproperty("Visible", true)("Width", 560)("MinHeight", 200)("Resizable", false)("Draggable", true);
230
256
  i0.ɵɵadvance(5);
231
- i0.ɵɵtextInterpolate1("Share \"", ctx_r1.Context == null ? null : ctx_r1.Context.ResourceName, "\"");
257
+ i0.ɵɵtextInterpolate(ctx_r1.Title);
232
258
  i0.ɵɵadvance(2);
233
259
  i0.ɵɵconditional(ctx_r1.Error ? 7 : -1);
260
+ i0.ɵɵadvance();
261
+ i0.ɵɵconditional(ctx_r1.Notice ? 8 : -1);
234
262
  i0.ɵɵadvance(4);
235
263
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.UserSearchFilter);
236
264
  i0.ɵɵproperty("disabled", ctx_r1.IsLoading);
237
265
  i0.ɵɵadvance();
238
- i0.ɵɵconditional(ctx_r1.FilteredAvailableUsers.length > 0 ? 12 : -1);
266
+ i0.ɵɵconditional(ctx_r1.FilteredAvailableUsers.length > 0 ? 13 : -1);
239
267
  i0.ɵɵadvance();
240
- i0.ɵɵconditional(ctx_r1.UserSearchFilter && ctx_r1.FilteredAvailableUsers.length === 0 ? 13 : -1);
268
+ i0.ɵɵconditional(ctx_r1.UserSearchFilter && ctx_r1.FilteredAvailableUsers.length === 0 ? 14 : -1);
241
269
  i0.ɵɵadvance(4);
242
- i0.ɵɵconditional((ctx_r1.Context == null ? null : ctx_r1.Context.OwnerDisplayName) ? 17 : -1);
270
+ i0.ɵɵconditional((ctx_r1.PrimaryContext == null ? null : ctx_r1.PrimaryContext.OwnerDisplayName) ? 18 : -1);
243
271
  i0.ɵɵadvance();
244
272
  i0.ɵɵrepeater(ctx_r1.ActiveShares);
245
273
  i0.ɵɵadvance(2);
246
- i0.ɵɵconditional(ctx_r1.ActiveShares.length === 0 ? 20 : -1);
274
+ i0.ɵɵconditional(ctx_r1.ActiveShares.length === 0 ? 21 : -1);
247
275
  i0.ɵɵadvance();
248
- i0.ɵɵconditional(ctx_r1.RemovedShares.length > 0 ? 21 : -1);
276
+ i0.ɵɵconditional(ctx_r1.RemovedShares.length > 0 ? 22 : -1);
249
277
  i0.ɵɵadvance(2);
250
- i0.ɵɵconditional(ctx_r1.HasChanges ? 23 : -1);
278
+ i0.ɵɵconditional(ctx_r1.HasChanges ? 24 : -1);
251
279
  i0.ɵɵadvance(4);
252
280
  i0.ɵɵproperty("disabled", !ctx_r1.HasChanges || ctx_r1.IsLoading);
253
281
  i0.ɵɵadvance();
254
- i0.ɵɵconditional(ctx_r1.IsLoading ? 28 : 29);
282
+ i0.ɵɵconditional(ctx_r1.IsLoading ? 29 : 30);
255
283
  } }
256
284
  /**
257
285
  * Resource-type-agnostic share dialog. Every resource's sharing UX collapses to
@@ -262,16 +290,40 @@ function GenericShareDialogComponent_Conditional_0_Template(rf, ctx) { if (rf &
262
290
  export class GenericShareDialogComponent extends BaseAngularComponent {
263
291
  cdr;
264
292
  Visible = false;
293
+ /** The single resource being shared. Ignored when `Contexts` is supplied. */
265
294
  Context = null;
295
+ /** Several resources to share at once; every action applies to all of them. */
296
+ Contexts = null;
266
297
  Adapter = null;
298
+ /** Singular noun for the title when sharing several ("3 conversations"). */
299
+ ResourceLabel = 'item';
300
+ /** Optional line shown above the dialog body — e.g. what the caller left out. */
301
+ Notice = null;
267
302
  Result = new EventEmitter();
268
303
  Levels = RESOURCE_SHARE_LEVELS;
269
- UserShares = [];
304
+ Grants = [];
270
305
  AvailableUsers = [];
271
306
  allUsers = [];
272
307
  IsLoading = false;
273
308
  Error = null;
274
309
  UserSearchFilter = '';
310
+ /** Every resource this dialog is operating on. */
311
+ get ActiveContexts() {
312
+ if (this.Contexts && this.Contexts.length > 0)
313
+ return this.Contexts;
314
+ return this.Context ? [this.Context] : [];
315
+ }
316
+ /** The resource whose owner row is shown — only meaningful for a single resource. */
317
+ get PrimaryContext() {
318
+ const contexts = this.ActiveContexts;
319
+ return contexts.length === 1 ? contexts[0] : null;
320
+ }
321
+ get Title() {
322
+ const contexts = this.ActiveContexts;
323
+ if (contexts.length === 1)
324
+ return `Share "${contexts[0].ResourceName}"`;
325
+ return `Share ${contexts.length} ${this.ResourceLabel}s`;
326
+ }
275
327
  /** Message for the no-results empty-state, echoing the current search term. */
276
328
  get NoUsersFoundMessage() {
277
329
  return `No users found matching "${this.UserSearchFilter}"`;
@@ -281,34 +333,29 @@ export class GenericShareDialogComponent extends BaseAngularComponent {
281
333
  this.cdr = cdr;
282
334
  }
283
335
  ngOnChanges(changes) {
284
- if (changes['Visible'] && this.Visible && this.Context && this.Adapter) {
336
+ if (changes['Visible'] && this.Visible && this.ActiveContexts.length > 0 && this.Adapter) {
285
337
  this.resetDialog();
286
- this.loadData();
338
+ void this.Reload();
287
339
  }
288
340
  }
289
341
  resetDialog() {
290
342
  this.Error = null;
291
343
  this.IsLoading = false;
292
- this.UserShares = [];
344
+ this.Grants = [];
293
345
  this.AvailableUsers = [];
294
346
  this.UserSearchFilter = '';
295
347
  }
296
- async loadData() {
297
- if (!this.Context || !this.Adapter)
348
+ /** Loads the people list and every resource's existing shares, merged per person. */
349
+ async Reload() {
350
+ const contexts = this.ActiveContexts;
351
+ if (contexts.length === 0 || !this.Adapter)
298
352
  return;
299
353
  this.IsLoading = true;
300
354
  this.cdr.detectChanges();
301
355
  try {
302
- const rv = RunView.FromMetadataProvider(this.ProviderToUse);
303
- const usersResult = await rv.RunView({
304
- EntityName: 'MJ: Users',
305
- ExtraFilter: 'IsActive = 1',
306
- OrderBy: 'Name',
307
- ResultType: 'entity_object'
308
- });
309
- this.allUsers = usersResult.Success ? usersResult.Results : [];
310
- this.UserShares = await this.Adapter.LoadShares(this.Context);
311
- this.UserShares.forEach((s) => (s._InitialLevel = s.Level));
356
+ await this.loadUsers();
357
+ const perResource = await Promise.all(contexts.map((ctx) => this.Adapter.LoadShares(ctx)));
358
+ this.Grants = this.mergeIntoGrants(contexts, perResource);
312
359
  this.updateAvailableUsers();
313
360
  }
314
361
  catch (error) {
@@ -320,17 +367,60 @@ export class GenericShareDialogComponent extends BaseAngularComponent {
320
367
  this.cdr.detectChanges();
321
368
  }
322
369
  }
370
+ async loadUsers() {
371
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
372
+ const usersResult = await rv.RunView({
373
+ EntityName: 'MJ: Users',
374
+ ExtraFilter: 'IsActive = 1',
375
+ OrderBy: 'Name',
376
+ ResultType: 'entity_object'
377
+ });
378
+ this.allUsers = usersResult.Success ? usersResult.Results : [];
379
+ }
380
+ /** One grant per person, carrying their row on each resource that has one. */
381
+ mergeIntoGrants(contexts, perResource) {
382
+ const byUser = new Map();
383
+ perResource.forEach((rows, index) => {
384
+ const resourceId = contexts[index].ResourceID;
385
+ for (const row of rows) {
386
+ row._InitialLevel = row.Level;
387
+ const key = row.UserID.toLowerCase();
388
+ const grant = byUser.get(key) ?? {
389
+ User: row.User,
390
+ UserID: row.UserID,
391
+ Rows: new Map(),
392
+ InitialLevel: row.Level,
393
+ Level: row.Level,
394
+ LevelTouched: false,
395
+ IsNew: false,
396
+ MarkedForRemoval: false
397
+ };
398
+ grant.Rows.set(resourceId, row);
399
+ if (grant.InitialLevel !== row.Level) {
400
+ grant.InitialLevel = null; // levels differ across resources
401
+ }
402
+ byUser.set(key, grant);
403
+ }
404
+ });
405
+ // A person on some but not all resources has no single level to show either.
406
+ for (const grant of byUser.values()) {
407
+ grant.Level = grant.InitialLevel ?? 'View';
408
+ }
409
+ return Array.from(byUser.values());
410
+ }
411
+ /** Everyone who owns none of the resources and doesn't already hold a (live) grant. */
323
412
  updateAvailableUsers() {
324
- if (!this.Context)
325
- return;
326
- const sharedUserIds = new Set(this.UserShares.filter((s) => !s.MarkedForRemoval).map((s) => s.User.ID));
327
- const ownerId = this.Context.OwnerUserID;
413
+ const sharedUserIds = new Set(this.Grants.filter((g) => !g.MarkedForRemoval).map((g) => g.User.ID));
414
+ const ownerIds = this.ActiveContexts
415
+ .map((ctx) => ctx.OwnerUserID)
416
+ .filter((id) => !!id);
328
417
  this.AvailableUsers = this.allUsers.filter((user) => {
329
- if (ownerId && UUIDsEqual(user.ID, ownerId))
418
+ if (ownerIds.some((ownerId) => UUIDsEqual(user.ID, ownerId)))
330
419
  return false;
331
420
  return !sharedUserIds.has(user.ID);
332
421
  });
333
422
  }
423
+ /** The first ten matches for the search box, or the first ten people. */
334
424
  get FilteredAvailableUsers() {
335
425
  if (!this.UserSearchFilter.trim()) {
336
426
  return this.AvailableUsers.slice(0, 10);
@@ -341,49 +431,84 @@ export class GenericShareDialogComponent extends BaseAngularComponent {
341
431
  .slice(0, 10);
342
432
  }
343
433
  get HasChanges() {
344
- return this.UserShares.some((s) => s.IsNew || s.MarkedForRemoval || s.Level !== s._InitialLevel);
434
+ return this.Grants.some((g) => g.IsNew || g.MarkedForRemoval || g.LevelTouched);
345
435
  }
346
436
  get ActiveShares() {
347
- return this.UserShares.filter((s) => !s.MarkedForRemoval);
437
+ return this.Grants.filter((g) => !g.MarkedForRemoval);
348
438
  }
349
439
  get RemovedShares() {
350
- return this.UserShares.filter((s) => s.MarkedForRemoval);
440
+ return this.Grants.filter((g) => g.MarkedForRemoval);
351
441
  }
352
- /** Highlight rows whose level has been changed from their loaded state. */
353
- isModified(share) {
354
- return !share.IsNew && share.Level !== share._InitialLevel;
442
+ /** Highlight grants whose level has been changed from their loaded state. */
443
+ IsModified(grant) {
444
+ return !grant.IsNew && grant.LevelTouched;
355
445
  }
356
- async addUserShare(user) {
357
- if (!this.Context || !this.Adapter)
446
+ /** A level button lights up only when the grant has one level to show. */
447
+ IsLevelActive(grant, level) {
448
+ if (!grant.LevelTouched && grant.InitialLevel === null && !grant.IsNew)
449
+ return false;
450
+ return grant.Level === level;
451
+ }
452
+ /**
453
+ * Why a grant does not simply read as "everyone, one level": levels that
454
+ * differ across resources, or access held on only some of them.
455
+ */
456
+ ScopeLabel(grant) {
457
+ if (grant.IsNew || this.ActiveContexts.length < 2)
458
+ return '';
459
+ const parts = [];
460
+ if (!grant.LevelTouched && grant.InitialLevel === null)
461
+ parts.push('Mixed');
462
+ if (grant.Rows.size < this.ActiveContexts.length) {
463
+ parts.push(`${grant.Rows.size} of ${this.ActiveContexts.length}`);
464
+ }
465
+ return parts.join(' · ');
466
+ }
467
+ /** Adds a person, to every resource the dialog is sharing. */
468
+ async AddUserShare(user) {
469
+ if (this.ActiveContexts.length === 0 || !this.Adapter)
358
470
  return;
359
- const row = await this.Adapter.CreateShare(this.Context, user);
360
- row._InitialLevel = row.Level;
361
- this.UserShares.push(row);
471
+ this.Grants = [
472
+ ...this.Grants,
473
+ {
474
+ User: user,
475
+ UserID: user.ID,
476
+ Rows: new Map(),
477
+ InitialLevel: null,
478
+ Level: 'View',
479
+ LevelTouched: false,
480
+ IsNew: true,
481
+ MarkedForRemoval: false
482
+ }
483
+ ];
362
484
  this.updateAvailableUsers();
363
485
  this.UserSearchFilter = '';
364
486
  this.cdr.detectChanges();
365
487
  }
366
- removeUserShare(share) {
367
- if (share.IsNew) {
368
- this.UserShares = this.UserShares.filter((s) => s !== share);
488
+ RemoveUserShare(grant) {
489
+ if (grant.IsNew) {
490
+ this.Grants = this.Grants.filter((g) => g !== grant);
369
491
  }
370
492
  else {
371
- share.MarkedForRemoval = true;
493
+ grant.MarkedForRemoval = true;
372
494
  }
373
495
  this.updateAvailableUsers();
374
496
  this.cdr.detectChanges();
375
497
  }
376
- undoRemove(share) {
377
- share.MarkedForRemoval = false;
498
+ UndoRemove(grant) {
499
+ grant.MarkedForRemoval = false;
378
500
  this.updateAvailableUsers();
379
501
  this.cdr.detectChanges();
380
502
  }
381
- setLevel(share, level) {
382
- share.Level = level;
503
+ /** Sets one level for the person across every resource, filling in any gaps. */
504
+ SetLevel(grant, level) {
505
+ grant.Level = level;
506
+ grant.LevelTouched = true;
383
507
  this.cdr.detectChanges();
384
508
  }
385
- async onSave() {
386
- if (!this.Adapter || !this.Context)
509
+ async OnSave() {
510
+ const contexts = this.ActiveContexts;
511
+ if (!this.Adapter || contexts.length === 0)
387
512
  return;
388
513
  if (!this.HasChanges) {
389
514
  this.onCancel();
@@ -393,22 +518,16 @@ export class GenericShareDialogComponent extends BaseAngularComponent {
393
518
  this.Error = null;
394
519
  this.cdr.detectChanges();
395
520
  try {
396
- for (const share of this.UserShares.filter((s) => s.MarkedForRemoval && !s.IsNew)) {
397
- const deleted = await share.PermissionEntity.Delete();
398
- if (!deleted) {
399
- throw new Error(`Failed to remove share for ${share.User.Name}: ${share.PermissionEntity.LatestResult?.Message ?? 'unknown error'}`);
400
- }
521
+ for (const grant of this.Grants.filter((g) => g.MarkedForRemoval && !g.IsNew)) {
522
+ await this.withdrawGrant(grant);
401
523
  }
402
- const dirtyRows = this.UserShares.filter((s) => !s.MarkedForRemoval && (s.IsNew || s.Level !== s._InitialLevel));
403
- for (const share of dirtyRows) {
404
- this.Adapter.SyncLevelToEntity(share);
405
- const saved = await share.PermissionEntity.Save();
406
- if (!saved) {
407
- throw new Error(`Failed to save share for ${share.User.Name}: ${share.PermissionEntity.LatestResult?.Message ?? 'unknown error'}`);
408
- }
524
+ for (const grant of this.Grants.filter((g) => !g.MarkedForRemoval && (g.IsNew || g.LevelTouched))) {
525
+ await this.applyGrant(grant, contexts);
409
526
  }
410
527
  if (this.Adapter.AfterSave) {
411
- await this.Adapter.AfterSave(this.Context);
528
+ for (const context of contexts) {
529
+ await this.Adapter.AfterSave(context);
530
+ }
412
531
  }
413
532
  this.Result.emit({ Action: 'save' });
414
533
  }
@@ -421,10 +540,49 @@ export class GenericShareDialogComponent extends BaseAngularComponent {
421
540
  this.cdr.detectChanges();
422
541
  }
423
542
  }
543
+ /**
544
+ * Withdraws a person's access from every resource that granted it. Each row
545
+ * leaves the grant once deleted, so a retry after a failure deletes only the
546
+ * rows still left.
547
+ */
548
+ async withdrawGrant(grant) {
549
+ for (const [resourceId, row] of Array.from(grant.Rows.entries())) {
550
+ const deleted = await row.PermissionEntity.Delete();
551
+ if (!deleted) {
552
+ throw new Error(`Failed to remove share for ${grant.User.Name}: ${row.PermissionEntity.LatestResult?.CompleteMessage ?? 'unknown error'}`);
553
+ }
554
+ grant.Rows.delete(resourceId);
555
+ }
556
+ }
557
+ /**
558
+ * Writes the grant's level to every resource, creating a permission row for
559
+ * the ones this person did not already have access to. A row stays `IsNew`
560
+ * until it saves, so a retry after a failure saves the rows still unsaved.
561
+ */
562
+ async applyGrant(grant, contexts) {
563
+ for (const context of contexts) {
564
+ let row = grant.Rows.get(context.ResourceID);
565
+ if (!row) {
566
+ row = await this.Adapter.CreateShare(context, grant.User);
567
+ row._InitialLevel = row.Level;
568
+ grant.Rows.set(context.ResourceID, row);
569
+ }
570
+ else if (!grant.LevelTouched && !row.IsNew) {
571
+ continue; // nothing changed for this resource
572
+ }
573
+ row.Level = grant.Level;
574
+ this.Adapter.SyncLevelToEntity(row);
575
+ const saved = await row.PermissionEntity.Save();
576
+ if (!saved) {
577
+ throw new Error(`Failed to save share for ${grant.User.Name}: ${row.PermissionEntity.LatestResult?.CompleteMessage ?? 'unknown error'}`);
578
+ }
579
+ row.IsNew = false;
580
+ }
581
+ }
424
582
  onCancel() {
425
583
  this.Result.emit({ Action: 'cancel' });
426
584
  }
427
- getUserInitials(user) {
585
+ GetUserInitials(user) {
428
586
  const name = user.Name || user.Email || '?';
429
587
  const parts = name.split(' ');
430
588
  if (parts.length >= 2) {
@@ -432,24 +590,58 @@ export class GenericShareDialogComponent extends BaseAngularComponent {
432
590
  }
433
591
  return name.substring(0, 2).toUpperCase();
434
592
  }
593
+ /** @deprecated Use {@link IsModified}. */
594
+ isModified(grant) {
595
+ return this.IsModified(grant);
596
+ }
597
+ /** @deprecated Use {@link AddUserShare}. */
598
+ async addUserShare(user) {
599
+ return this.AddUserShare(user);
600
+ }
601
+ /** @deprecated Use {@link RemoveUserShare}. */
602
+ removeUserShare(grant) {
603
+ return this.RemoveUserShare(grant);
604
+ }
605
+ /** @deprecated Use {@link UndoRemove}. */
606
+ undoRemove(grant) {
607
+ return this.UndoRemove(grant);
608
+ }
609
+ /** @deprecated Use {@link SetLevel}. */
610
+ setLevel(grant, level) {
611
+ return this.SetLevel(grant, level);
612
+ }
613
+ /** @deprecated Use {@link OnSave}. */
614
+ async onSave() {
615
+ return this.OnSave();
616
+ }
617
+ /** @deprecated Use {@link GetUserInitials}. */
618
+ getUserInitials(user) {
619
+ return this.GetUserInitials(user);
620
+ }
435
621
  static ɵfac = function GenericShareDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || GenericShareDialogComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
436
- 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.ɵɵInheritDefinitionFeature, 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) {
437
- i0.ɵɵconditionalCreate(0, GenericShareDialogComponent_Conditional_0_Template, 30, 17, "mj-window", 0);
622
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: GenericShareDialogComponent, selectors: [["mj-resource-share-dialog"]], inputs: { Visible: "Visible", Context: "Context", Contexts: "Contexts", Adapter: "Adapter", ResourceLabel: "ResourceLabel", Notice: "Notice" }, outputs: { Result: "Result" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, 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-notice"], [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"], [1, "fa-solid", "fa-circle-info"], ["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"], [1, "share-person-scope"], ["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) {
623
+ i0.ɵɵconditionalCreate(0, GenericShareDialogComponent_Conditional_0_Template, 31, 18, "mj-window", 0);
438
624
  } if (rf & 2) {
439
625
  i0.ɵɵconditional(ctx.Visible ? 0 : -1);
440
- } }, 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 });
626
+ } }, 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\n/* Caller-supplied line above the body \u2014 e.g. what a bulk share left out. */\n.mj-share-dialog-window .share-notice {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 8px 12px;\n margin-bottom: 12px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, transparent);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n/* Why a grant is not simply \"everyone, one level\": mixed levels or partial coverage. */\n.mj-share-dialog-window .share-person-scope {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n"], encapsulation: 2 });
441
627
  }
442
628
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(GenericShareDialogComponent, [{
443
629
  type: Component,
444
- 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"] }]
630
+ 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>{{ Title }}</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 @if (Notice) {\n <div class=\"share-notice\">\n <i class=\"fa-solid fa-circle-info\"></i>\n <span>{{ Notice }}</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 <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 (PrimaryContext?.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\">{{ PrimaryContext?.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 @if (ScopeLabel(share)) {\n <span class=\"share-person-scope\">{{ ScopeLabel(share) }}</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]=\"IsLevelActive(share, 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\n/* Caller-supplied line above the body \u2014 e.g. what a bulk share left out. */\n.mj-share-dialog-window .share-notice {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 8px 12px;\n margin-bottom: 12px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, transparent);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n/* Why a grant is not simply \"everyone, one level\": mixed levels or partial coverage. */\n.mj-share-dialog-window .share-person-scope {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n"] }]
445
631
  }], () => [{ type: i0.ChangeDetectorRef }], { Visible: [{
446
632
  type: Input
447
633
  }], Context: [{
448
634
  type: Input
635
+ }], Contexts: [{
636
+ type: Input
449
637
  }], Adapter: [{
450
638
  type: Input
639
+ }], ResourceLabel: [{
640
+ type: Input
641
+ }], Notice: [{
642
+ type: Input
451
643
  }], Result: [{
452
644
  type: Output
453
645
  }] }); })();
454
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(GenericShareDialogComponent, { className: "GenericShareDialogComponent", filePath: "src/lib/resource-share-dialog.component.ts", lineNumber: 34 }); })();
646
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(GenericShareDialogComponent, { className: "GenericShareDialogComponent", filePath: "src/lib/resource-share-dialog.component.ts", lineNumber: 35 }); })();
455
647
  //# sourceMappingURL=resource-share-dialog.component.js.map