@idp.global/catalog 2.0.0 → 2.1.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.
Files changed (70) hide show
  1. package/changelog.md +27 -0
  2. package/dist_bundle/bundle.js +3726 -1337
  3. package/dist_ts_web/00_commitinfo_data.js +1 -1
  4. package/dist_ts_web/elements/idp-admin-overview.d.ts +28 -0
  5. package/dist_ts_web/elements/idp-admin-overview.js +460 -0
  6. package/dist_ts_web/elements/idp-admin-shared.d.ts +18 -0
  7. package/dist_ts_web/elements/idp-admin-shared.js +404 -0
  8. package/dist_ts_web/elements/idp-admin-shell.d.ts +96 -11
  9. package/dist_ts_web/elements/idp-admin-shell.js +442 -816
  10. package/dist_ts_web/elements/idp-admin-sidebar.d.ts +42 -0
  11. package/dist_ts_web/elements/idp-admin-sidebar.js +702 -0
  12. package/dist_ts_web/elements/idp-app-pair.d.ts +19 -0
  13. package/dist_ts_web/elements/idp-app-pair.js +187 -0
  14. package/dist_ts_web/elements/idp-auth-card.d.ts +17 -0
  15. package/dist_ts_web/elements/idp-auth-card.js +180 -0
  16. package/dist_ts_web/elements/idp-avatar.d.ts +17 -0
  17. package/dist_ts_web/elements/idp-avatar.js +151 -0
  18. package/dist_ts_web/elements/idp-badge.d.ts +2 -0
  19. package/dist_ts_web/elements/idp-badge.js +12 -3
  20. package/dist_ts_web/elements/idp-brand-mark.d.ts +16 -0
  21. package/dist_ts_web/elements/idp-brand-mark.js +139 -0
  22. package/dist_ts_web/elements/idp-button.d.ts +3 -0
  23. package/dist_ts_web/elements/idp-button.js +47 -3
  24. package/dist_ts_web/elements/idp-consent-card.d.ts +34 -0
  25. package/dist_ts_web/elements/idp-consent-card.js +217 -0
  26. package/dist_ts_web/elements/idp-delegation-section.d.ts +59 -0
  27. package/dist_ts_web/elements/idp-delegation-section.js +609 -0
  28. package/dist_ts_web/elements/idp-form-submit.d.ts +2 -1
  29. package/dist_ts_web/elements/idp-form-submit.js +11 -2
  30. package/dist_ts_web/elements/idp-form.js +2 -2
  31. package/dist_ts_web/elements/idp-input.d.ts +4 -0
  32. package/dist_ts_web/elements/idp-input.js +68 -15
  33. package/dist_ts_web/elements/idp-option-row.d.ts +25 -0
  34. package/dist_ts_web/elements/idp-option-row.js +267 -0
  35. package/dist_ts_web/elements/idp-otp-input.d.ts +32 -0
  36. package/dist_ts_web/elements/idp-otp-input.js +274 -0
  37. package/dist_ts_web/elements/idp-progress-bar.d.ts +14 -0
  38. package/dist_ts_web/elements/idp-progress-bar.js +127 -0
  39. package/dist_ts_web/elements/idp-signed-in-pill.d.ts +15 -0
  40. package/dist_ts_web/elements/idp-signed-in-pill.js +113 -0
  41. package/dist_ts_web/elements/idp-spinner.d.ts +13 -0
  42. package/dist_ts_web/elements/idp-spinner.js +109 -0
  43. package/dist_ts_web/elements/idp-status-icon.d.ts +18 -0
  44. package/dist_ts_web/elements/idp-status-icon.js +136 -0
  45. package/dist_ts_web/elements/index.d.ts +15 -0
  46. package/dist_ts_web/elements/index.js +16 -1
  47. package/package.json +2 -2
  48. package/ts_web/00_commitinfo_data.ts +1 -1
  49. package/ts_web/elements/idp-admin-overview.ts +388 -0
  50. package/ts_web/elements/idp-admin-shared.ts +419 -0
  51. package/ts_web/elements/idp-admin-shell.ts +514 -871
  52. package/ts_web/elements/idp-admin-sidebar.ts +648 -0
  53. package/ts_web/elements/idp-app-pair.ts +120 -0
  54. package/ts_web/elements/idp-auth-card.ts +113 -0
  55. package/ts_web/elements/idp-avatar.ts +84 -0
  56. package/ts_web/elements/idp-badge.ts +5 -1
  57. package/ts_web/elements/idp-brand-mark.ts +76 -0
  58. package/ts_web/elements/idp-button.ts +36 -1
  59. package/ts_web/elements/idp-consent-card.ts +146 -0
  60. package/ts_web/elements/idp-delegation-section.ts +576 -0
  61. package/ts_web/elements/idp-form-submit.ts +5 -1
  62. package/ts_web/elements/idp-form.ts +1 -1
  63. package/ts_web/elements/idp-input.ts +58 -13
  64. package/ts_web/elements/idp-option-row.ts +184 -0
  65. package/ts_web/elements/idp-otp-input.ts +204 -0
  66. package/ts_web/elements/idp-progress-bar.ts +69 -0
  67. package/ts_web/elements/idp-signed-in-pill.ts +55 -0
  68. package/ts_web/elements/idp-spinner.ts +56 -0
  69. package/ts_web/elements/idp-status-icon.ts +76 -0
  70. package/ts_web/elements/index.ts +15 -0
@@ -0,0 +1,59 @@
1
+ import { DeesElement, type TemplateResult } from '@design.estate/dees-element';
2
+ import './idp-avatar.js';
3
+ import './idp-button.js';
4
+ import './idp-icon.js';
5
+ export interface IIdpDelegationPermission {
6
+ id: string;
7
+ label: string;
8
+ hint: string;
9
+ }
10
+ export interface IIdpDelegationApp {
11
+ id: string;
12
+ name: string;
13
+ perms: IIdpDelegationPermission[];
14
+ }
15
+ export interface IIdpDelegation {
16
+ id: string;
17
+ account: {
18
+ name: string;
19
+ email: string;
20
+ };
21
+ grants: Record<string, string[]>;
22
+ expiresAt: number | null;
23
+ createdAt: number;
24
+ }
25
+ export interface IIdpDelegationGrantEventDetail {
26
+ email: string;
27
+ grants: Record<string, string[]>;
28
+ expiryDays: number | null;
29
+ }
30
+ export interface IIdpDelegationRevokeEventDetail {
31
+ delegationId: string;
32
+ }
33
+ declare global {
34
+ interface HTMLElementTagNameMap {
35
+ 'idp-delegation-section': IdpDelegationSection;
36
+ }
37
+ }
38
+ export declare class IdpDelegationSection extends DeesElement {
39
+ static demo: () => TemplateResult<1>;
40
+ static demoGroups: string[];
41
+ accessor apps: IIdpDelegationApp[];
42
+ accessor delegations: IIdpDelegation[];
43
+ private accessor grantOpen;
44
+ private accessor grantEmail;
45
+ private accessor grantSelections;
46
+ private accessor grantExpiry;
47
+ static styles: import("@design.estate/dees-element").CSSResult[];
48
+ private expiryLabel;
49
+ render(): TemplateResult;
50
+ private renderDelegationRow;
51
+ private renderGrantModal;
52
+ private renderGrantAppRow;
53
+ private openGrant;
54
+ private closeGrant;
55
+ private toggleGrantApp;
56
+ private toggleGrantPerm;
57
+ private submitGrant;
58
+ private revoke;
59
+ }
@@ -0,0 +1,609 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { DeesElement, html, property, state, customElement, css } from '@design.estate/dees-element';
36
+ import { idpElementStyles } from './tokens.js';
37
+ import './idp-avatar.js';
38
+ import './idp-button.js';
39
+ import './idp-icon.js';
40
+ const demoApps = [
41
+ {
42
+ id: 'foss',
43
+ name: 'foss.global',
44
+ perms: [
45
+ { id: 'projects:read', label: 'View projects', hint: 'Read-only access to your projects' },
46
+ { id: 'projects:write', label: 'Manage projects', hint: 'Create, edit and archive projects' },
47
+ { id: 'billing:read', label: 'View billing', hint: 'See invoices and payment history' },
48
+ ],
49
+ },
50
+ {
51
+ id: 'task',
52
+ name: 'task.vc',
53
+ perms: [
54
+ { id: 'tasks:read', label: 'View tasks', hint: 'See your tasks and boards' },
55
+ { id: 'tasks:write', label: 'Act on tasks', hint: 'Create, assign and complete tasks as you' },
56
+ ],
57
+ },
58
+ ];
59
+ const demoDelegations = [
60
+ {
61
+ id: 'd1',
62
+ account: { name: 'Jordan Kim', email: 'jordan@lossless.com' },
63
+ grants: { task: ['tasks:read', 'tasks:write'] },
64
+ expiresAt: Date.now() + 86400000 * 24,
65
+ createdAt: Date.now() - 86400000 * 6,
66
+ },
67
+ {
68
+ id: 'd2',
69
+ account: { name: 'Sam Rivera', email: 'sam@lossless.com' },
70
+ grants: { foss: ['billing:read'] },
71
+ expiresAt: null,
72
+ createdAt: Date.now() - 86400000 * 40,
73
+ },
74
+ ];
75
+ let IdpDelegationSection = (() => {
76
+ let _classDecorators = [customElement('idp-delegation-section')];
77
+ let _classDescriptor;
78
+ let _classExtraInitializers = [];
79
+ let _classThis;
80
+ let _classSuper = DeesElement;
81
+ let _apps_decorators;
82
+ let _apps_initializers = [];
83
+ let _apps_extraInitializers = [];
84
+ let _delegations_decorators;
85
+ let _delegations_initializers = [];
86
+ let _delegations_extraInitializers = [];
87
+ let _grantOpen_decorators;
88
+ let _grantOpen_initializers = [];
89
+ let _grantOpen_extraInitializers = [];
90
+ let _grantEmail_decorators;
91
+ let _grantEmail_initializers = [];
92
+ let _grantEmail_extraInitializers = [];
93
+ let _grantSelections_decorators;
94
+ let _grantSelections_initializers = [];
95
+ let _grantSelections_extraInitializers = [];
96
+ let _grantExpiry_decorators;
97
+ let _grantExpiry_initializers = [];
98
+ let _grantExpiry_extraInitializers = [];
99
+ var IdpDelegationSection = class extends _classSuper {
100
+ static { _classThis = this; }
101
+ static {
102
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
103
+ _apps_decorators = [property({ type: Array })];
104
+ _delegations_decorators = [property({ type: Array })];
105
+ _grantOpen_decorators = [state()];
106
+ _grantEmail_decorators = [state()];
107
+ _grantSelections_decorators = [state()];
108
+ _grantExpiry_decorators = [state()];
109
+ __esDecorate(this, null, _apps_decorators, { kind: "accessor", name: "apps", static: false, private: false, access: { has: obj => "apps" in obj, get: obj => obj.apps, set: (obj, value) => { obj.apps = value; } }, metadata: _metadata }, _apps_initializers, _apps_extraInitializers);
110
+ __esDecorate(this, null, _delegations_decorators, { kind: "accessor", name: "delegations", static: false, private: false, access: { has: obj => "delegations" in obj, get: obj => obj.delegations, set: (obj, value) => { obj.delegations = value; } }, metadata: _metadata }, _delegations_initializers, _delegations_extraInitializers);
111
+ __esDecorate(this, null, _grantOpen_decorators, { kind: "accessor", name: "grantOpen", static: false, private: false, access: { has: obj => "grantOpen" in obj, get: obj => obj.grantOpen, set: (obj, value) => { obj.grantOpen = value; } }, metadata: _metadata }, _grantOpen_initializers, _grantOpen_extraInitializers);
112
+ __esDecorate(this, null, _grantEmail_decorators, { kind: "accessor", name: "grantEmail", static: false, private: false, access: { has: obj => "grantEmail" in obj, get: obj => obj.grantEmail, set: (obj, value) => { obj.grantEmail = value; } }, metadata: _metadata }, _grantEmail_initializers, _grantEmail_extraInitializers);
113
+ __esDecorate(this, null, _grantSelections_decorators, { kind: "accessor", name: "grantSelections", static: false, private: false, access: { has: obj => "grantSelections" in obj, get: obj => obj.grantSelections, set: (obj, value) => { obj.grantSelections = value; } }, metadata: _metadata }, _grantSelections_initializers, _grantSelections_extraInitializers);
114
+ __esDecorate(this, null, _grantExpiry_decorators, { kind: "accessor", name: "grantExpiry", static: false, private: false, access: { has: obj => "grantExpiry" in obj, get: obj => obj.grantExpiry, set: (obj, value) => { obj.grantExpiry = value; } }, metadata: _metadata }, _grantExpiry_initializers, _grantExpiry_extraInitializers);
115
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
116
+ IdpDelegationSection = _classThis = _classDescriptor.value;
117
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
118
+ }
119
+ static demo = () => html `
120
+ <div style="max-width: 640px;">
121
+ <idp-delegation-section .apps=${demoApps} .delegations=${demoDelegations}></idp-delegation-section>
122
+ </div>
123
+ `;
124
+ static demoGroups = ['idp.global v5 composed surfaces'];
125
+ #apps_accessor_storage = __runInitializers(this, _apps_initializers, []);
126
+ get apps() { return this.#apps_accessor_storage; }
127
+ set apps(value) { this.#apps_accessor_storage = value; }
128
+ #delegations_accessor_storage = (__runInitializers(this, _apps_extraInitializers), __runInitializers(this, _delegations_initializers, []));
129
+ get delegations() { return this.#delegations_accessor_storage; }
130
+ set delegations(value) { this.#delegations_accessor_storage = value; }
131
+ #grantOpen_accessor_storage = (__runInitializers(this, _delegations_extraInitializers), __runInitializers(this, _grantOpen_initializers, false));
132
+ get grantOpen() { return this.#grantOpen_accessor_storage; }
133
+ set grantOpen(value) { this.#grantOpen_accessor_storage = value; }
134
+ #grantEmail_accessor_storage = (__runInitializers(this, _grantOpen_extraInitializers), __runInitializers(this, _grantEmail_initializers, ''));
135
+ get grantEmail() { return this.#grantEmail_accessor_storage; }
136
+ set grantEmail(value) { this.#grantEmail_accessor_storage = value; }
137
+ #grantSelections_accessor_storage = (__runInitializers(this, _grantEmail_extraInitializers), __runInitializers(this, _grantSelections_initializers, {}));
138
+ get grantSelections() { return this.#grantSelections_accessor_storage; }
139
+ set grantSelections(value) { this.#grantSelections_accessor_storage = value; }
140
+ #grantExpiry_accessor_storage = (__runInitializers(this, _grantSelections_extraInitializers), __runInitializers(this, _grantExpiry_initializers, '30'));
141
+ get grantExpiry() { return this.#grantExpiry_accessor_storage; }
142
+ set grantExpiry(value) { this.#grantExpiry_accessor_storage = value; }
143
+ static styles = [
144
+ ...idpElementStyles,
145
+ css `
146
+ :host {
147
+ display: block;
148
+ font-family: var(--idp-font);
149
+ color: var(--idp-fg);
150
+ }
151
+ .section {
152
+ background: var(--idp-card);
153
+ border: 1px solid var(--idp-border);
154
+ border-radius: var(--idp-radius);
155
+ padding: 20px;
156
+ }
157
+ .headline {
158
+ display: flex;
159
+ align-items: flex-start;
160
+ justify-content: space-between;
161
+ gap: 16px;
162
+ margin-bottom: 16px;
163
+ }
164
+ .title {
165
+ font-size: 14px;
166
+ font-weight: 600;
167
+ }
168
+ .muted {
169
+ font-size: 12.5px;
170
+ color: var(--idp-muted-fg);
171
+ line-height: 1.5;
172
+ margin-top: 3px;
173
+ }
174
+ .row {
175
+ padding: 12px 0;
176
+ border-bottom: 1px solid var(--idp-border);
177
+ }
178
+ .row:last-of-type {
179
+ border-bottom: none;
180
+ }
181
+ .row-head {
182
+ display: flex;
183
+ align-items: center;
184
+ gap: 10px;
185
+ }
186
+ .row-name {
187
+ font-size: 13px;
188
+ font-weight: 500;
189
+ }
190
+ .row-email {
191
+ font-size: 11px;
192
+ color: var(--idp-muted-fg);
193
+ }
194
+ .row-expiry {
195
+ font-size: 11px;
196
+ color: var(--idp-muted-fg);
197
+ white-space: nowrap;
198
+ }
199
+ .revoke {
200
+ background: none;
201
+ border: none;
202
+ cursor: pointer;
203
+ font-family: inherit;
204
+ font-size: 11px;
205
+ font-weight: 500;
206
+ color: var(--idp-destructive);
207
+ padding: 4px 8px;
208
+ border-radius: 6px;
209
+ }
210
+ .revoke:hover {
211
+ background: var(--idp-error-bg);
212
+ }
213
+ .grant-chips {
214
+ display: flex;
215
+ flex-wrap: wrap;
216
+ gap: 6px;
217
+ margin: 8px 0 0 40px;
218
+ }
219
+ .grant-chip {
220
+ display: flex;
221
+ align-items: center;
222
+ gap: 6px;
223
+ border: 1px solid var(--idp-border);
224
+ border-radius: 7px;
225
+ padding: 3px 8px 3px 4px;
226
+ background: var(--idp-muted);
227
+ }
228
+ .grant-chip-tile {
229
+ width: 18px;
230
+ height: 18px;
231
+ border-radius: 4px;
232
+ background: var(--idp-accent-soft);
233
+ display: flex;
234
+ align-items: center;
235
+ justify-content: center;
236
+ font-size: 8px;
237
+ font-weight: 700;
238
+ color: var(--idp-accent);
239
+ flex-shrink: 0;
240
+ }
241
+ .grant-chip-name {
242
+ font-size: 11px;
243
+ font-weight: 500;
244
+ }
245
+ .grant-chip-perms {
246
+ font-size: 10.5px;
247
+ color: var(--idp-muted-fg);
248
+ font-family: var(--idp-mono);
249
+ }
250
+ .empty {
251
+ font-size: 12.5px;
252
+ color: var(--idp-muted-fg);
253
+ padding: 4px 0;
254
+ }
255
+ .backdrop {
256
+ position: fixed;
257
+ inset: 0;
258
+ background: rgba(0, 0, 0, 0.4);
259
+ display: flex;
260
+ align-items: center;
261
+ justify-content: center;
262
+ z-index: 9990;
263
+ }
264
+ .modal {
265
+ width: 460px;
266
+ max-width: calc(100vw - 32px);
267
+ max-height: calc(100vh - 80px);
268
+ overflow: auto;
269
+ background: var(--idp-card);
270
+ border: 1px solid var(--idp-border);
271
+ border-radius: 12px;
272
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
273
+ }
274
+ .modal-head {
275
+ display: flex;
276
+ align-items: center;
277
+ justify-content: space-between;
278
+ padding: 16px 20px;
279
+ border-bottom: 1px solid var(--idp-border);
280
+ font-size: 15px;
281
+ font-weight: 600;
282
+ }
283
+ .modal-close {
284
+ background: none;
285
+ border: none;
286
+ cursor: pointer;
287
+ color: var(--idp-muted-fg);
288
+ display: flex;
289
+ padding: 2px;
290
+ }
291
+ .modal-body {
292
+ padding: 20px;
293
+ }
294
+ .field-label {
295
+ font-size: 12px;
296
+ font-weight: 500;
297
+ margin-bottom: 4px;
298
+ }
299
+ .field-label .req {
300
+ color: var(--idp-destructive);
301
+ }
302
+ input[type='email'] {
303
+ width: 100%;
304
+ height: 34px;
305
+ box-sizing: border-box;
306
+ padding: 0 10px;
307
+ font-size: 13px;
308
+ font-family: inherit;
309
+ color: var(--idp-fg);
310
+ background: var(--idp-bg);
311
+ border: 1px solid var(--idp-border);
312
+ border-radius: 8px;
313
+ outline: none;
314
+ }
315
+ input[type='email']:focus {
316
+ border-color: var(--idp-accent);
317
+ }
318
+ .apps-box {
319
+ border: 1px solid var(--idp-border);
320
+ border-radius: 10px;
321
+ overflow: hidden;
322
+ margin-bottom: 14px;
323
+ }
324
+ .app-row {
325
+ border-bottom: 1px solid var(--idp-border);
326
+ }
327
+ .app-row:last-child {
328
+ border-bottom: none;
329
+ }
330
+ .app-head {
331
+ display: flex;
332
+ align-items: center;
333
+ gap: 10px;
334
+ padding: 10px 12px;
335
+ cursor: pointer;
336
+ }
337
+ .app-head.enabled {
338
+ background: var(--idp-muted);
339
+ }
340
+ .app-tile {
341
+ width: 22px;
342
+ height: 22px;
343
+ border-radius: 6px;
344
+ background: var(--idp-accent-soft);
345
+ border: 1px solid var(--idp-border);
346
+ display: flex;
347
+ align-items: center;
348
+ justify-content: center;
349
+ font-size: 9px;
350
+ font-weight: 700;
351
+ color: var(--idp-accent);
352
+ flex-shrink: 0;
353
+ }
354
+ .app-name {
355
+ flex: 1;
356
+ font-size: 13px;
357
+ font-weight: 500;
358
+ }
359
+ .app-count {
360
+ font-size: 10.5px;
361
+ color: var(--idp-muted-fg);
362
+ }
363
+ .perm-list {
364
+ display: flex;
365
+ flex-direction: column;
366
+ gap: 2px;
367
+ padding: 2px 12px 10px 36px;
368
+ }
369
+ .perm-row {
370
+ display: flex;
371
+ align-items: flex-start;
372
+ gap: 9px;
373
+ padding: 5px 0;
374
+ cursor: pointer;
375
+ }
376
+ .perm-label {
377
+ font-size: 12.5px;
378
+ }
379
+ .perm-hint {
380
+ display: block;
381
+ font-size: 11px;
382
+ color: var(--idp-muted-fg);
383
+ }
384
+ .perm-id {
385
+ font-size: 10px;
386
+ color: var(--idp-muted-fg);
387
+ font-family: var(--idp-mono);
388
+ margin-top: 2px;
389
+ }
390
+ input[type='checkbox'] {
391
+ accent-color: var(--idp-accent);
392
+ margin: 2px 0 0;
393
+ cursor: pointer;
394
+ }
395
+ .modal-actions {
396
+ display: flex;
397
+ gap: 8px;
398
+ justify-content: flex-end;
399
+ margin-top: 18px;
400
+ }
401
+ .expiry-select {
402
+ width: 100%;
403
+ height: 34px;
404
+ padding: 0 10px;
405
+ font-size: 13px;
406
+ font-family: inherit;
407
+ color: var(--idp-fg);
408
+ background: var(--idp-bg);
409
+ border: 1px solid var(--idp-border);
410
+ border-radius: 8px;
411
+ outline: none;
412
+ cursor: pointer;
413
+ }
414
+ `,
415
+ ];
416
+ expiryLabel(expiresAtArg) {
417
+ if (!expiresAtArg) {
418
+ return 'Until revoked';
419
+ }
420
+ const days = Math.max(0, Math.round((expiresAtArg - Date.now()) / 86400000));
421
+ return days === 0 ? 'Expires today' : `Expires in ${days}d`;
422
+ }
423
+ render() {
424
+ return html `
425
+ <section class="section">
426
+ <div class="headline">
427
+ <div>
428
+ <div class="title">Delegated access</div>
429
+ <div class="muted">Let other idp.global accounts act on your behalf — scoped to specific apps and app-specific permissions.</div>
430
+ </div>
431
+ <idp-button variant="outline" size="sm" @click=${() => this.openGrant()}>Delegate access</idp-button>
432
+ </div>
433
+ ${this.delegations.length
434
+ ? this.delegations.map((delegationArg) => this.renderDelegationRow(delegationArg))
435
+ : html `<div class="empty">No delegations yet. Access you grant here can be revoked at any time.</div>`}
436
+ </section>
437
+ ${this.grantOpen ? this.renderGrantModal() : html ``}
438
+ `;
439
+ }
440
+ renderDelegationRow(delegationArg) {
441
+ const grantedApps = Object.keys(delegationArg.grants);
442
+ return html `
443
+ <div class="row">
444
+ <div class="row-head">
445
+ <idp-avatar name=${delegationArg.account.name} size="30"></idp-avatar>
446
+ <div style="flex:1;min-width:0">
447
+ <div class="row-name">${delegationArg.account.name}</div>
448
+ <div class="row-email">${delegationArg.account.email}</div>
449
+ </div>
450
+ <span class="row-expiry">${this.expiryLabel(delegationArg.expiresAt)}</span>
451
+ <button class="revoke" @click=${() => this.revoke(delegationArg.id)}>Revoke</button>
452
+ </div>
453
+ <div class="grant-chips">
454
+ ${grantedApps.map((appIdArg) => {
455
+ const app = this.apps.find((appArg) => appArg.id === appIdArg);
456
+ if (!app) {
457
+ return html ``;
458
+ }
459
+ return html `
460
+ <span class="grant-chip">
461
+ <span class="grant-chip-tile">${app.name.slice(0, 2).toUpperCase()}</span>
462
+ <span class="grant-chip-name">${app.name}</span>
463
+ <span class="grant-chip-perms">${delegationArg.grants[appIdArg].join(' · ')}</span>
464
+ </span>
465
+ `;
466
+ })}
467
+ </div>
468
+ </div>
469
+ `;
470
+ }
471
+ renderGrantModal() {
472
+ const valid = /.+@.+\..+/.test(this.grantEmail)
473
+ && Object.values(this.grantSelections).some((permsArg) => permsArg.length > 0);
474
+ return html `
475
+ <div class="backdrop" @click=${(eventArg) => { if (eventArg.target === eventArg.currentTarget)
476
+ this.closeGrant(); }}>
477
+ <div class="modal">
478
+ <div class="modal-head">
479
+ <span>Delegate access</span>
480
+ <button class="modal-close" @click=${() => this.closeGrant()}><idp-icon name="x" size="16"></idp-icon></button>
481
+ </div>
482
+ <div class="modal-body">
483
+ <div class="muted" style="margin: 0 0 14px;">
484
+ The delegate signs in with their own idp.global account and can act on your behalf — only in the apps and permissions you pick here. They never see your credentials.
485
+ </div>
486
+ <div style="margin-bottom: 14px;">
487
+ <div class="field-label">Account email <span class="req">*</span></div>
488
+ <input
489
+ type="email"
490
+ placeholder="colleague@company.com"
491
+ .value=${this.grantEmail}
492
+ @input=${(eventArg) => { this.grantEmail = eventArg.target.value; }}
493
+ />
494
+ </div>
495
+ <div class="field-label">Apps &amp; permissions <span class="req">*</span></div>
496
+ <div class="apps-box">
497
+ ${this.apps.map((appArg) => this.renderGrantAppRow(appArg))}
498
+ </div>
499
+ <div style="margin-bottom: 18px;">
500
+ <div class="field-label">Access expires</div>
501
+ <select class="expiry-select" .value=${this.grantExpiry} @change=${(eventArg) => { this.grantExpiry = eventArg.target.value; }}>
502
+ <option value="7">7 days</option>
503
+ <option value="30">30 days</option>
504
+ <option value="90">90 days</option>
505
+ <option value="">Until revoked</option>
506
+ </select>
507
+ </div>
508
+ <div class="modal-actions">
509
+ <idp-button variant="outline" size="sm" @click=${() => this.closeGrant()}>Cancel</idp-button>
510
+ <idp-button variant="accent" size="sm" ?disabled=${!valid} @click=${() => this.submitGrant()}>Grant access</idp-button>
511
+ </div>
512
+ </div>
513
+ </div>
514
+ </div>
515
+ `;
516
+ }
517
+ renderGrantAppRow(appArg) {
518
+ const enabled = !!this.grantSelections[appArg.id];
519
+ const selected = this.grantSelections[appArg.id] || [];
520
+ return html `
521
+ <div class="app-row">
522
+ <label class="app-head ${enabled ? 'enabled' : ''}">
523
+ <input type="checkbox" .checked=${enabled} @change=${() => this.toggleGrantApp(appArg.id)} />
524
+ <span class="app-tile">${appArg.name.slice(0, 2).toUpperCase()}</span>
525
+ <span class="app-name">${appArg.name}</span>
526
+ ${enabled ? html `<span class="app-count">${selected.length} of ${appArg.perms.length} permissions</span>` : html ``}
527
+ </label>
528
+ ${enabled
529
+ ? html `
530
+ <div class="perm-list">
531
+ ${appArg.perms.map((permArg) => html `
532
+ <label class="perm-row">
533
+ <input
534
+ type="checkbox"
535
+ .checked=${selected.includes(permArg.id)}
536
+ @change=${() => this.toggleGrantPerm(appArg.id, permArg.id)}
537
+ />
538
+ <span style="flex:1">
539
+ <span class="perm-label">${permArg.label}</span>
540
+ <span class="perm-hint">${permArg.hint}</span>
541
+ </span>
542
+ <code class="perm-id">${permArg.id}</code>
543
+ </label>
544
+ `)}
545
+ </div>
546
+ `
547
+ : html ``}
548
+ </div>
549
+ `;
550
+ }
551
+ openGrant() {
552
+ this.grantEmail = '';
553
+ this.grantSelections = {};
554
+ this.grantExpiry = '30';
555
+ this.grantOpen = true;
556
+ }
557
+ closeGrant() {
558
+ this.grantOpen = false;
559
+ }
560
+ toggleGrantApp(appIdArg) {
561
+ const next = { ...this.grantSelections };
562
+ if (next[appIdArg]) {
563
+ delete next[appIdArg];
564
+ }
565
+ else {
566
+ next[appIdArg] = [];
567
+ }
568
+ this.grantSelections = next;
569
+ }
570
+ toggleGrantPerm(appIdArg, permIdArg) {
571
+ const current = this.grantSelections[appIdArg] || [];
572
+ this.grantSelections = {
573
+ ...this.grantSelections,
574
+ [appIdArg]: current.includes(permIdArg)
575
+ ? current.filter((permArg) => permArg !== permIdArg)
576
+ : [...current, permIdArg],
577
+ };
578
+ }
579
+ submitGrant() {
580
+ const grants = {};
581
+ for (const [appId, perms] of Object.entries(this.grantSelections)) {
582
+ if (perms.length) {
583
+ grants[appId] = perms;
584
+ }
585
+ }
586
+ const detail = {
587
+ email: this.grantEmail,
588
+ grants,
589
+ expiryDays: this.grantExpiry ? parseInt(this.grantExpiry, 10) : null,
590
+ };
591
+ this.dispatchEvent(new CustomEvent('idp-delegation-grant', { detail, bubbles: true, composed: true }));
592
+ this.closeGrant();
593
+ }
594
+ revoke(delegationIdArg) {
595
+ const detail = { delegationId: delegationIdArg };
596
+ this.dispatchEvent(new CustomEvent('idp-delegation-revoke', { detail, bubbles: true, composed: true }));
597
+ }
598
+ constructor() {
599
+ super(...arguments);
600
+ __runInitializers(this, _grantExpiry_extraInitializers);
601
+ }
602
+ static {
603
+ __runInitializers(_classThis, _classExtraInitializers);
604
+ }
605
+ };
606
+ return IdpDelegationSection = _classThis;
607
+ })();
608
+ export { IdpDelegationSection };
609
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWRwLWRlbGVnYXRpb24tc2VjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9lbGVtZW50cy9pZHAtZGVsZWdhdGlvbi1zZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxHQUFHLEVBQXVCLE1BQU0sNkJBQTZCLENBQUM7QUFDMUgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQy9DLE9BQU8saUJBQWlCLENBQUM7QUFDekIsT0FBTyxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLGVBQWUsQ0FBQztBQW1DdkIsTUFBTSxRQUFRLEdBQXdCO0lBQ3BDO1FBQ0UsRUFBRSxFQUFFLE1BQU07UUFDVixJQUFJLEVBQUUsYUFBYTtRQUNuQixLQUFLLEVBQUU7WUFDTCxFQUFFLEVBQUUsRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsbUNBQW1DLEVBQUU7WUFDMUYsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixFQUFFLElBQUksRUFBRSxtQ0FBbUMsRUFBRTtZQUM3RixFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUUsa0NBQWtDLEVBQUU7U0FDeEY7S0FDRjtJQUNEO1FBQ0UsRUFBRSxFQUFFLE1BQU07UUFDVixJQUFJLEVBQUUsU0FBUztRQUNmLEtBQUssRUFBRTtZQUNMLEVBQUUsRUFBRSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSwyQkFBMkIsRUFBRTtZQUM1RSxFQUFFLEVBQUUsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUUsMENB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