@idp.global/catalog 1.2.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/changelog.md +21 -0
  2. package/dist_bundle/bundle.js +4428 -1496
  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 +700 -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 +1 -1
  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 +646 -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,419 @@
1
+ import { css, html, type TemplateResult } from '@design.estate/dees-element';
2
+ import './idp-icon.js';
3
+
4
+ export type TIdpAdminKpi = {
5
+ label: string;
6
+ value: string;
7
+ unit?: string;
8
+ delta: string;
9
+ deltaKind: 'up' | 'live';
10
+ sub: string;
11
+ accent: string;
12
+ spark: number[];
13
+ sparkColor: string;
14
+ };
15
+
16
+ export const idpAdminSharedStyles = css`
17
+ .state-card {
18
+ padding: 42px 24px;
19
+ border: 1px solid var(--idp-border);
20
+ border-radius: var(--idp-radius);
21
+ background: var(--idp-card);
22
+ color: var(--idp-muted-fg);
23
+ text-align: center;
24
+ }
25
+ .state-icon {
26
+ width: 38px;
27
+ height: 38px;
28
+ display: inline-flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ margin-bottom: 12px;
32
+ border: 1px solid var(--idp-border);
33
+ border-radius: 10px;
34
+ background: var(--idp-muted);
35
+ color: var(--idp-muted-fg);
36
+ }
37
+ .state-title {
38
+ margin-bottom: 4px;
39
+ color: var(--idp-fg);
40
+ font-size: 14px;
41
+ font-weight: 600;
42
+ }
43
+ .state-description {
44
+ max-width: 420px;
45
+ margin: 0 auto;
46
+ font-size: 12px;
47
+ line-height: 1.5;
48
+ }
49
+ .org-avatar {
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: center;
53
+ flex-shrink: 0;
54
+ width: 14px;
55
+ height: 14px;
56
+ border: 1px solid var(--idp-border);
57
+ border-radius: 6px;
58
+ background: var(--idp-accent-soft);
59
+ color: var(--idp-accent);
60
+ font-family: var(--idp-mono);
61
+ font-size: 5px;
62
+ font-weight: 700;
63
+ }
64
+ .page-head {
65
+ display: flex;
66
+ align-items: flex-end;
67
+ justify-content: space-between;
68
+ gap: 16px;
69
+ flex-wrap: wrap;
70
+ padding: 24px 28px 18px;
71
+ border-bottom: 1px solid var(--idp-border);
72
+ background: var(--idp-bg);
73
+ }
74
+ .eyebrow-row {
75
+ display: flex;
76
+ align-items: center;
77
+ gap: 8px;
78
+ margin-bottom: 4px;
79
+ }
80
+ .eyebrow {
81
+ color: var(--idp-muted-fg);
82
+ font-family: var(--idp-mono);
83
+ font-size: 10px;
84
+ font-weight: 600;
85
+ letter-spacing: 0.08em;
86
+ text-transform: uppercase;
87
+ }
88
+ .live-pill {
89
+ display: inline-flex;
90
+ align-items: center;
91
+ gap: 4px;
92
+ padding: 1px 7px;
93
+ border: 1px solid var(--idp-ok-border);
94
+ border-radius: 999px;
95
+ background: var(--idp-ok-bg);
96
+ color: var(--idp-ok);
97
+ font-family: var(--idp-mono);
98
+ font-size: 10px;
99
+ font-weight: 500;
100
+ }
101
+ .live-dot,
102
+ .feed-dot {
103
+ width: 6px;
104
+ height: 6px;
105
+ border-radius: 50%;
106
+ background: var(--idp-ok);
107
+ box-shadow: 0 0 6px var(--idp-ok);
108
+ animation: idp-blink 1.6s ease-in-out infinite;
109
+ }
110
+ @keyframes idp-blink {
111
+ 0%, 100% { opacity: 1; }
112
+ 50% { opacity: 0.35; }
113
+ }
114
+ h1,
115
+ h2 {
116
+ margin: 0;
117
+ color: var(--idp-fg);
118
+ font-family: var(--idp-display);
119
+ letter-spacing: -0.025em;
120
+ }
121
+ h1 {
122
+ font-size: 26px;
123
+ font-weight: 700;
124
+ line-height: 1.1;
125
+ }
126
+ .lead {
127
+ margin-top: 4px;
128
+ color: var(--idp-muted-fg);
129
+ font-size: 13px;
130
+ }
131
+ .lead code,
132
+ .mono {
133
+ color: var(--idp-info);
134
+ font-family: var(--idp-mono);
135
+ }
136
+ .page-actions {
137
+ display: flex;
138
+ align-items: center;
139
+ gap: 12px;
140
+ }
141
+ .tabs {
142
+ display: inline-flex;
143
+ gap: 1px;
144
+ padding: 2px;
145
+ border: 1px solid var(--idp-border);
146
+ border-radius: 6px;
147
+ background: var(--idp-bg-2);
148
+ }
149
+ .tab {
150
+ padding: 4px 10px;
151
+ border-radius: 4px;
152
+ color: var(--idp-muted-fg);
153
+ font-family: var(--idp-mono);
154
+ font-size: 11px;
155
+ font-weight: 500;
156
+ }
157
+ .tab.active {
158
+ background: var(--idp-muted);
159
+ color: var(--idp-fg);
160
+ }
161
+ .plain-button {
162
+ display: inline-flex;
163
+ align-items: center;
164
+ gap: 6px;
165
+ height: 28px;
166
+ padding: 5px 10px;
167
+ border: 0;
168
+ border-radius: 8px;
169
+ background: transparent;
170
+ color: var(--idp-fg);
171
+ font-family: inherit;
172
+ font-size: 12px;
173
+ font-weight: 500;
174
+ white-space: nowrap;
175
+ }
176
+ .plain-button.outline {
177
+ border: 1px solid var(--idp-border);
178
+ }
179
+ .plain-button.primary {
180
+ background: var(--idp-accent);
181
+ color: var(--idp-accent-fg);
182
+ }
183
+ .plain-button.destructive {
184
+ background: var(--idp-destructive);
185
+ color: var(--idp-accent-fg);
186
+ }
187
+ .plain-button.ghost {
188
+ color: var(--idp-fg);
189
+ }
190
+ .plain-button:disabled {
191
+ opacity: 0.45;
192
+ cursor: not-allowed;
193
+ }
194
+ .body {
195
+ display: flex;
196
+ flex-direction: column;
197
+ gap: 16px;
198
+ padding: 20px 28px 32px;
199
+ }
200
+ .narrow-body {
201
+ max-width: 700px;
202
+ }
203
+ .wide-body {
204
+ max-width: 860px;
205
+ }
206
+ .kpis {
207
+ display: grid;
208
+ grid-template-columns: repeat(4, 1fr);
209
+ gap: 12px;
210
+ }
211
+ .kpi,
212
+ .card {
213
+ border: 1px solid var(--idp-border);
214
+ background: var(--idp-card);
215
+ }
216
+ .kpi {
217
+ position: relative;
218
+ min-height: 132px;
219
+ display: flex;
220
+ flex-direction: column;
221
+ gap: 4px;
222
+ overflow: hidden;
223
+ padding: 18px 20px 14px;
224
+ border-radius: 10px;
225
+ }
226
+ .kpi::before {
227
+ content: '';
228
+ position: absolute;
229
+ top: 0;
230
+ left: 0;
231
+ right: 0;
232
+ height: 2px;
233
+ background: var(--kpi-accent);
234
+ }
235
+ .kpi-label {
236
+ color: var(--idp-muted-fg);
237
+ font-size: 11.5px;
238
+ font-weight: 500;
239
+ letter-spacing: 0.02em;
240
+ }
241
+ .kpi-value {
242
+ color: var(--idp-fg);
243
+ font-family: var(--idp-display);
244
+ font-size: 30px;
245
+ font-weight: 700;
246
+ font-variant-numeric: tabular-nums;
247
+ letter-spacing: -0.025em;
248
+ line-height: 1.1;
249
+ }
250
+ .kpi-value span {
251
+ margin-left: 2px;
252
+ color: var(--idp-muted-fg);
253
+ font-size: 14px;
254
+ font-weight: 500;
255
+ }
256
+ .kpi-sub {
257
+ color: var(--idp-fg-3);
258
+ font-family: var(--idp-mono);
259
+ font-size: 11px;
260
+ }
261
+ .kpi-foot {
262
+ display: flex;
263
+ align-items: flex-end;
264
+ justify-content: space-between;
265
+ gap: 8px;
266
+ margin-top: auto;
267
+ }
268
+ .delta {
269
+ display: inline-flex;
270
+ align-items: center;
271
+ gap: 4px;
272
+ color: var(--idp-ok);
273
+ font-family: var(--idp-mono);
274
+ font-size: 11px;
275
+ font-weight: 600;
276
+ }
277
+ .sparkline {
278
+ width: 84px;
279
+ opacity: 0.85;
280
+ }
281
+ .primary-grid,
282
+ .secondary-grid {
283
+ display: grid;
284
+ grid-template-columns: minmax(0, 1.6fr) minmax(300px, 1fr);
285
+ gap: 16px;
286
+ }
287
+ .card {
288
+ overflow: hidden;
289
+ border-radius: 8px;
290
+ }
291
+ .card-head {
292
+ display: flex;
293
+ align-items: center;
294
+ gap: 10px;
295
+ padding: 12px 16px;
296
+ border-bottom: 1px solid var(--idp-border-soft);
297
+ }
298
+ .card-title {
299
+ color: var(--idp-fg);
300
+ font-size: 13px;
301
+ font-weight: 600;
302
+ }
303
+ .feed-dot {
304
+ display: inline-block;
305
+ width: 8px;
306
+ height: 8px;
307
+ border-radius: 4px;
308
+ background: var(--dot-color);
309
+ box-shadow: var(--dot-glow, none);
310
+ }
311
+ .feed-meta {
312
+ color: var(--idp-muted-fg);
313
+ font-family: var(--idp-mono);
314
+ font-size: 11.5px;
315
+ }
316
+ .feed-item {
317
+ display: grid;
318
+ grid-template-columns: 14px 1fr auto;
319
+ gap: 12px;
320
+ align-items: center;
321
+ padding: 11px 16px;
322
+ border-bottom: 1px solid var(--idp-border-soft);
323
+ }
324
+ .feed-item:last-child {
325
+ border-bottom: 0;
326
+ }
327
+ .feed-text {
328
+ color: var(--idp-fg-2);
329
+ font-size: 12.5px;
330
+ }
331
+ .feed-text strong {
332
+ color: var(--idp-fg);
333
+ font-weight: 600;
334
+ }
335
+ @media (max-width: 1120px) {
336
+ .kpis {
337
+ grid-template-columns: repeat(2, 1fr);
338
+ }
339
+ .primary-grid,
340
+ .secondary-grid {
341
+ grid-template-columns: 1fr;
342
+ }
343
+ }
344
+ @media (max-width: 720px) {
345
+ .page-head,
346
+ .body {
347
+ padding-left: 20px;
348
+ padding-right: 20px;
349
+ }
350
+ .page-actions {
351
+ flex-wrap: wrap;
352
+ }
353
+ .kpis {
354
+ grid-template-columns: 1fr;
355
+ }
356
+ }
357
+ `;
358
+
359
+ export const renderAdminSparkline = (dataArg: number[], colorArg: string): TemplateResult => {
360
+ const max = Math.max(...dataArg);
361
+ const min = Math.min(...dataArg);
362
+ const range = max - min || 1;
363
+ const width = 100;
364
+ const height = 22;
365
+ const points = dataArg.map((valueArg, indexArg) => {
366
+ const x = (indexArg / (dataArg.length - 1)) * width;
367
+ const y = height - ((valueArg - min) / range) * (height - 4) - 2;
368
+ return `${x},${y}`;
369
+ }).join(' ');
370
+ const area = `0,${height} ${points} ${width},${height}`;
371
+
372
+ return html`
373
+ <svg viewBox="0 0 ${width} ${height}" preserveAspectRatio="none">
374
+ <polygon points=${area} fill=${colorArg} opacity="0.12"></polygon>
375
+ <polyline points=${points} fill="none" stroke=${colorArg} stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></polyline>
376
+ </svg>
377
+ `;
378
+ };
379
+
380
+ export const renderAdminKpi = (kpiArg: TIdpAdminKpi): TemplateResult => {
381
+ return html`
382
+ <div class="kpi" style="--kpi-accent:${kpiArg.accent}">
383
+ <div class="kpi-label">${kpiArg.label}</div>
384
+ <div class="kpi-value">${kpiArg.value}${kpiArg.unit ? html`<span>${kpiArg.unit}</span>` : html``}</div>
385
+ <div class="kpi-sub">${kpiArg.sub}</div>
386
+ <div class="kpi-foot">
387
+ <span class="delta">${kpiArg.deltaKind === 'live' ? html`<span class="live-dot"></span>` : html``}${kpiArg.delta}</span>
388
+ <div class="sparkline">${renderAdminSparkline(kpiArg.spark, kpiArg.sparkColor)}</div>
389
+ </div>
390
+ </div>
391
+ `;
392
+ };
393
+
394
+ export const renderAdminStateCard = (titleArg: string, descriptionArg: string, iconArg = 'box'): TemplateResult => {
395
+ return html`
396
+ <div class="state-card">
397
+ <span class="state-icon"><idp-icon name=${iconArg as any} size="17"></idp-icon></span>
398
+ <div class="state-title">${titleArg}</div>
399
+ <div class="state-description">${descriptionArg}</div>
400
+ </div>
401
+ `;
402
+ };
403
+
404
+ export const formatAdminTimeAgo = (timestampArg?: number): string => {
405
+ if (!timestampArg) {
406
+ return 'unknown';
407
+ }
408
+
409
+ const diff = Date.now() - timestampArg;
410
+ const minutes = Math.floor(diff / 60000);
411
+ const hours = Math.floor(diff / 3600000);
412
+ const days = Math.floor(diff / 86400000);
413
+
414
+ if (minutes < 1) return 'just now';
415
+ if (minutes < 60) return `${minutes}m ago`;
416
+ if (hours < 24) return `${hours}h ago`;
417
+ if (days < 7) return `${days}d ago`;
418
+ return new Date(timestampArg).toLocaleDateString();
419
+ };