@lostgradient/cinder 0.8.0 → 0.9.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/CHANGELOG.md +9 -0
- package/README.md +2 -2
- package/components.json +59 -15
- package/dist/components/_internal/command-list-context.d.ts +3 -3
- package/dist/components/_internal/create-command-list-state.svelte.d.ts +11 -11
- package/dist/components/access-gate/index.js +201 -126
- package/dist/components/approval-card/approval-card-actions.svelte.d.ts +16 -0
- package/dist/components/approval-card/approval-card-state.d.ts +65 -0
- package/dist/components/approval-card/approval-card.css +269 -92
- package/dist/components/approval-card/approval-card.schema.js +10 -31
- package/dist/components/approval-card/approval-card.svelte.d.ts +3 -3
- package/dist/components/approval-card/approval-card.types.d.ts +14 -28
- package/dist/components/approval-card/index.d.ts +1 -1
- package/dist/components/approval-card/index.js +4268 -2884
- package/dist/components/card/card.css +5 -0
- package/dist/components/card/card.schema.js +2 -2
- package/dist/components/card/card.types.d.ts +2 -2
- package/dist/components/card/index.js +2 -1
- package/dist/components/chat/chat.schema.js +44 -2
- package/dist/components/chat/chat.svelte.d.ts +4 -2
- package/dist/components/chat/chat.types.d.ts +34 -3
- package/dist/components/chat/container/chat.svelte.d.ts +4 -2
- package/dist/components/chat/index.d.ts +3 -3
- package/dist/components/chat/index.js +2485 -6279
- package/dist/components/chat/input/chat-attachment-serialization.d.ts +9 -0
- package/dist/components/chat/input/chat-input.svelte.d.ts +22 -1
- package/dist/components/chat/input/index.d.ts +1 -0
- package/dist/components/chat-composer-popover/chat-composer-popover-filter.d.ts +11 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.css +7 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.css.d.ts +1 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.schema.d.ts +3 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.schema.js +150 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.svelte.d.ts +46 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.types.d.ts +77 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.variables.d.ts +2 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.variables.js +61 -0
- package/dist/components/chat-composer-popover/index.d.ts +6 -0
- package/dist/components/chat-composer-popover/index.js +3285 -0
- package/dist/components/chat-conversation-header/index.js +1627 -5600
- package/dist/components/chat-conversation-list/index.js +15 -3988
- package/dist/components/code-block/code-block.schema.js +5 -1
- package/dist/components/code-block/code-block.types.d.ts +6 -0
- package/dist/components/code-block/index.js +4 -4
- package/dist/components/command-item/index.js +7 -6
- package/dist/components/command-menu/command-menu.schema.js +5 -1
- package/dist/components/command-menu/command-menu.types.d.ts +2 -0
- package/dist/components/command-menu/index.js +48 -19
- package/dist/components/command-palette/index.js +40 -14
- package/dist/components/event-stream-viewer/index.js +44 -44
- package/dist/components/experimental/json-viewer/index.js +44 -44
- package/dist/components/json-schema-editor/index.js +5 -2
- package/dist/components/json-viewer/index.js +44 -44
- package/dist/components/json-viewer/json-viewer.css +10 -6
- package/dist/components/payload-inspector/index.d.ts +1 -1
- package/dist/components/payload-inspector/index.js +306 -1422
- package/dist/components/payload-inspector/payload-inspector.css +15 -75
- package/dist/components/payload-inspector/payload-inspector.schema.js +5 -41
- package/dist/components/payload-inspector/payload-inspector.svelte.d.ts +5 -5
- package/dist/components/payload-inspector/payload-inspector.types.d.ts +10 -56
- package/dist/components/tab/index.js +5 -2
- package/dist/components/tab/tab.schema.js +7 -3
- package/dist/components/tab/tab.svelte.d.ts +2 -1
- package/dist/components/tab/tab.types.d.ts +8 -2
- package/dist/components/tabs/index.js +5 -2
- package/dist/components/team-section/index.js +2 -1
- package/dist/components/testimonial-section/index.js +2 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +23711 -27432
- package/dist/server/components/access-gate/index.js +2 -1
- package/dist/server/components/accordion/index.js +2 -2
- package/dist/server/components/alert-dialog/index.js +2 -2
- package/dist/server/components/approval-card/index.js +15 -19
- package/dist/server/components/autocomplete/index.js +7 -7
- package/dist/server/components/avatar-group/index.js +5 -5
- package/dist/server/components/button-group/index.js +3 -5
- package/dist/server/components/card/index.js +2 -2
- package/dist/server/components/chat/index.js +14 -11
- package/dist/server/components/chat-composer-popover/index.js +26 -0
- package/dist/server/components/chat-conversation-header/index.js +9 -10
- package/dist/server/components/chat-conversation-list/index.js +4 -5
- package/dist/server/components/checkbox/index.js +3 -3
- package/dist/server/components/choice-grid/index.js +2 -2
- package/dist/server/components/code-block/index.js +2 -2
- package/dist/server/components/color-field/index.js +3 -3
- package/dist/server/components/combobox/index.js +6 -6
- package/dist/server/components/command-item/index.js +5 -3
- package/dist/server/components/command-menu/index.js +6 -4
- package/dist/server/components/command-palette/index.js +2 -2
- package/dist/server/components/confirm-dialog/index.js +2 -2
- package/dist/server/components/context-menu/index.js +5 -5
- package/dist/server/components/data-table/index.js +5 -5
- package/dist/server/components/date-picker/index.js +6 -6
- package/dist/server/components/date-range-field/index.js +7 -7
- package/dist/server/components/description-list/index.js +3 -5
- package/dist/server/components/diff-viewer/index.js +7 -7
- package/dist/server/components/drawer/index.js +3 -3
- package/dist/server/components/dropdown/index.js +4 -4
- package/dist/server/components/event-stream-viewer/index.js +2 -2
- package/dist/server/components/experimental/json-viewer/index.js +2 -2
- package/dist/server/components/faceted-filter-bar/index.js +1 -1
- package/dist/server/components/hover-card/index.js +1 -1
- package/dist/server/components/input/index.js +3 -3
- package/dist/server/components/json-schema-editor/index.js +22 -22
- package/dist/server/components/json-viewer/index.js +2 -2
- package/dist/server/components/markdown-editor/index.js +13 -13
- package/dist/server/components/modal/index.js +1 -1
- package/dist/server/components/multi-select/index.js +1 -1
- package/dist/server/components/newsletter-section/index.js +3 -3
- package/dist/server/components/payload-inspector/index.js +4 -16
- package/dist/server/components/popover/index.js +5 -5
- package/dist/server/components/review-editor/index.js +25 -25
- package/dist/server/components/run-step-timeline/index.js +2 -2
- package/dist/server/components/schema-form/index.js +4 -4
- package/dist/server/components/secret-value-field/index.js +3 -5
- package/dist/server/components/segment/index.js +3 -3
- package/dist/server/components/segmented-control/index.js +4 -4
- package/dist/server/components/selection-popover/index.js +4 -4
- package/dist/server/components/sheet/index.js +2 -2
- package/dist/server/components/sidebar/index.js +3 -3
- package/dist/server/components/tab/index.js +2 -2
- package/dist/server/components/table/index.js +3 -3
- package/dist/server/components/tabs/index.js +4 -4
- package/dist/server/components/tag-input/index.js +3 -3
- package/dist/server/components/team-section/index.js +8 -8
- package/dist/server/components/testimonial-section/index.js +2 -2
- package/dist/server/components/toggle/index.js +2 -2
- package/dist/server/components/tooltip/index.js +1 -1
- package/dist/server/index.js +159 -148
- package/dist/server/{index.server-cbtg8rq5.js → index.server-0atyznp7.js} +5 -5
- package/dist/server/{index.server-20y4mdhm.js → index.server-0chhpkg7.js} +40 -14
- package/dist/server/{index.server-ecm1vs3g.js → index.server-1nq7z1qw.js} +1 -1
- package/dist/server/{index.server-jync915v.js → index.server-2dga5yzr.js} +25 -25
- package/dist/server/index.server-2hqrv7ca.js +9 -0
- package/dist/server/{index.server-69epaape.js → index.server-2qj6s2mh.js} +1 -1
- package/dist/server/{index.server-pt8b65mt.js → index.server-38aywdk1.js} +1 -1
- package/dist/server/{index.server-rermas0k.js → index.server-47v2fhp4.js} +4 -4
- package/dist/server/{index.server-9j5sym59.js → index.server-4x91gzy1.js} +2 -2
- package/dist/server/{index.server-q48q15g7.js → index.server-4y2jtvv1.js} +4 -2
- package/dist/server/index.server-67qgdypc.js +9 -0
- package/dist/server/{index.server-9jete4xx.js → index.server-6sh11ap6.js} +4 -4
- package/dist/server/{index.server-4ztq565m.js → index.server-85p4ydph.js} +1 -1
- package/dist/server/{index.server-4nk7gy0q.js → index.server-894t97kv.js} +1 -1
- package/dist/server/{index.server-1vscnped.js → index.server-8dt36sdm.js} +2 -1
- package/dist/server/{index.server-bfsbp9dz.js → index.server-8xvc73zh.js} +4 -4
- package/dist/server/{index.server-cvnw3hw9.js → index.server-9kz37z89.js} +1 -1
- package/dist/server/{index.server-kc1k02tk.js → index.server-9ykk1kbg.js} +1 -1
- package/dist/server/{index.server-g789yep6.js → index.server-aqethy0w.js} +2 -2
- package/dist/server/{index.server-wc9aggfz.js → index.server-bmxbsk4y.js} +7 -7
- package/dist/server/{index.server-j3ddzcaa.js → index.server-c6pe4kaf.js} +6 -6
- package/dist/server/{index.server-q89dz8h1.js → index.server-d3pqthtp.js} +4 -3
- package/dist/server/{index.server-qfa2rxzx.js → index.server-dg83ke3k.js} +3 -5
- package/dist/server/{index.server-jk4rx4aa.js → index.server-dmmvwy6p.js} +1 -1
- package/dist/server/{index.server-hcfnae5y.js → index.server-dwwqssey.js} +4 -4
- package/dist/server/{index.server-e8x1hgw6.js → index.server-dz1r9xw5.js} +4 -4
- package/dist/server/{index.server-wm7mk5kw.js → index.server-ez5hp0ya.js} +1 -1
- package/dist/server/{index.server-ejyf7e48.js → index.server-fy068yne.js} +1 -1
- package/dist/server/{index.server-wc8dbm5e.js → index.server-g95bk8rc.js} +4 -2
- package/dist/server/index.server-gkazv439.js +576 -0
- package/dist/server/{index.server-dp9j2kkr.js → index.server-h0cvwvhy.js} +1 -1
- package/dist/server/{index.server-pacrqvyz.js → index.server-h90pjrez.js} +1 -1
- package/dist/server/{index.server-p8d04em5.js → index.server-hcsd5gdb.js} +6 -2
- package/dist/server/{index.server-n39drzes.js → index.server-hpeavvnq.js} +1 -1
- package/dist/server/{index.server-1p3patnj.js → index.server-hx91ng7z.js} +1 -1
- package/dist/server/{index.server-jtj3r53y.js → index.server-jgb8yh5k.js} +1 -1
- package/dist/server/{index.server-w1g5q9j9.js → index.server-jtgw9d23.js} +4 -2
- package/dist/server/{index.server-mehav5vs.js → index.server-jxg42jpz.js} +4 -4
- package/dist/server/{index.server-hd8gpehd.js → index.server-jxseyx33.js} +1 -1
- package/dist/server/{index.server-kg2sepsr.js → index.server-krqvnt6p.js} +14 -15
- package/dist/server/{index.server-0e1m3agz.js → index.server-ks49bprh.js} +1 -1
- package/dist/server/{index.server-f0hma3jp.js → index.server-kt0ncrqs.js} +1 -1
- package/dist/server/index.server-m0ezemav.js +170 -0
- package/dist/server/index.server-m191rm44.js +79 -0
- package/dist/server/{index.server-f23vtaw4.js → index.server-marjz8ps.js} +6 -6
- package/dist/server/index.server-mqt1ngqw.js +250 -0
- package/dist/server/{index.server-s9khh4ry.js → index.server-mzzb7dnm.js} +3 -5
- package/dist/server/{index.server-z721a5gp.js → index.server-n82rcv0m.js} +4 -4
- package/dist/server/{index.server-rhhmdxtz.js → index.server-np3c7kx0.js} +4 -4
- package/dist/server/{index.server-hpcs7tmh.js → index.server-p56xxef1.js} +1 -1
- package/dist/server/{index.server-w83kmcrx.js → index.server-pag862vz.js} +10 -10
- package/dist/server/{index.server-gxf0d1p5.js → index.server-q7w4jw89.js} +2 -2
- package/dist/server/{index.server-v4zabrsx.js → index.server-qh9qzd5t.js} +163 -25
- package/dist/server/{index.server-pxg74pyp.js → index.server-qk1h0n02.js} +4 -4
- package/dist/server/{index.server-sh2rxejg.js → index.server-qke3ekjt.js} +1 -1
- package/dist/server/{index.server-73x2d3j3.js → index.server-rbpvcrr3.js} +1 -1
- package/dist/server/{index.server-8cxs4kya.js → index.server-rga8sc7j.js} +41 -44
- package/dist/server/{index.server-e3fnv1g6.js → index.server-sedjxt36.js} +5 -5
- package/dist/server/{index.server-pen9pxt6.js → index.server-sf3nk3j2.js} +2 -2
- package/dist/server/{index.server-7fp0epev.js → index.server-veastatv.js} +4 -4
- package/dist/server/{index.server-jeqg2d22.js → index.server-xeqtpv61.js} +1 -1
- package/dist/server/{index.server-9s4na701.js → index.server-xjnge1yw.js} +4 -4
- package/dist/server/index.server-xtjjmsyq.js +315 -0
- package/dist/server/{index.server-hhxjaeen.js → index.server-xz99aed4.js} +4 -4
- package/dist/server/{index.server-vne4rzfa.js → index.server-y4n8vc08.js} +1 -1
- package/dist/server/{index.server-5d01cn4f.js → index.server-y83kqayt.js} +4 -4
- package/dist/server/{index.server-1nh09ck7.js → index.server-yhzydqxe.js} +5 -5
- package/dist/server/{index.server-atjc1qcq.js → index.server-yz4k36cw.js} +1 -1
- package/dist/server/{index.server-w6k62afr.js → index.server-ze1ymmbw.js} +2 -2
- package/dist/server/{index.server-914v805w.js → index.server-zgd1g8mk.js} +1 -1
- package/dist/server/{index.server-aeexcxdp.js → index.server-zh3r8vfd.js} +1 -1
- package/dist/server/{index.server-10jb2jzm.js → index.server-zsjf8enc.js} +4 -4
- package/package.json +40 -6
- package/src/components/_internal/command-list-context.ts +3 -3
- package/src/components/_internal/create-command-list-state.svelte.ts +39 -13
- package/src/components/approval-card/approval-card-actions.svelte +168 -0
- package/src/components/approval-card/approval-card-state.ts +152 -1
- package/src/components/approval-card/approval-card.css +269 -92
- package/src/components/approval-card/approval-card.examples.json +3 -3
- package/src/components/approval-card/approval-card.schema.json +9 -30
- package/src/components/approval-card/approval-card.schema.ts +13 -31
- package/src/components/approval-card/approval-card.svelte +176 -470
- package/src/components/approval-card/approval-card.types.ts +15 -28
- package/src/components/approval-card/index.ts +1 -0
- package/src/components/card/card.css +5 -0
- package/src/components/card/card.schema.json +1 -1
- package/src/components/card/card.schema.ts +1 -1
- package/src/components/card/card.svelte +1 -0
- package/src/components/card/card.types.ts +2 -2
- package/src/components/chat/chat.schema.json +36 -1
- package/src/components/chat/chat.schema.ts +44 -1
- package/src/components/chat/chat.svelte +12 -0
- package/src/components/chat/chat.types.ts +35 -3
- package/src/components/chat/container/chat.svelte +73 -3
- package/src/components/chat/index.ts +15 -3
- package/src/components/chat/input/chat-attachment-serialization.ts +63 -0
- package/src/components/chat/input/chat-input.svelte +22 -5
- package/src/components/chat/input/index.ts +5 -0
- package/src/components/chat-composer-popover/chat-composer-popover-filter.ts +68 -0
- package/src/components/chat-composer-popover/chat-composer-popover.css +7 -0
- package/src/components/chat-composer-popover/chat-composer-popover.examples.json +13 -0
- package/src/components/chat-composer-popover/chat-composer-popover.schema.json +90 -0
- package/src/components/chat-composer-popover/chat-composer-popover.schema.ts +95 -0
- package/src/components/chat-composer-popover/chat-composer-popover.svelte +234 -0
- package/src/components/chat-composer-popover/chat-composer-popover.types.ts +88 -0
- package/src/components/chat-composer-popover/chat-composer-popover.variables.json +1 -0
- package/src/components/chat-composer-popover/chat-composer-popover.variables.ts +3 -0
- package/src/components/chat-composer-popover/index.ts +19 -0
- package/src/components/code-block/code-block.schema.json +4 -0
- package/src/components/code-block/code-block.schema.ts +5 -0
- package/src/components/code-block/code-block.svelte +3 -3
- package/src/components/code-block/code-block.types.ts +6 -0
- package/src/components/command-item/command-item.svelte +7 -6
- package/src/components/command-menu/command-menu.schema.json +4 -0
- package/src/components/command-menu/command-menu.schema.ts +4 -0
- package/src/components/command-menu/command-menu.svelte +16 -5
- package/src/components/command-menu/command-menu.types.ts +2 -0
- package/src/components/json-viewer/_json-viewer-node.svelte +15 -1
- package/src/components/json-viewer/json-viewer.css +10 -6
- package/src/components/payload-inspector/index.ts +0 -2
- package/src/components/payload-inspector/payload-inspector.css +15 -75
- package/src/components/payload-inspector/payload-inspector.examples.json +5 -5
- package/src/components/payload-inspector/payload-inspector.schema.json +3 -31
- package/src/components/payload-inspector/payload-inspector.schema.ts +3 -36
- package/src/components/payload-inspector/payload-inspector.svelte +46 -239
- package/src/components/payload-inspector/payload-inspector.types.ts +10 -58
- package/src/components/tab/tab.schema.json +6 -2
- package/src/components/tab/tab.schema.ts +8 -2
- package/src/components/tab/tab.svelte +9 -5
- package/src/components/tab/tab.types.ts +8 -2
- package/src/index.ts +18 -5
- package/src/styles/components.css +1 -0
- package/dist/server/index-49we2xfs.js +0 -344
- package/dist/server/index-8fhvxk30.js +0 -265
- package/dist/server/index-x2ysg8ds.js +0 -388
- package/dist/server/index.server-20j0jh30.js +0 -9
- package/dist/server/index.server-dc35kh7d.js +0 -1835
- package/dist/server/index.server-kd4b0342.js +0 -607
- package/dist/server/index.server-n5cdmsz4.js +0 -30
- package/dist/server/index.server-rjap4k7y.js +0 -1389
- package/dist/server/index.server-vt6sn9y4.js +0 -447
- package/dist/server/index.server-w63n618v.js +0 -9
- package/dist/server/index.server-y2pa1k46.js +0 -9
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { inDocumentOrder } from '../../utilities/document-order.ts';
|
|
2
2
|
export class CommandListState {
|
|
3
|
-
|
|
3
|
+
#getListboxId;
|
|
4
|
+
#registeredListboxId = $state('');
|
|
4
5
|
registrations = $state([]);
|
|
5
6
|
registrationsReady = $state(false);
|
|
6
7
|
#itemCounter = 0;
|
|
@@ -15,7 +16,24 @@ export class CommandListState {
|
|
|
15
16
|
? this.#intendedActiveId
|
|
16
17
|
: (this.enabledIds[0] ?? null));
|
|
17
18
|
constructor(listboxId) {
|
|
18
|
-
this
|
|
19
|
+
this.#getListboxId = typeof listboxId === 'function' ? listboxId : () => listboxId;
|
|
20
|
+
this.#registeredListboxId = this.#getListboxId();
|
|
21
|
+
}
|
|
22
|
+
get listboxId() {
|
|
23
|
+
return this.#registeredListboxId;
|
|
24
|
+
}
|
|
25
|
+
syncListboxId(nextListboxId = this.#getListboxId()) {
|
|
26
|
+
const listboxId = nextListboxId;
|
|
27
|
+
if (this.#registeredListboxId === listboxId)
|
|
28
|
+
return;
|
|
29
|
+
this.#registeredListboxId = listboxId;
|
|
30
|
+
this.#intendedActiveId = null;
|
|
31
|
+
this.registrations = this.registrations.map((registration, index) => ({
|
|
32
|
+
...registration,
|
|
33
|
+
id: updateRegistrationHandleId(registration, `${listboxId}-item-${index + 1}`),
|
|
34
|
+
}));
|
|
35
|
+
this.#itemCounter = this.registrations.length;
|
|
36
|
+
this.refreshRegistrationsReady();
|
|
19
37
|
}
|
|
20
38
|
resetActiveItem() {
|
|
21
39
|
this.#intendedActiveId = null;
|
|
@@ -38,22 +56,26 @@ export class CommandListState {
|
|
|
38
56
|
this.#intendedActiveId = id;
|
|
39
57
|
}
|
|
40
58
|
register(input, node) {
|
|
59
|
+
this.syncListboxId();
|
|
41
60
|
const id = `${this.listboxId}-item-${++this.#itemCounter}`;
|
|
42
|
-
|
|
43
|
-
id,
|
|
44
|
-
node,
|
|
45
|
-
getValue: input.getValue,
|
|
46
|
-
getOnselect: input.getOnselect,
|
|
47
|
-
getDisabled: input.getDisabled,
|
|
48
|
-
});
|
|
49
|
-
return {
|
|
61
|
+
const handle = $state({
|
|
50
62
|
id,
|
|
51
63
|
unregister: () => {
|
|
52
|
-
const index = this.registrations.findIndex((
|
|
64
|
+
const index = this.registrations.findIndex((registeredItem) => registeredItem.node === node);
|
|
53
65
|
if (index !== -1)
|
|
54
66
|
this.registrations.splice(index, 1);
|
|
55
67
|
},
|
|
68
|
+
});
|
|
69
|
+
const registration = {
|
|
70
|
+
id,
|
|
71
|
+
node,
|
|
72
|
+
handle,
|
|
73
|
+
getValue: input.getValue,
|
|
74
|
+
getOnselect: input.getOnselect,
|
|
75
|
+
getDisabled: input.getDisabled,
|
|
56
76
|
};
|
|
77
|
+
this.registrations.push(registration);
|
|
78
|
+
return handle;
|
|
57
79
|
}
|
|
58
80
|
activateItemById(id) {
|
|
59
81
|
const record = this.registrations.find((registration) => registration.id === id);
|
|
@@ -122,13 +144,13 @@ export class CommandListState {
|
|
|
122
144
|
return false;
|
|
123
145
|
}
|
|
124
146
|
createContext(activateItemById = (id) => void this.activateItemById(id)) {
|
|
125
|
-
const
|
|
147
|
+
const getListboxId = () => this.listboxId;
|
|
126
148
|
const getActiveItemId = () => this.activeItemId;
|
|
127
149
|
const register = (input, node) => this.register(input, node);
|
|
128
150
|
const setActiveById = (id) => this.setActiveById(id);
|
|
129
151
|
return {
|
|
130
152
|
get listboxId() {
|
|
131
|
-
return
|
|
153
|
+
return getListboxId();
|
|
132
154
|
},
|
|
133
155
|
get activeItemId() {
|
|
134
156
|
return getActiveItemId();
|
|
@@ -142,3 +164,7 @@ export class CommandListState {
|
|
|
142
164
|
export function createCommandListState(listboxId) {
|
|
143
165
|
return new CommandListState(listboxId);
|
|
144
166
|
}
|
|
167
|
+
function updateRegistrationHandleId(registration, id) {
|
|
168
|
+
registration.handle.id = id;
|
|
169
|
+
return id;
|
|
170
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Button from '../button/button.svelte';
|
|
3
|
+
import { formatEditableArguments, parseJsonText } from './approval-card-state.ts';
|
|
4
|
+
let { idBase, requestKey, canEditArguments, argumentsValue, resolve } = $props();
|
|
5
|
+
const reasonId = $derived(`${idBase}-resolution-reason`);
|
|
6
|
+
const editorId = $derived(`${idBase}-edited-arguments`);
|
|
7
|
+
const editRegionId = $derived(`${idBase}-edit-region`);
|
|
8
|
+
const editDescriptionId = $derived(`${idBase}-edit-description`);
|
|
9
|
+
const editErrorId = $derived(`${idBase}-edit-error`);
|
|
10
|
+
let resolutionReason = $state('');
|
|
11
|
+
let rememberResolution = $state(false);
|
|
12
|
+
let editingArguments = $state(false);
|
|
13
|
+
let editedArgumentsText = $state('');
|
|
14
|
+
// A writable `$derived` that reads `requestKey` looked like the simpler
|
|
15
|
+
// reset mechanism, but a $derived re-runs whenever ANY parent prop update
|
|
16
|
+
// touches its host — not only when the tracked value actually changes —
|
|
17
|
+
// so it silently wiped in-progress reason text / edits on every unrelated
|
|
18
|
+
// host re-render. `{#key requestKey}` has the same intent but was
|
|
19
|
+
// unreliable in practice here (a fresh DOM node with a stale value).
|
|
20
|
+
// Comparing the previous value explicitly, inside the effect, is the
|
|
21
|
+
// one thing that's actually gated on requestKey CHANGING, not merely
|
|
22
|
+
// being re-touched.
|
|
23
|
+
let previousRequestKey = requestKey;
|
|
24
|
+
$effect(() => {
|
|
25
|
+
if (requestKey === previousRequestKey)
|
|
26
|
+
return;
|
|
27
|
+
previousRequestKey = requestKey;
|
|
28
|
+
resolutionReason = '';
|
|
29
|
+
rememberResolution = false;
|
|
30
|
+
// A new request must never leave a stale editor open, even if its
|
|
31
|
+
// arguments happen to serialize identically to the previous request's
|
|
32
|
+
// (the separate snapshot effect below wouldn't see a change in that
|
|
33
|
+
// case) — an edit must never be confirmed against the wrong request.
|
|
34
|
+
editingArguments = false;
|
|
35
|
+
editedArgumentsText = '';
|
|
36
|
+
});
|
|
37
|
+
// Separate from the identity reset above: a host can revise
|
|
38
|
+
// `operation.argsPreview` for the SAME request (e.g. a live update) while
|
|
39
|
+
// the edit panel is open. Comparing the formatted snapshot — not object
|
|
40
|
+
// identity, which changes on unrelated re-renders too — closes a stale
|
|
41
|
+
// editor whenever the underlying arguments actually change, so a confirmed
|
|
42
|
+
// edit can never be based on arguments older than what PayloadInspector is
|
|
43
|
+
// currently showing. Re-opening reseeds from the current value.
|
|
44
|
+
let previousArgumentsSnapshot = formatEditableArguments(argumentsValue);
|
|
45
|
+
$effect(() => {
|
|
46
|
+
const snapshot = formatEditableArguments(argumentsValue);
|
|
47
|
+
if (snapshot === previousArgumentsSnapshot)
|
|
48
|
+
return;
|
|
49
|
+
previousArgumentsSnapshot = snapshot;
|
|
50
|
+
editingArguments = false;
|
|
51
|
+
editedArgumentsText = '';
|
|
52
|
+
});
|
|
53
|
+
const editParseResult = $derived(parseJsonText(editedArgumentsText));
|
|
54
|
+
function emitResolution(decision, editedArgs) {
|
|
55
|
+
const trimmedReason = resolutionReason.trim();
|
|
56
|
+
const resolution = {
|
|
57
|
+
decision,
|
|
58
|
+
remember: rememberResolution,
|
|
59
|
+
};
|
|
60
|
+
if (decision === 'approve_with_edits') {
|
|
61
|
+
resolution.editedArgs = editedArgs;
|
|
62
|
+
}
|
|
63
|
+
if (trimmedReason) {
|
|
64
|
+
resolution.reason = trimmedReason;
|
|
65
|
+
}
|
|
66
|
+
resolve(resolution);
|
|
67
|
+
}
|
|
68
|
+
function toggleEditingArguments() {
|
|
69
|
+
if (!canEditArguments)
|
|
70
|
+
return;
|
|
71
|
+
if (!editingArguments) {
|
|
72
|
+
editedArgumentsText = formatEditableArguments(argumentsValue);
|
|
73
|
+
}
|
|
74
|
+
editingArguments = !editingArguments;
|
|
75
|
+
}
|
|
76
|
+
function handleConfirmEditedApproval() {
|
|
77
|
+
if (!canEditArguments || !editParseResult.ok)
|
|
78
|
+
return;
|
|
79
|
+
emitResolution('approve_with_edits', editParseResult.value);
|
|
80
|
+
}
|
|
81
|
+
</script>
|
|
82
|
+
|
|
83
|
+
<div class="cinder-approval-card__actions">
|
|
84
|
+
<div class="cinder-approval-card__resolution-controls">
|
|
85
|
+
<label class="cinder-approval-card__control-label" for={reasonId}>Reason</label>
|
|
86
|
+
<textarea
|
|
87
|
+
id={reasonId}
|
|
88
|
+
class="cinder-approval-card__textarea cinder-approval-card__textarea--reason"
|
|
89
|
+
bind:value={resolutionReason}
|
|
90
|
+
rows="2"
|
|
91
|
+
></textarea>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div class="cinder-approval-card__action-row" role="group" aria-label="Approval actions">
|
|
95
|
+
<label class="cinder-approval-card__remember-control">
|
|
96
|
+
<input type="checkbox" bind:checked={rememberResolution} />
|
|
97
|
+
<span>Don't ask again for operations like this</span>
|
|
98
|
+
</label>
|
|
99
|
+
|
|
100
|
+
<div class="cinder-approval-card__action-buttons">
|
|
101
|
+
<Button
|
|
102
|
+
type="button"
|
|
103
|
+
variant="ghost"
|
|
104
|
+
class="cinder-approval-card__dismiss"
|
|
105
|
+
onclick={() => emitResolution('cancel')}
|
|
106
|
+
>
|
|
107
|
+
Dismiss
|
|
108
|
+
</Button>
|
|
109
|
+
<Button type="button" variant="soft-danger" onclick={() => emitResolution('deny')}>
|
|
110
|
+
Deny
|
|
111
|
+
</Button>
|
|
112
|
+
{#if canEditArguments}
|
|
113
|
+
<Button
|
|
114
|
+
type="button"
|
|
115
|
+
variant="secondary"
|
|
116
|
+
onclick={toggleEditingArguments}
|
|
117
|
+
aria-expanded={editingArguments}
|
|
118
|
+
aria-controls={editingArguments ? editRegionId : undefined}
|
|
119
|
+
>
|
|
120
|
+
Approve with edits
|
|
121
|
+
</Button>
|
|
122
|
+
{/if}
|
|
123
|
+
<Button type="button" variant="primary" onclick={() => emitResolution('approve')}>
|
|
124
|
+
Approve
|
|
125
|
+
</Button>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
{#if editingArguments && canEditArguments}
|
|
130
|
+
<div id={editRegionId} class="cinder-approval-card__editor">
|
|
131
|
+
<label class="cinder-approval-card__control-label" for={editorId}>
|
|
132
|
+
Edited arguments JSON
|
|
133
|
+
</label>
|
|
134
|
+
<p id={editDescriptionId} class="cinder-approval-card__muted">
|
|
135
|
+
Approving sends the parsed JSON below instead of the original arguments.
|
|
136
|
+
</p>
|
|
137
|
+
<textarea
|
|
138
|
+
id={editorId}
|
|
139
|
+
class="cinder-approval-card__textarea"
|
|
140
|
+
bind:value={editedArgumentsText}
|
|
141
|
+
rows="8"
|
|
142
|
+
spellcheck="false"
|
|
143
|
+
aria-describedby={editParseResult.ok
|
|
144
|
+
? editDescriptionId
|
|
145
|
+
: `${editDescriptionId} ${editErrorId}`}
|
|
146
|
+
aria-invalid={editParseResult.ok ? undefined : 'true'}
|
|
147
|
+
{@attach (element) => {
|
|
148
|
+
element.focus();
|
|
149
|
+
}}
|
|
150
|
+
></textarea>
|
|
151
|
+
{#if !editParseResult.ok}
|
|
152
|
+
<p id={editErrorId} class="cinder-approval-card__error" role="alert">
|
|
153
|
+
{editParseResult.message}
|
|
154
|
+
</p>
|
|
155
|
+
{/if}
|
|
156
|
+
<div class="cinder-approval-card__editor-actions">
|
|
157
|
+
<Button
|
|
158
|
+
type="button"
|
|
159
|
+
variant="primary"
|
|
160
|
+
onclick={handleConfirmEditedApproval}
|
|
161
|
+
disabled={!editParseResult.ok}
|
|
162
|
+
>
|
|
163
|
+
Confirm edited approval
|
|
164
|
+
</Button>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
{/if}
|
|
168
|
+
</div>
|
|
@@ -1,5 +1,40 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StatusDotStatus } from '../status-dot/status-dot.types.ts';
|
|
2
|
+
import type { ApprovalState, ApprovalToolRisk } from './approval-card.types.ts';
|
|
2
3
|
|
|
4
|
+
/** Character budget for the serialized arguments preview before truncation. */
|
|
5
|
+
export const ARGUMENTS_PREVIEW_MAX_CHARACTERS = 4_096;
|
|
6
|
+
|
|
7
|
+
/** Visible label for each risk level. */
|
|
8
|
+
export const RISK_LABELS = {
|
|
9
|
+
low: 'Low risk',
|
|
10
|
+
medium: 'Medium risk',
|
|
11
|
+
high: 'High risk',
|
|
12
|
+
} as const satisfies Record<ApprovalToolRisk, string>;
|
|
13
|
+
|
|
14
|
+
/** Visible label for each approval state. */
|
|
15
|
+
export const STATE_LABELS = {
|
|
16
|
+
pending: 'Pending',
|
|
17
|
+
approved: 'Approved',
|
|
18
|
+
approved_with_edits: 'Approved with edits',
|
|
19
|
+
denied: 'Denied',
|
|
20
|
+
expired: 'Expired',
|
|
21
|
+
cancelled: 'Cancelled',
|
|
22
|
+
} as const satisfies Record<ApprovalState, string>;
|
|
23
|
+
|
|
24
|
+
/** StatusDot status for each approval state. */
|
|
25
|
+
export const STATE_DOT_STATUS = {
|
|
26
|
+
pending: 'pending',
|
|
27
|
+
approved: 'success',
|
|
28
|
+
approved_with_edits: 'success',
|
|
29
|
+
denied: 'danger',
|
|
30
|
+
expired: 'neutral',
|
|
31
|
+
cancelled: 'offline',
|
|
32
|
+
} as const satisfies Record<ApprovalState, StatusDotStatus>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Resolves the state shown to the approver: a pending approval whose
|
|
36
|
+
* expiration timestamp has passed presents as expired.
|
|
37
|
+
*/
|
|
3
38
|
export function resolveEffectiveApprovalState(
|
|
4
39
|
approvalState: ApprovalState,
|
|
5
40
|
expirationTimestamp: number | undefined,
|
|
@@ -9,6 +44,7 @@ export function resolveEffectiveApprovalState(
|
|
|
9
44
|
return resolveComparisonTime(currentTime) >= expirationTimestamp ? 'expired' : approvalState;
|
|
10
45
|
}
|
|
11
46
|
|
|
47
|
+
/** Whether approval actions may still be taken on the request. */
|
|
12
48
|
export function isApprovalActionable(
|
|
13
49
|
approvalState: ApprovalState,
|
|
14
50
|
expirationTimestamp: number | undefined,
|
|
@@ -22,3 +58,118 @@ export function isApprovalActionable(
|
|
|
22
58
|
function resolveComparisonTime(currentTime: number | undefined): number {
|
|
23
59
|
return currentTime ?? Date.now();
|
|
24
60
|
}
|
|
61
|
+
|
|
62
|
+
/** Parses an ISO expiration timestamp, returning undefined for invalid input. */
|
|
63
|
+
export function parseExpirationTimestamp(value: string | undefined): number | undefined {
|
|
64
|
+
if (!value) return undefined;
|
|
65
|
+
const timestamp = Date.parse(value);
|
|
66
|
+
return Number.isFinite(timestamp) ? timestamp : undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Formats a millisecond duration as a compact countdown such as `2h 5m` or `45s`. */
|
|
70
|
+
export function formatRemainingTime(milliseconds: number): string {
|
|
71
|
+
const totalSeconds = Math.max(0, Math.ceil(milliseconds / 1_000));
|
|
72
|
+
const hours = Math.floor(totalSeconds / 3_600);
|
|
73
|
+
const minutes = Math.floor((totalSeconds % 3_600) / 60);
|
|
74
|
+
const seconds = totalSeconds % 60;
|
|
75
|
+
|
|
76
|
+
if (hours > 0) return `${hours}h ${minutes}m`;
|
|
77
|
+
if (minutes > 0) return `${minutes}m ${seconds}s`;
|
|
78
|
+
return `${seconds}s`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Accepts serialized JSON strings as argument previews by parsing them into
|
|
83
|
+
* their structured form; any other value passes through unchanged.
|
|
84
|
+
*/
|
|
85
|
+
export function normalizeArgumentsPreviewValue(value: unknown): unknown {
|
|
86
|
+
if (typeof value !== 'string') return value;
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(value);
|
|
90
|
+
} catch {
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Bounds the arguments preview: values whose serialized form exceeds the
|
|
97
|
+
* character budget are replaced with a truncation notice and an excerpt.
|
|
98
|
+
*/
|
|
99
|
+
export function prepareArgumentsPreview(value: unknown): { value: unknown; truncated: boolean } {
|
|
100
|
+
try {
|
|
101
|
+
const serialized = JSON.stringify(value);
|
|
102
|
+
if (typeof serialized !== 'string' || serialized.length <= ARGUMENTS_PREVIEW_MAX_CHARACTERS) {
|
|
103
|
+
// Pass the original value through unchanged — including strings.
|
|
104
|
+
// PayloadInspector does its own parsing/display/copy handling for
|
|
105
|
+
// strings; re-serializing here would hand it an already-quoted JSON
|
|
106
|
+
// string, which displays unquoted but copies quoted (a mismatch).
|
|
107
|
+
return { value, truncated: false };
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
value: {
|
|
111
|
+
notice: 'Arguments preview truncated',
|
|
112
|
+
originalCharacters: serialized.length,
|
|
113
|
+
displayedCharacters: ARGUMENTS_PREVIEW_MAX_CHARACTERS,
|
|
114
|
+
excerpt: serialized.slice(0, ARGUMENTS_PREVIEW_MAX_CHARACTERS),
|
|
115
|
+
},
|
|
116
|
+
truncated: true,
|
|
117
|
+
};
|
|
118
|
+
} catch {
|
|
119
|
+
return { value, truncated: false };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Serializes the arguments preview as the editable JSON seed text. */
|
|
124
|
+
export function formatEditableArguments(value: unknown): string {
|
|
125
|
+
try {
|
|
126
|
+
const serialized = JSON.stringify(value, null, 2);
|
|
127
|
+
return serialized ?? 'null';
|
|
128
|
+
} catch {
|
|
129
|
+
return '{}';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Parses editor text as JSON, returning a friendly error for invalid input. */
|
|
134
|
+
export function parseJsonText(
|
|
135
|
+
text: string,
|
|
136
|
+
): { ok: true; value: unknown } | { ok: false; message: string } {
|
|
137
|
+
try {
|
|
138
|
+
return { ok: true, value: JSON.parse(text) };
|
|
139
|
+
} catch {
|
|
140
|
+
return { ok: false, message: 'Edited arguments must be valid JSON.' };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Reduces environment entries to unique variable names. Values accidentally
|
|
146
|
+
* supplied as `NAME=value` are stripped so no secret material is rendered.
|
|
147
|
+
*/
|
|
148
|
+
export function sanitizeEnvironmentNames(names: string[]): string[] {
|
|
149
|
+
const seen = new Set<string>();
|
|
150
|
+
const sanitizedNames: string[] = [];
|
|
151
|
+
|
|
152
|
+
for (const name of names) {
|
|
153
|
+
const [firstPart] = name.split('=');
|
|
154
|
+
const sanitizedName = firstPart?.trim() ?? '';
|
|
155
|
+
if (!sanitizedName || seen.has(sanitizedName)) continue;
|
|
156
|
+
seen.add(sanitizedName);
|
|
157
|
+
sanitizedNames.push(sanitizedName);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return sanitizedNames;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Collapses duplicate file paths while preserving first-seen order. */
|
|
164
|
+
export function dedupeFilePaths(paths: string[]): string[] {
|
|
165
|
+
const seen = new Set<string>();
|
|
166
|
+
const uniquePaths: string[] = [];
|
|
167
|
+
|
|
168
|
+
for (const path of paths) {
|
|
169
|
+
if (seen.has(path)) continue;
|
|
170
|
+
seen.add(path);
|
|
171
|
+
uniquePaths.push(path);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return uniquePaths;
|
|
175
|
+
}
|