@unofficialbox/box-open-elements 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/components/collections/table.d.ts +57 -3
- package/dist/components/collections/table.js +339 -20
- package/dist/components/feedback/due-badge.d.ts +38 -0
- package/dist/components/feedback/due-badge.js +168 -0
- package/dist/components/feedback/due-types.d.ts +32 -0
- package/dist/components/feedback/due-types.js +91 -0
- package/dist/components/feedback/progress-steps.d.ts +51 -5
- package/dist/components/feedback/progress-steps.js +200 -22
- package/dist/components/feedback/stage-path.d.ts +44 -0
- package/dist/components/feedback/stage-path.js +235 -0
- package/dist/components/forms/select.d.ts +21 -0
- package/dist/components/forms/select.js +100 -3
- package/dist/components/forms/text-field.d.ts +21 -0
- package/dist/components/forms/text-field.js +100 -1
- package/dist/components/layout/nav-sidebar.d.ts +14 -0
- package/dist/components/layout/nav-sidebar.js +49 -0
- package/dist/components/layout/split-view.d.ts +14 -0
- package/dist/components/layout/split-view.js +80 -1
- package/dist/components/overlays/command-palette.d.ts +62 -0
- package/dist/components/overlays/command-palette.js +537 -0
- package/dist/components/overlays/command-types.d.ts +90 -0
- package/dist/components/overlays/command-types.js +259 -0
- package/dist/components/overlays/drawer.d.ts +18 -0
- package/dist/components/overlays/drawer.js +135 -9
- package/dist/components/overlays/shortcuts-overlay.d.ts +48 -0
- package/dist/components/overlays/shortcuts-overlay.js +385 -0
- package/dist/components/overlays/tooltip.js +1 -1
- package/dist/element-maps.d.ts +292 -0
- package/dist/element-maps.js +1 -0
- package/dist/entries/activity-density.d.ts +1 -0
- package/dist/entries/activity-density.js +1 -0
- package/dist/entries/agent-chat.d.ts +1 -0
- package/dist/entries/agent-chat.js +1 -0
- package/dist/entries/audit-log.d.ts +1 -0
- package/dist/entries/audit-log.js +1 -0
- package/dist/entries/command-palette.d.ts +1 -0
- package/dist/entries/command-palette.js +1 -0
- package/dist/entries/compare-view.d.ts +1 -0
- package/dist/entries/compare-view.js +1 -0
- package/dist/entries/diff-viewer.d.ts +1 -0
- package/dist/entries/diff-viewer.js +1 -0
- package/dist/entries/due-badge.d.ts +1 -0
- package/dist/entries/due-badge.js +1 -0
- package/dist/entries/form-wizard.d.ts +1 -0
- package/dist/entries/form-wizard.js +1 -0
- package/dist/entries/lineage-graph.d.ts +1 -0
- package/dist/entries/lineage-graph.js +1 -0
- package/dist/entries/notification-bell.d.ts +1 -0
- package/dist/entries/notification-bell.js +1 -0
- package/dist/entries/notification-inbox.d.ts +1 -0
- package/dist/entries/notification-inbox.js +1 -0
- package/dist/entries/provenance-strip.d.ts +1 -0
- package/dist/entries/provenance-strip.js +1 -0
- package/dist/entries/run-trace.d.ts +1 -0
- package/dist/entries/run-trace.js +1 -0
- package/dist/entries/shortcuts-overlay.d.ts +1 -0
- package/dist/entries/shortcuts-overlay.js +1 -0
- package/dist/entries/signature-ceremony.d.ts +1 -0
- package/dist/entries/signature-ceremony.js +1 -0
- package/dist/entries/stage-path.d.ts +1 -0
- package/dist/entries/stage-path.js +1 -0
- package/dist/entries/timeline.d.ts +1 -0
- package/dist/entries/timeline.js +1 -0
- package/dist/entries/version-graph.d.ts +1 -0
- package/dist/entries/version-graph.js +1 -0
- package/dist/entries/version-list.d.ts +1 -0
- package/dist/entries/version-list.js +1 -0
- package/dist/entries/wizard-summary.d.ts +1 -0
- package/dist/entries/wizard-summary.js +1 -0
- package/dist/entries/work-queue.d.ts +1 -0
- package/dist/entries/work-queue.js +1 -0
- package/dist/entries/workload-board.d.ts +1 -0
- package/dist/entries/workload-board.js +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +21 -0
- package/dist/patterns/agent-chat/agent-chat.d.ts +75 -0
- package/dist/patterns/agent-chat/agent-chat.js +820 -0
- package/dist/patterns/agent-chat/controller.d.ts +27 -0
- package/dist/patterns/agent-chat/controller.js +182 -0
- package/dist/patterns/agent-chat/index.d.ts +3 -0
- package/dist/patterns/agent-chat/index.js +6 -0
- package/dist/patterns/agent-chat/types.d.ts +109 -0
- package/dist/patterns/agent-chat/types.js +1 -0
- package/dist/patterns/audit/activity-density.d.ts +68 -0
- package/dist/patterns/audit/activity-density.js +428 -0
- package/dist/patterns/audit/audit-log.d.ts +81 -0
- package/dist/patterns/audit/audit-log.js +794 -0
- package/dist/patterns/audit/index.d.ts +3 -0
- package/dist/patterns/audit/index.js +7 -0
- package/dist/patterns/audit/shared.d.ts +10 -0
- package/dist/patterns/audit/shared.js +50 -0
- package/dist/patterns/audit/types.d.ts +143 -0
- package/dist/patterns/audit/types.js +327 -0
- package/dist/patterns/content-explorer/actions/controller.js +12 -2
- package/dist/patterns/content-explorer/box-transport.js +117 -25
- package/dist/patterns/content-explorer/content-explorer.d.ts +13 -1
- package/dist/patterns/content-explorer/content-explorer.js +36 -3
- package/dist/patterns/content-explorer/contracts.d.ts +24 -1
- package/dist/patterns/content-explorer/contracts.js +68 -11
- package/dist/patterns/content-explorer/controller.d.ts +16 -1
- package/dist/patterns/content-explorer/controller.js +130 -4
- package/dist/patterns/content-explorer/navigation/controller.js +11 -9
- package/dist/patterns/content-explorer/types.d.ts +58 -1
- package/dist/patterns/content-picker/content-picker.d.ts +71 -0
- package/dist/patterns/content-picker/content-picker.js +747 -0
- package/dist/patterns/content-picker/controller.d.ts +38 -0
- package/dist/patterns/content-picker/controller.js +141 -0
- package/dist/patterns/content-picker/index.d.ts +3 -0
- package/dist/patterns/content-picker/index.js +6 -0
- package/dist/patterns/content-picker/types.d.ts +52 -0
- package/dist/patterns/content-picker/types.js +26 -0
- package/dist/patterns/content-sidebar/content-sidebar.d.ts +43 -0
- package/dist/patterns/content-sidebar/content-sidebar.js +293 -0
- package/dist/patterns/content-sidebar/index.d.ts +2 -0
- package/dist/patterns/content-sidebar/index.js +4 -0
- package/dist/patterns/content-sidebar/types.d.ts +18 -0
- package/dist/patterns/content-sidebar/types.js +20 -0
- package/dist/patterns/content-uploader/box-transport.d.ts +14 -0
- package/dist/patterns/content-uploader/box-transport.js +54 -0
- package/dist/patterns/content-uploader/content-uploader.d.ts +62 -0
- package/dist/patterns/content-uploader/content-uploader.js +559 -0
- package/dist/patterns/content-uploader/controller.d.ts +39 -0
- package/dist/patterns/content-uploader/controller.js +227 -0
- package/dist/patterns/content-uploader/index.d.ts +4 -0
- package/dist/patterns/content-uploader/index.js +8 -0
- package/dist/patterns/content-uploader/types.d.ts +120 -0
- package/dist/patterns/content-uploader/types.js +38 -0
- package/dist/patterns/diff/compare-view.d.ts +47 -0
- package/dist/patterns/diff/compare-view.js +276 -0
- package/dist/patterns/diff/diff-viewer.d.ts +42 -0
- package/dist/patterns/diff/diff-viewer.js +434 -0
- package/dist/patterns/diff/engine.d.ts +22 -0
- package/dist/patterns/diff/engine.js +276 -0
- package/dist/patterns/diff/index.d.ts +4 -0
- package/dist/patterns/diff/index.js +8 -0
- package/dist/patterns/diff/types.d.ts +69 -0
- package/dist/patterns/diff/types.js +24 -0
- package/dist/patterns/form-wizard/controller.d.ts +39 -0
- package/dist/patterns/form-wizard/controller.js +157 -0
- package/dist/patterns/form-wizard/form-wizard.d.ts +63 -0
- package/dist/patterns/form-wizard/form-wizard.js +468 -0
- package/dist/patterns/form-wizard/index.d.ts +4 -0
- package/dist/patterns/form-wizard/index.js +8 -0
- package/dist/patterns/form-wizard/types.d.ts +109 -0
- package/dist/patterns/form-wizard/types.js +83 -0
- package/dist/patterns/form-wizard/wizard-summary.d.ts +62 -0
- package/dist/patterns/form-wizard/wizard-summary.js +324 -0
- package/dist/patterns/internal/safe-href.d.ts +17 -0
- package/dist/patterns/internal/safe-href.js +17 -0
- package/dist/patterns/lineage/index.d.ts +3 -0
- package/dist/patterns/lineage/index.js +6 -0
- package/dist/patterns/lineage/lineage-graph.d.ts +30 -0
- package/dist/patterns/lineage/lineage-graph.js +434 -0
- package/dist/patterns/lineage/provenance-strip.d.ts +22 -0
- package/dist/patterns/lineage/provenance-strip.js +194 -0
- package/dist/patterns/lineage/types.d.ts +53 -0
- package/dist/patterns/lineage/types.js +49 -0
- package/dist/patterns/notifications/index.d.ts +3 -0
- package/dist/patterns/notifications/index.js +6 -0
- package/dist/patterns/notifications/notification-bell.d.ts +38 -0
- package/dist/patterns/notifications/notification-bell.js +198 -0
- package/dist/patterns/notifications/notification-inbox.d.ts +46 -0
- package/dist/patterns/notifications/notification-inbox.js +537 -0
- package/dist/patterns/notifications/types.d.ts +61 -0
- package/dist/patterns/notifications/types.js +108 -0
- package/dist/patterns/preview/annotation-inspector.d.ts +25 -6
- package/dist/patterns/preview/annotation-inspector.js +239 -94
- package/dist/patterns/preview/annotation-thread.d.ts +25 -5
- package/dist/patterns/preview/annotation-thread.js +233 -82
- package/dist/patterns/preview/annotation-toolbar.d.ts +20 -6
- package/dist/patterns/preview/annotation-toolbar.js +162 -96
- package/dist/patterns/preview/content-preview-adapter.d.ts +10 -1
- package/dist/patterns/preview/content-preview-adapter.js +26 -1
- package/dist/patterns/preview/preview-element.d.ts +15 -2
- package/dist/patterns/preview/preview-element.js +223 -52
- package/dist/patterns/preview/provider-adapter.d.ts +47 -0
- package/dist/patterns/preview/provider-adapter.js +17 -0
- package/dist/patterns/run/index.d.ts +2 -0
- package/dist/patterns/run/index.js +4 -0
- package/dist/patterns/run/run-trace.d.ts +40 -0
- package/dist/patterns/run/run-trace.js +441 -0
- package/dist/patterns/run/types.d.ts +66 -0
- package/dist/patterns/run/types.js +152 -0
- package/dist/patterns/signature/index.d.ts +2 -0
- package/dist/patterns/signature/index.js +4 -0
- package/dist/patterns/signature/signature-ceremony.d.ts +33 -0
- package/dist/patterns/signature/signature-ceremony.js +317 -0
- package/dist/patterns/signature/types.d.ts +68 -0
- package/dist/patterns/signature/types.js +89 -0
- package/dist/patterns/timeline/index.d.ts +2 -0
- package/dist/patterns/timeline/index.js +4 -0
- package/dist/patterns/timeline/timeline.d.ts +27 -0
- package/dist/patterns/timeline/timeline.js +430 -0
- package/dist/patterns/timeline/types.d.ts +36 -0
- package/dist/patterns/timeline/types.js +27 -0
- package/dist/patterns/versions/graph-layout.d.ts +43 -0
- package/dist/patterns/versions/graph-layout.js +159 -0
- package/dist/patterns/versions/index.d.ts +4 -0
- package/dist/patterns/versions/index.js +8 -0
- package/dist/patterns/versions/shared.d.ts +4 -0
- package/dist/patterns/versions/shared.js +13 -0
- package/dist/patterns/versions/types.d.ts +37 -0
- package/dist/patterns/versions/types.js +39 -0
- package/dist/patterns/versions/version-graph.d.ts +36 -0
- package/dist/patterns/versions/version-graph.js +438 -0
- package/dist/patterns/versions/version-list.d.ts +39 -0
- package/dist/patterns/versions/version-list.js +407 -0
- package/dist/patterns/work-queue/controller.d.ts +26 -0
- package/dist/patterns/work-queue/controller.js +150 -0
- package/dist/patterns/work-queue/index.d.ts +4 -0
- package/dist/patterns/work-queue/index.js +7 -0
- package/dist/patterns/work-queue/types.d.ts +128 -0
- package/dist/patterns/work-queue/types.js +45 -0
- package/dist/patterns/work-queue/work-queue.d.ts +48 -0
- package/dist/patterns/work-queue/work-queue.js +534 -0
- package/dist/patterns/work-queue/workload-board.d.ts +53 -0
- package/dist/patterns/work-queue/workload-board.js +608 -0
- package/package.json +89 -5
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolvePreviewStatus, } from "./provider-adapter.js";
|
|
1
2
|
import { BaseElement } from "../../core/index.js";
|
|
2
3
|
import { boePanel } from "../../foundations/geometry/index.js";
|
|
3
4
|
const DEFAULT_TAG_NAME = "box-preview-element";
|
|
@@ -19,6 +20,7 @@ const elementStyles = `
|
|
|
19
20
|
--_obp-text-muted: var(--boe-token-text-text-secondary, #6f6f6f);
|
|
20
21
|
--_obp-brand: var(--boe-token-surface-surface-brand, #0061d5);
|
|
21
22
|
--_obp-brand-soft: color-mix(in srgb, var(--_obp-brand) 12%, var(--boe-token-surface-surface, #ffffff) 88%);
|
|
23
|
+
--_obp-error: var(--boe-token-surface-status-surface-error, #ed3757);
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
[part="shell"] {
|
|
@@ -58,6 +60,20 @@ const elementStyles = `
|
|
|
58
60
|
text-transform: uppercase;
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
[part="status"][data-status="error"] {
|
|
64
|
+
background: color-mix(in srgb, var(--_obp-error) 14%, var(--_obp-surface) 86%);
|
|
65
|
+
color: var(--_obp-error);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
[part="error"] {
|
|
69
|
+
margin: 0;
|
|
70
|
+
padding: 0.5rem 0.7rem;
|
|
71
|
+
border: 1px solid color-mix(in srgb, var(--_obp-error) 50%, #fff);
|
|
72
|
+
border-radius: 8px;
|
|
73
|
+
background: color-mix(in srgb, var(--_obp-error) 10%, #fff);
|
|
74
|
+
color: inherit;
|
|
75
|
+
}
|
|
76
|
+
|
|
61
77
|
[part="adapter-meta"],
|
|
62
78
|
[part="capabilities"] {
|
|
63
79
|
display: flex;
|
|
@@ -105,7 +121,8 @@ const elementStyles = `
|
|
|
105
121
|
gap: 0.5rem;
|
|
106
122
|
}
|
|
107
123
|
|
|
108
|
-
[part="action"]
|
|
124
|
+
[part="action"],
|
|
125
|
+
[part="control"] {
|
|
109
126
|
appearance: none;
|
|
110
127
|
min-height: 2rem;
|
|
111
128
|
padding: 0.4rem 0.7rem;
|
|
@@ -123,6 +140,24 @@ const elementStyles = `
|
|
|
123
140
|
color: var(--boe-token-text-text-on-brand, #ffffff);
|
|
124
141
|
}
|
|
125
142
|
|
|
143
|
+
[part="control"]:disabled {
|
|
144
|
+
opacity: 0.5;
|
|
145
|
+
cursor: not-allowed;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
[part="controls"] {
|
|
149
|
+
display: flex;
|
|
150
|
+
flex-wrap: wrap;
|
|
151
|
+
align-items: center;
|
|
152
|
+
gap: 0.45rem;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
[part="control-readout"] {
|
|
156
|
+
color: var(--_obp-text-muted);
|
|
157
|
+
font-size: 0.85rem;
|
|
158
|
+
font-variant-numeric: tabular-nums;
|
|
159
|
+
}
|
|
160
|
+
|
|
126
161
|
[part="toolbar"] {
|
|
127
162
|
display: block;
|
|
128
163
|
}
|
|
@@ -134,6 +169,10 @@ const elementStyles = `
|
|
|
134
169
|
align-items: start;
|
|
135
170
|
}
|
|
136
171
|
|
|
172
|
+
[part="workspace"][data-sidebar="empty"] {
|
|
173
|
+
grid-template-columns: minmax(0, 1fr);
|
|
174
|
+
}
|
|
175
|
+
|
|
137
176
|
[part="stage"] {
|
|
138
177
|
min-block-size: 13rem;
|
|
139
178
|
border: 1px solid var(--_obp-border-subtle);
|
|
@@ -142,11 +181,28 @@ const elementStyles = `
|
|
|
142
181
|
overflow: hidden;
|
|
143
182
|
}
|
|
144
183
|
|
|
184
|
+
[part="stage"][aria-busy="true"] {
|
|
185
|
+
opacity: 0.7;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
[part="stage-mount"] {
|
|
189
|
+
width: 100%;
|
|
190
|
+
height: 100%;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
[part="stage-mount"][hidden] {
|
|
194
|
+
display: none;
|
|
195
|
+
}
|
|
196
|
+
|
|
145
197
|
[part="sidebar"] {
|
|
146
198
|
display: grid;
|
|
147
199
|
gap: 0.6rem;
|
|
148
200
|
}
|
|
149
201
|
|
|
202
|
+
[part="workspace"][data-sidebar="empty"] [part="sidebar"] {
|
|
203
|
+
display: none;
|
|
204
|
+
}
|
|
205
|
+
|
|
150
206
|
::slotted([slot="toolbar"]) {
|
|
151
207
|
display: block;
|
|
152
208
|
}
|
|
@@ -171,6 +227,7 @@ export class Preview extends BaseElement {
|
|
|
171
227
|
static tagName = DEFAULT_TAG_NAME;
|
|
172
228
|
providerAdapterValue = null;
|
|
173
229
|
providerAdapterUnsubscribe = null;
|
|
230
|
+
adapterMounted = false;
|
|
174
231
|
static get observedAttributes() {
|
|
175
232
|
return ["actions", "adapter-state", "item-label", "message", "provider", "provider-label", "status", "heading"];
|
|
176
233
|
}
|
|
@@ -252,12 +309,8 @@ export class Preview extends BaseElement {
|
|
|
252
309
|
set providerAdapter(value) {
|
|
253
310
|
this.teardownProviderAdapter();
|
|
254
311
|
this.providerAdapterValue = value;
|
|
255
|
-
if (
|
|
256
|
-
this.
|
|
257
|
-
if (this.isRendered) {
|
|
258
|
-
this.update();
|
|
259
|
-
}
|
|
260
|
-
});
|
|
312
|
+
if (this.isConnected) {
|
|
313
|
+
this.attachProviderAdapter();
|
|
261
314
|
}
|
|
262
315
|
if (this.isRendered) {
|
|
263
316
|
this.update();
|
|
@@ -265,13 +318,16 @@ export class Preview extends BaseElement {
|
|
|
265
318
|
}
|
|
266
319
|
connectedCallback() {
|
|
267
320
|
super.connectedCallback();
|
|
321
|
+
// Re-attach after a detach: disconnectedCallback tears the subscription and
|
|
322
|
+
// mount down, so a reconnect must restore both or the element goes stale.
|
|
323
|
+
this.attachProviderAdapter();
|
|
324
|
+
if (this.isRendered) {
|
|
325
|
+
this.update();
|
|
326
|
+
}
|
|
268
327
|
}
|
|
269
328
|
disconnectedCallback() {
|
|
270
329
|
this.teardownProviderAdapter();
|
|
271
330
|
}
|
|
272
|
-
attributeChangedCallback(name, oldValue, newValue) {
|
|
273
|
-
super.attributeChangedCallback(name, oldValue, newValue);
|
|
274
|
-
}
|
|
275
331
|
parseJsonAttribute(name, fallback) {
|
|
276
332
|
const raw = this.getAttribute(name);
|
|
277
333
|
if (!raw) {
|
|
@@ -284,9 +340,36 @@ export class Preview extends BaseElement {
|
|
|
284
340
|
return fallback;
|
|
285
341
|
}
|
|
286
342
|
}
|
|
343
|
+
attachProviderAdapter() {
|
|
344
|
+
const adapter = this.providerAdapterValue;
|
|
345
|
+
if (!adapter) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (adapter.subscribe && !this.providerAdapterUnsubscribe) {
|
|
349
|
+
this.providerAdapterUnsubscribe = adapter.subscribe(() => {
|
|
350
|
+
if (this.isRendered) {
|
|
351
|
+
this.update();
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
const mountNode = this.shadowRoot?.querySelector('[part="stage-mount"]');
|
|
356
|
+
if (adapter.mount && mountNode && !this.adapterMounted) {
|
|
357
|
+
mountNode.hidden = false;
|
|
358
|
+
adapter.mount(mountNode);
|
|
359
|
+
this.adapterMounted = true;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
287
362
|
teardownProviderAdapter() {
|
|
288
363
|
this.providerAdapterUnsubscribe?.();
|
|
289
364
|
this.providerAdapterUnsubscribe = null;
|
|
365
|
+
if (this.adapterMounted) {
|
|
366
|
+
this.providerAdapterValue?.unmount?.();
|
|
367
|
+
this.adapterMounted = false;
|
|
368
|
+
const mountNode = this.shadowRoot?.querySelector('[part="stage-mount"]');
|
|
369
|
+
if (mountNode) {
|
|
370
|
+
mountNode.hidden = true;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
290
373
|
}
|
|
291
374
|
getActiveProvider() {
|
|
292
375
|
return this.providerAdapterValue?.getProvider() ?? this.provider;
|
|
@@ -303,13 +386,39 @@ export class Preview extends BaseElement {
|
|
|
303
386
|
provider,
|
|
304
387
|
providerId: provider?.id ?? null,
|
|
305
388
|
};
|
|
306
|
-
|
|
389
|
+
Promise.resolve(this.providerAdapterValue?.performAction?.(detail)).catch((error) => {
|
|
390
|
+
this.dispatchEvent(new CustomEvent("action-error", {
|
|
391
|
+
bubbles: true,
|
|
392
|
+
composed: true,
|
|
393
|
+
detail: {
|
|
394
|
+
action: actionId,
|
|
395
|
+
message: error instanceof Error ? error.message : "Preview action failed",
|
|
396
|
+
},
|
|
397
|
+
}));
|
|
398
|
+
});
|
|
307
399
|
this.dispatchEvent(new CustomEvent("action", {
|
|
308
400
|
bubbles: true,
|
|
309
401
|
composed: true,
|
|
310
402
|
detail,
|
|
311
403
|
}));
|
|
312
|
-
|
|
404
|
+
}
|
|
405
|
+
emitCommand(command) {
|
|
406
|
+
const provider = this.getActiveProvider();
|
|
407
|
+
const detail = {
|
|
408
|
+
command,
|
|
409
|
+
providerId: provider?.id ?? null,
|
|
410
|
+
};
|
|
411
|
+
Promise.resolve(this.providerAdapterValue?.sendCommand?.(command)).catch((error) => {
|
|
412
|
+
this.dispatchEvent(new CustomEvent("action-error", {
|
|
413
|
+
bubbles: true,
|
|
414
|
+
composed: true,
|
|
415
|
+
detail: {
|
|
416
|
+
action: command.command,
|
|
417
|
+
message: error instanceof Error ? error.message : "Preview command failed",
|
|
418
|
+
},
|
|
419
|
+
}));
|
|
420
|
+
});
|
|
421
|
+
this.dispatchEvent(new CustomEvent("command", {
|
|
313
422
|
bubbles: true,
|
|
314
423
|
composed: true,
|
|
315
424
|
detail,
|
|
@@ -319,11 +428,58 @@ export class Preview extends BaseElement {
|
|
|
319
428
|
if (!this.shadowRoot) {
|
|
320
429
|
return;
|
|
321
430
|
}
|
|
431
|
+
// Stable skeleton: the chrome host is re-rendered per update, while the
|
|
432
|
+
// workspace (adapter mount node + slots) keeps node identity so mounted
|
|
433
|
+
// preview engines and slotted content survive chrome updates.
|
|
322
434
|
this.shadowRoot.innerHTML = `
|
|
323
435
|
<style>${elementStyles}</style>
|
|
324
|
-
<
|
|
436
|
+
<article part="shell">
|
|
437
|
+
<div part="content-host"></div>
|
|
438
|
+
<div part="toolbar">
|
|
439
|
+
<slot name="toolbar"></slot>
|
|
440
|
+
</div>
|
|
441
|
+
<div part="workspace" data-sidebar="empty">
|
|
442
|
+
<div part="stage">
|
|
443
|
+
<div part="stage-mount" hidden></div>
|
|
444
|
+
<slot name="stage"></slot>
|
|
445
|
+
</div>
|
|
446
|
+
<aside part="sidebar">
|
|
447
|
+
<slot name="sidebar"></slot>
|
|
448
|
+
</aside>
|
|
449
|
+
</div>
|
|
450
|
+
</article>
|
|
325
451
|
`;
|
|
326
452
|
}
|
|
453
|
+
setupListeners() {
|
|
454
|
+
if (!this.shadowRoot) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
// Delegated once — chrome re-renders never re-bind listeners.
|
|
458
|
+
this.shadowRoot.querySelector('[part="content-host"]')?.addEventListener("click", event => {
|
|
459
|
+
const target = event.target.closest("[data-action-id], [data-command]");
|
|
460
|
+
if (!target || target.disabled) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const actionId = target.getAttribute("data-action-id");
|
|
464
|
+
if (actionId) {
|
|
465
|
+
this.emitAction(actionId);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const command = target.getAttribute("data-command");
|
|
469
|
+
if (command) {
|
|
470
|
+
this.emitCommand({ command });
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
const sidebarSlot = this.shadowRoot.querySelector('slot[name="sidebar"]');
|
|
474
|
+
const workspace = this.shadowRoot.querySelector('[part="workspace"]');
|
|
475
|
+
const syncSidebar = () => {
|
|
476
|
+
const hasContent = (sidebarSlot?.assignedNodes({ flatten: true }) ?? []).some(node => node.nodeType === Node.ELEMENT_NODE || (node.textContent ?? "").trim() !== "");
|
|
477
|
+
workspace?.setAttribute("data-sidebar", hasContent ? "filled" : "empty");
|
|
478
|
+
};
|
|
479
|
+
sidebarSlot?.addEventListener("slotchange", syncSidebar);
|
|
480
|
+
syncSidebar();
|
|
481
|
+
this.attachProviderAdapter();
|
|
482
|
+
}
|
|
327
483
|
update() {
|
|
328
484
|
if (!this.shadowRoot) {
|
|
329
485
|
return;
|
|
@@ -331,8 +487,15 @@ export class Preview extends BaseElement {
|
|
|
331
487
|
const provider = this.getActiveProvider();
|
|
332
488
|
const adapterState = this.getActiveAdapterState();
|
|
333
489
|
const providerLabel = provider?.label ?? this.providerLabel;
|
|
334
|
-
const
|
|
335
|
-
const
|
|
490
|
+
const lifecycle = resolvePreviewStatus(adapterState);
|
|
491
|
+
const statusLabel = provider?.status ?? this.status ?? "";
|
|
492
|
+
const statusText = statusLabel || (adapterState ? lifecycle : "");
|
|
493
|
+
const statusMarkup = statusText
|
|
494
|
+
? `<span part="status" role="status" data-status="${escapeHtml(lifecycle)}">${escapeHtml(statusText)}</span>`
|
|
495
|
+
: "";
|
|
496
|
+
const errorMarkup = lifecycle === "error"
|
|
497
|
+
? `<p part="error" role="alert">${escapeHtml(adapterState?.errorMessage ?? "Preview failed to load.")}</p>`
|
|
498
|
+
: "";
|
|
336
499
|
const messageMarkup = this.message ? `<div part="message">${escapeHtml(this.message)}</div>` : "";
|
|
337
500
|
const providerMarkup = providerLabel ? `<span part="provider">${escapeHtml(providerLabel)}</span>` : "";
|
|
338
501
|
const itemMarkup = this.itemLabel ? `<div part="item-label">${escapeHtml(this.itemLabel)}</div>` : "";
|
|
@@ -346,9 +509,6 @@ export class Preview extends BaseElement {
|
|
|
346
509
|
${adapterState.currentAnnotationId
|
|
347
510
|
? `<span part="adapter-chip">${escapeHtml(`Annotation ${adapterState.currentAnnotationId}`)}</span>`
|
|
348
511
|
: ""}
|
|
349
|
-
${typeof adapterState.ready === "boolean"
|
|
350
|
-
? `<span part="adapter-chip">${adapterState.ready ? "Ready" : "Connecting"}</span>`
|
|
351
|
-
: ""}
|
|
352
512
|
</div>
|
|
353
513
|
`
|
|
354
514
|
: "";
|
|
@@ -359,6 +519,7 @@ export class Preview extends BaseElement {
|
|
|
359
519
|
</div>
|
|
360
520
|
`
|
|
361
521
|
: "";
|
|
522
|
+
const controlsMarkup = this.renderControls(adapterState);
|
|
362
523
|
const actionsMarkup = this.actions.length
|
|
363
524
|
? `
|
|
364
525
|
<div part="actions">
|
|
@@ -382,42 +543,52 @@ export class Preview extends BaseElement {
|
|
|
382
543
|
return;
|
|
383
544
|
}
|
|
384
545
|
host.innerHTML = `
|
|
385
|
-
<
|
|
386
|
-
<div part="topline">
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
${statusMarkup}
|
|
390
|
-
</div>
|
|
391
|
-
${actionsMarkup}
|
|
392
|
-
</div>
|
|
393
|
-
<header part="header">
|
|
394
|
-
<h2 part="title">${escapeHtml(this.heading)}</h2>
|
|
395
|
-
${itemMarkup}
|
|
396
|
-
${messageMarkup}
|
|
397
|
-
${adapterMarkup}
|
|
398
|
-
${capabilityMarkup}
|
|
399
|
-
</header>
|
|
400
|
-
<div part="toolbar">
|
|
401
|
-
<slot name="toolbar"></slot>
|
|
546
|
+
<div part="topline">
|
|
547
|
+
<div part="topline-meta">
|
|
548
|
+
${providerMarkup}
|
|
549
|
+
${statusMarkup}
|
|
402
550
|
</div>
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
551
|
+
${actionsMarkup}
|
|
552
|
+
</div>
|
|
553
|
+
<header part="header">
|
|
554
|
+
<h2 part="title">${escapeHtml(this.heading)}</h2>
|
|
555
|
+
${itemMarkup}
|
|
556
|
+
${messageMarkup}
|
|
557
|
+
${errorMarkup}
|
|
558
|
+
${adapterMarkup}
|
|
559
|
+
${capabilityMarkup}
|
|
560
|
+
${controlsMarkup}
|
|
561
|
+
</header>
|
|
412
562
|
`;
|
|
413
|
-
this.shadowRoot.
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
563
|
+
const stage = this.shadowRoot.querySelector('[part="stage"]');
|
|
564
|
+
stage?.setAttribute("aria-busy", lifecycle === "loading" ? "true" : "false");
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Paging/zoom controls render only when the adapter accepts commands and the
|
|
568
|
+
* state carries the numeric fields to drive them.
|
|
569
|
+
*/
|
|
570
|
+
renderControls(adapterState) {
|
|
571
|
+
if (!this.providerAdapterValue?.sendCommand || !adapterState) {
|
|
572
|
+
return "";
|
|
573
|
+
}
|
|
574
|
+
const segments = [];
|
|
575
|
+
if (typeof adapterState.page === "number" && typeof adapterState.pageCount === "number") {
|
|
576
|
+
const atFirst = adapterState.page <= 1;
|
|
577
|
+
const atLast = adapterState.page >= adapterState.pageCount;
|
|
578
|
+
segments.push(`
|
|
579
|
+
<button type="button" part="control" data-command="previous-page" aria-label="Previous page" ${atFirst ? "disabled" : ""}>‹</button>
|
|
580
|
+
<span part="control-readout">Page ${adapterState.page} of ${adapterState.pageCount}</span>
|
|
581
|
+
<button type="button" part="control" data-command="next-page" aria-label="Next page" ${atLast ? "disabled" : ""}>›</button>
|
|
582
|
+
`);
|
|
583
|
+
}
|
|
584
|
+
if (typeof adapterState.zoomPercent === "number") {
|
|
585
|
+
segments.push(`
|
|
586
|
+
<button type="button" part="control" data-command="zoom-out" aria-label="Zoom out">−</button>
|
|
587
|
+
<span part="control-readout">${Math.round(adapterState.zoomPercent)}%</span>
|
|
588
|
+
<button type="button" part="control" data-command="zoom-in" aria-label="Zoom in">+</button>
|
|
589
|
+
`);
|
|
590
|
+
}
|
|
591
|
+
return segments.length ? `<div part="controls" aria-label="Preview controls">${segments.join("")}</div>` : "";
|
|
421
592
|
}
|
|
422
593
|
}
|
|
423
594
|
Preview.register();
|
|
@@ -5,13 +5,49 @@ export type PreviewProvider = {
|
|
|
5
5
|
label: string;
|
|
6
6
|
status?: string;
|
|
7
7
|
};
|
|
8
|
+
/** Lifecycle of the previewed content, from nothing loaded to failure. */
|
|
9
|
+
export type PreviewStatus = "idle" | "loading" | "ready" | "error";
|
|
8
10
|
export type PreviewAdapterState = {
|
|
9
11
|
currentAnnotationId?: string;
|
|
10
12
|
mode?: string;
|
|
13
|
+
/** Display-only label; prefer the numeric `page`/`pageCount` when driving UI. */
|
|
11
14
|
pageLabel?: string;
|
|
15
|
+
/** Legacy readiness flag; prefer `status`. Kept for adapter compatibility. */
|
|
12
16
|
ready?: boolean;
|
|
13
17
|
selectionLabel?: string;
|
|
18
|
+
/** Display-only label; prefer the numeric `zoomPercent` when driving UI. */
|
|
14
19
|
zoomLabel?: string;
|
|
20
|
+
/** Content lifecycle. When absent, derived from `ready` (see resolvePreviewStatus). */
|
|
21
|
+
status?: PreviewStatus;
|
|
22
|
+
/** Human-readable failure description; render when `status` is "error". */
|
|
23
|
+
errorMessage?: string;
|
|
24
|
+
/** 1-based current page for paged content. */
|
|
25
|
+
page?: number;
|
|
26
|
+
pageCount?: number;
|
|
27
|
+
/** Zoom level as a percentage (100 = actual size). */
|
|
28
|
+
zoomPercent?: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Effective lifecycle for a state object: an explicit `status` wins; otherwise
|
|
32
|
+
* the legacy `ready` flag maps true→ready / false→loading; no state → idle.
|
|
33
|
+
*/
|
|
34
|
+
export declare const resolvePreviewStatus: (state: PreviewAdapterState | null | undefined) => PreviewStatus;
|
|
35
|
+
/**
|
|
36
|
+
* A typed command the host UI sends INTO the preview engine. Known commands
|
|
37
|
+
* carry their payload shape; the string fallback keeps the channel open for
|
|
38
|
+
* engine-specific extensions.
|
|
39
|
+
*/
|
|
40
|
+
export type PreviewCommand = {
|
|
41
|
+
command: "next-page" | "previous-page" | "zoom-in" | "zoom-out" | "toggle-fullscreen" | "download" | "print";
|
|
42
|
+
} | {
|
|
43
|
+
command: "go-to-page";
|
|
44
|
+
value: number;
|
|
45
|
+
} | {
|
|
46
|
+
command: "set-zoom";
|
|
47
|
+
value: number;
|
|
48
|
+
} | {
|
|
49
|
+
command: string;
|
|
50
|
+
value?: unknown;
|
|
15
51
|
};
|
|
16
52
|
export type PreviewProviderActionDetail = {
|
|
17
53
|
action: string;
|
|
@@ -24,6 +60,16 @@ export type PreviewProviderAdapter = {
|
|
|
24
60
|
getState: () => PreviewAdapterState | null;
|
|
25
61
|
performAction?: (detail: PreviewProviderActionDetail) => void | Promise<void>;
|
|
26
62
|
subscribe?: (listener: () => void) => () => void;
|
|
63
|
+
/**
|
|
64
|
+
* Hand the adapter a stable container to render the preview engine into.
|
|
65
|
+
* `box-preview-element` calls this with its stage node when present; the
|
|
66
|
+
* node survives shell re-renders, so mounted DOM is never destroyed by
|
|
67
|
+
* chrome updates.
|
|
68
|
+
*/
|
|
69
|
+
mount?: (container: HTMLElement) => void;
|
|
70
|
+
unmount?: () => void;
|
|
71
|
+
/** Drive the engine (paging, zoom, download, …) with a typed command. */
|
|
72
|
+
sendCommand?: (command: PreviewCommand) => void | Promise<void>;
|
|
27
73
|
};
|
|
28
74
|
export type StaticPreviewProviderAdapter = PreviewProviderAdapter & {
|
|
29
75
|
setProvider: (provider: PreviewProvider | null) => void;
|
|
@@ -31,6 +77,7 @@ export type StaticPreviewProviderAdapter = PreviewProviderAdapter & {
|
|
|
31
77
|
};
|
|
32
78
|
export declare const createStaticPreviewProviderAdapter: (config: {
|
|
33
79
|
onAction?: (detail: PreviewProviderActionDetail) => void | Promise<void>;
|
|
80
|
+
onCommand?: (command: PreviewCommand) => void | Promise<void>;
|
|
34
81
|
provider?: PreviewProvider | null;
|
|
35
82
|
state?: PreviewAdapterState | null;
|
|
36
83
|
}) => StaticPreviewProviderAdapter;
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effective lifecycle for a state object: an explicit `status` wins; otherwise
|
|
3
|
+
* the legacy `ready` flag maps true→ready / false→loading; no state → idle.
|
|
4
|
+
*/
|
|
5
|
+
export const resolvePreviewStatus = (state) => {
|
|
6
|
+
if (!state) {
|
|
7
|
+
return "idle";
|
|
8
|
+
}
|
|
9
|
+
if (state.status) {
|
|
10
|
+
return state.status;
|
|
11
|
+
}
|
|
12
|
+
if (typeof state.ready === "boolean") {
|
|
13
|
+
return state.ready ? "ready" : "loading";
|
|
14
|
+
}
|
|
15
|
+
return "idle";
|
|
16
|
+
};
|
|
1
17
|
export const createStaticPreviewProviderAdapter = (config) => {
|
|
2
18
|
let provider = config.provider ?? null;
|
|
3
19
|
let state = config.state ?? null;
|
|
@@ -11,6 +27,7 @@ export const createStaticPreviewProviderAdapter = (config) => {
|
|
|
11
27
|
getProvider: () => provider,
|
|
12
28
|
getState: () => state,
|
|
13
29
|
performAction: config.onAction,
|
|
30
|
+
...(config.onCommand ? { sendCommand: config.onCommand } : {}),
|
|
14
31
|
setProvider(nextProvider) {
|
|
15
32
|
provider = nextProvider;
|
|
16
33
|
notify();
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { RunResolution, RunStep, RunStepStatus } from "./types.js";
|
|
2
|
+
import { BaseElement } from "../../core/index.js";
|
|
3
|
+
/** Every status in words — colour never carries the meaning alone. */
|
|
4
|
+
export declare const RUN_STEP_STATUS_LABEL: Record<RunStepStatus, string>;
|
|
5
|
+
/**
|
|
6
|
+
* Machine execution trace: a job, pipeline, or agent run, top-down. The
|
|
7
|
+
* rules live in `resolveRunSteps` (pure), the same way `resolveCeremony`
|
|
8
|
+
* backs the signature card: an explicit status wins, a failure shadows the
|
|
9
|
+
* queue behind it as skipped, timestamps derive running/succeeded, and the
|
|
10
|
+
* host can drive its notifications from the identical function.
|
|
11
|
+
*
|
|
12
|
+
* Deliberately not `box-timeline` (the human activity feed): a run reads
|
|
13
|
+
* forward, has one step in flight, and takes no comments.
|
|
14
|
+
*
|
|
15
|
+
* The summary chip doubles as a polite status region, so a run driven by
|
|
16
|
+
* attribute updates announces "Running Deploy — step 3 of 5" → "Completed"
|
|
17
|
+
* without extra wiring. Per-step detail expands in place: `description`
|
|
18
|
+
* plus a `detail-<id>` slot for rich host content, plus child tasks with
|
|
19
|
+
* live `box-progress-bar` rows.
|
|
20
|
+
*/
|
|
21
|
+
export declare class RunTrace extends BaseElement {
|
|
22
|
+
static readonly tagName: string;
|
|
23
|
+
static get observedAttributes(): string[];
|
|
24
|
+
private hostEl;
|
|
25
|
+
private stepsRaw;
|
|
26
|
+
private stepsCache;
|
|
27
|
+
private readonly expandedIds;
|
|
28
|
+
get heading(): string;
|
|
29
|
+
set heading(value: string);
|
|
30
|
+
get steps(): RunStep[];
|
|
31
|
+
set steps(value: RunStep[]);
|
|
32
|
+
/** The resolved run — same object the render uses. */
|
|
33
|
+
get resolution(): RunResolution;
|
|
34
|
+
/** Ids of the steps whose detail is expanded (host-readable). */
|
|
35
|
+
get expandedSteps(): string[];
|
|
36
|
+
protected renderTemplate(): void;
|
|
37
|
+
protected setupListeners(): void;
|
|
38
|
+
private childrenMarkup;
|
|
39
|
+
protected update(): void;
|
|
40
|
+
}
|