@lostgradient/cinder 0.8.0 → 0.11.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 +25 -0
- package/README.md +2 -2
- package/components.json +140 -18
- 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 +435 -218
- 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/builders.d.ts +17 -8
- 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/conversation-model.d.ts +1 -1
- package/dist/components/chat/index.d.ts +4 -4
- package/dist/components/chat/index.js +2767 -6278
- 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/utilities/conversation.d.ts +6 -6
- 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 +577 -4537
- package/dist/components/chat-conversation-list/index.js +24 -3984
- 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/connection-indicator/connection-indicator.css +136 -0
- package/dist/components/connection-indicator/connection-indicator.css.d.ts +1 -0
- package/dist/components/connection-indicator/connection-indicator.schema.d.ts +3 -0
- package/dist/components/connection-indicator/connection-indicator.schema.js +89 -0
- package/dist/components/connection-indicator/connection-indicator.svelte.d.ts +21 -0
- package/dist/components/connection-indicator/connection-indicator.types.d.ts +46 -0
- package/dist/components/connection-indicator/connection-indicator.variables.d.ts +2 -0
- package/dist/components/connection-indicator/connection-indicator.variables.js +61 -0
- package/dist/components/connection-indicator/index.d.ts +5 -0
- package/dist/components/connection-indicator/index.js +409 -0
- package/dist/components/container/container.schema.js +4 -4
- package/dist/components/event-stream-viewer/index.js +44 -44
- package/dist/components/experimental/json-viewer/index.js +44 -44
- package/dist/components/invocation-rule-builder/index.d.ts +1 -1
- package/dist/components/invocation-rule-builder/index.js +305 -150
- package/dist/components/invocation-rule-builder/invocation-rule-builder.css +28 -0
- package/dist/components/invocation-rule-builder/invocation-rule-builder.schema.js +89 -5
- package/dist/components/invocation-rule-builder/invocation-rule-builder.svelte.d.ts +2 -1
- package/dist/components/invocation-rule-builder/invocation-rule-builder.types.d.ts +114 -16
- 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/run-step-timeline/index.d.ts +1 -1
- package/dist/components/run-step-timeline/index.js +992 -559
- package/dist/components/run-step-timeline/run-step-branch-disclosure.svelte.d.ts +17 -0
- package/dist/components/run-step-timeline/run-step-timeline.css +124 -0
- package/dist/components/run-step-timeline/run-step-timeline.schema.js +873 -350
- package/dist/components/run-step-timeline/run-step-timeline.svelte.d.ts +1 -15
- package/dist/components/run-step-timeline/run-step-timeline.types.d.ts +182 -5
- package/dist/components/run-step-timeline/run-step-timeline.utilities.d.ts +52 -0
- package/dist/components/schedule-builder/index.d.ts +5 -0
- package/dist/components/schedule-builder/index.js +3176 -0
- package/dist/components/schedule-builder/schedule-builder.css +121 -0
- package/dist/components/schedule-builder/schedule-builder.css.d.ts +1 -0
- package/dist/components/schedule-builder/schedule-builder.schema.d.ts +3 -0
- package/dist/components/schedule-builder/schedule-builder.schema.js +141 -0
- package/dist/components/schedule-builder/schedule-builder.svelte.d.ts +22 -0
- package/dist/components/schedule-builder/schedule-builder.types.d.ts +130 -0
- package/dist/components/schedule-builder/schedule-builder.utilities.d.ts +78 -0
- package/dist/components/schedule-builder/schedule-builder.variables.d.ts +2 -0
- package/dist/components/schedule-builder/schedule-builder.variables.js +61 -0
- 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/tag-input/index.js +22 -4
- package/dist/components/tag-input/tag-input.schema.js +5 -1
- package/dist/components/tag-input/tag-input.types.d.ts +4 -0
- package/dist/components/team-section/index.js +2 -1
- package/dist/components/testimonial-section/index.js +2 -1
- package/dist/index.d.ts +10 -4
- package/dist/index.js +28577 -30168
- package/dist/server/components/access-gate/index.js +3 -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 +15 -12
- package/dist/server/components/chat-composer-popover/index.js +26 -0
- package/dist/server/components/chat-conversation-header/index.js +10 -11
- 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/connection-indicator/index.js +16 -0
- 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 +9 -8
- 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/invocation-rule-builder/index.js +1 -1
- package/dist/server/components/json-schema-editor/index.js +24 -23
- 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 +27 -26
- package/dist/server/components/run-step-timeline/index.js +2 -2
- package/dist/server/components/schedule-builder/index.js +30 -0
- 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/side-navigation/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/time-field/index.js +5 -3
- package/dist/server/components/toggle/index.js +2 -2
- package/dist/server/components/tooltip/index.js +1 -1
- package/dist/server/index.js +235 -211
- package/dist/server/{index.server-20y4mdhm.js → index.server-0chhpkg7.js} +40 -14
- package/dist/server/index.server-0sx92swg.js +9 -0
- package/dist/server/{index.server-ecm1vs3g.js → index.server-1nq7z1qw.js} +1 -1
- package/dist/server/{index.server-s9khh4ry.js → index.server-2bbwajb2.js} +3 -5
- 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-gxf0d1p5.js → index.server-2s5h1d05.js} +2 -2
- package/dist/server/{index.server-qfa2rxzx.js → index.server-2zdbz3rj.js} +3 -5
- package/dist/server/{index.server-pt8b65mt.js → index.server-38aywdk1.js} +1 -1
- package/dist/server/{index.server-0jhra85x.js → index.server-3w72dxz7.js} +4 -4
- package/dist/server/{index.server-rermas0k.js → index.server-47v2fhp4.js} +4 -4
- package/dist/server/{index.server-v4zabrsx.js → index.server-4x4hgvqe.js} +434 -26
- 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-j3ddzcaa.js → index.server-5gzyqv78.js} +6 -6
- package/dist/server/index.server-67qgdypc.js +9 -0
- package/dist/server/index.server-6hnfzc7f.js +263 -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-be9bpqeh.js +93 -0
- package/dist/server/{index.server-wc9aggfz.js → index.server-bmxbsk4y.js} +7 -7
- package/dist/server/{index.server-f3z7tpxr.js → index.server-c42b462p.js} +2 -4
- package/dist/server/{index.server-7vyzen5x.js → index.server-c5qv3p61.js} +171 -63
- package/dist/server/index.server-cch0eed5.js +144 -0
- package/dist/server/{index.server-q89dz8h1.js → index.server-d3pqthtp.js} +4 -3
- 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-wc8dbm5e.js → index.server-g95bk8rc.js} +4 -2
- package/dist/server/index.server-gkazv439.js +576 -0
- package/dist/server/index.server-gmh5ar16.js +2 -0
- package/dist/server/{index.server-dp9j2kkr.js → index.server-h0cvwvhy.js} +1 -1
- package/dist/server/{index.server-cbtg8rq5.js → index.server-h89zk5ev.js} +8 -8
- 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-mehav5vs.js → index.server-jdcq5zza.js} +7 -7
- package/dist/server/{index.server-jync915v.js → index.server-jfrssta6.js} +25 -25
- package/dist/server/{index.server-jtj3r53y.js → index.server-jgb8yh5k.js} +1 -1
- package/dist/server/{index.server-ejyf7e48.js → index.server-jj76374p.js} +1 -1
- package/dist/server/{index.server-w1g5q9j9.js → index.server-jtgw9d23.js} +4 -2
- 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-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-qbkxz7r2.js +750 -0
- 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-f23vtaw4.js → index.server-tcay903b.js} +8 -7
- 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-z38bxms8.js +734 -0
- package/dist/server/{index.server-atjc1qcq.js → index.server-z7hxtqs1.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 +102 -5
- 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/builders.ts +445 -14
- 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/conversation-model.ts +1 -0
- package/src/components/chat/index.ts +16 -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/utilities/conversation.ts +33 -15
- 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/connection-indicator/connection-indicator.css +136 -0
- package/src/components/connection-indicator/connection-indicator.examples.json +31 -0
- package/src/components/connection-indicator/connection-indicator.schema.json +29 -0
- package/src/components/connection-indicator/connection-indicator.schema.ts +36 -0
- package/src/components/connection-indicator/connection-indicator.svelte +63 -0
- package/src/components/connection-indicator/connection-indicator.types.ts +58 -0
- package/src/components/connection-indicator/connection-indicator.variables.json +1 -0
- package/src/components/connection-indicator/connection-indicator.variables.ts +3 -0
- package/src/components/connection-indicator/index.ts +10 -0
- package/src/components/container/container.schema.json +3 -3
- package/src/components/container/container.schema.ts +3 -3
- package/src/components/invocation-rule-builder/index.ts +4 -0
- package/src/components/invocation-rule-builder/invocation-rule-builder.css +28 -0
- package/src/components/invocation-rule-builder/invocation-rule-builder.examples.json +6 -0
- package/src/components/invocation-rule-builder/invocation-rule-builder.schema.json +76 -3
- package/src/components/invocation-rule-builder/invocation-rule-builder.schema.ts +83 -3
- package/src/components/invocation-rule-builder/invocation-rule-builder.svelte +326 -113
- package/src/components/invocation-rule-builder/invocation-rule-builder.types.ts +157 -43
- 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/run-step-timeline/index.ts +8 -0
- package/src/components/run-step-timeline/run-step-branch-disclosure.svelte +16 -0
- package/src/components/run-step-timeline/run-step-timeline.css +124 -0
- package/src/components/run-step-timeline/run-step-timeline.examples.json +18 -0
- package/src/components/run-step-timeline/run-step-timeline.schema.json +872 -349
- package/src/components/run-step-timeline/run-step-timeline.schema.ts +931 -349
- package/src/components/run-step-timeline/run-step-timeline.svelte +387 -268
- package/src/components/run-step-timeline/run-step-timeline.types.ts +192 -5
- package/src/components/run-step-timeline/run-step-timeline.utilities.ts +242 -0
- package/src/components/schedule-builder/index.ts +14 -0
- package/src/components/schedule-builder/schedule-builder.css +121 -0
- package/src/components/schedule-builder/schedule-builder.examples.json +31 -0
- package/src/components/schedule-builder/schedule-builder.schema.json +78 -0
- package/src/components/schedule-builder/schedule-builder.schema.ts +86 -0
- package/src/components/schedule-builder/schedule-builder.svelte +629 -0
- package/src/components/schedule-builder/schedule-builder.types.ts +137 -0
- package/src/components/schedule-builder/schedule-builder.utilities.ts +344 -0
- package/src/components/schedule-builder/schedule-builder.variables.json +1 -0
- package/src/components/schedule-builder/schedule-builder.variables.ts +3 -0
- 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/components/tag-input/tag-input.schema.json +4 -0
- package/src/components/tag-input/tag-input.schema.ts +4 -0
- package/src/components/tag-input/tag-input.svelte +20 -3
- package/src/components/tag-input/tag-input.types.ts +4 -0
- package/src/index.ts +41 -5
- package/src/styles/components.css +3 -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-pxg74pyp.js +0 -393
- 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
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export {};
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import { classNames } from '../../utilities/class-names.ts';
|
|
7
|
+
import Chip from '../chip/chip.svelte';
|
|
8
|
+
import Input from '../input/input.svelte';
|
|
9
|
+
import NumberInput from '../number-input/number-input.svelte';
|
|
10
|
+
import Segment from '../segment/segment.svelte';
|
|
11
|
+
import SegmentedControl from '../segmented-control/segmented-control.svelte';
|
|
12
|
+
import Select from '../select/select.svelte';
|
|
13
|
+
import TimeField from '../time-field/time-field.svelte';
|
|
14
|
+
import { CRON_FIELDS, WEEKDAYS, INTERVAL_UNITS, cronFieldsValid, defaultScheduleValue, describeValue, joinCron, lowerDailyAt, lowerEveryN, lowerMonthlyOnDay, lowerWeeklyAt, validateCronField, valueToCronFields, valueToInterval, } from './schedule-builder.utilities.ts';
|
|
15
|
+
const PRESET_EVERY_UNIT_OPTIONS = [
|
|
16
|
+
{ value: 'minutes', label: 'Minutes' },
|
|
17
|
+
{ value: 'hours', label: 'Hours' },
|
|
18
|
+
];
|
|
19
|
+
const INTERVAL_UNIT_LABELS = {
|
|
20
|
+
minutes: 'Minutes',
|
|
21
|
+
hours: 'Hours',
|
|
22
|
+
days: 'Days',
|
|
23
|
+
weeks: 'Weeks',
|
|
24
|
+
};
|
|
25
|
+
const INTERVAL_UNIT_OPTIONS = INTERVAL_UNITS.map((unit) => ({
|
|
26
|
+
value: unit,
|
|
27
|
+
label: INTERVAL_UNIT_LABELS[unit],
|
|
28
|
+
}));
|
|
29
|
+
let { value, onchange, computeNextFires, previewCount = 5, timezoneLabel, timezone, label = 'Schedule', class: className, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, ...rest } = $props();
|
|
30
|
+
const baseId = $props.id();
|
|
31
|
+
// Normalize ARIA label props: an empty string `aria-label=""` (or
|
|
32
|
+
// `aria-labelledby=""`) suppresses the accessible-name fallback (ARIA spec
|
|
33
|
+
// §4.3) without actually providing a name. Convert empty strings to
|
|
34
|
+
// `undefined` so the DOM attribute is omitted and the `label` default
|
|
35
|
+
// remains the accessible name. Matches button.svelte's normalization.
|
|
36
|
+
const normalizedAriaLabel = $derived(typeof ariaLabel === 'string' && ariaLabel.trim().length > 0 ? ariaLabel : undefined);
|
|
37
|
+
const normalizedAriaLabelledby = $derived(typeof ariaLabelledby === 'string' && ariaLabelledby.trim().length > 0
|
|
38
|
+
? ariaLabelledby
|
|
39
|
+
: undefined);
|
|
40
|
+
const resolvedAriaLabel = $derived(normalizedAriaLabelledby === undefined && normalizedAriaLabel === undefined
|
|
41
|
+
? label
|
|
42
|
+
: normalizedAriaLabel);
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Seed local field state from the `value` prop (or the shared default), so
|
|
45
|
+
// mid-edit intermediate text (e.g. a half-typed cron range) has somewhere to
|
|
46
|
+
// live without fighting a controlled `value` prop on every keystroke. This
|
|
47
|
+
// seeding runs at construction AND — guarded against re-seeding on a mere
|
|
48
|
+
// re-render or an echoed `onchange` — again whenever the CONSUMER hands in a
|
|
49
|
+
// genuinely different `value` (see the resync `$effect` below `lastKnownValue`).
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
const seedValue = value ?? defaultScheduleValue();
|
|
52
|
+
/** Structural equality for the small `ScheduleValue` discriminated union. */
|
|
53
|
+
function scheduleValuesEqual(a, b) {
|
|
54
|
+
if (a.mode !== b.mode)
|
|
55
|
+
return false;
|
|
56
|
+
if (a.mode === 'cron' && b.mode === 'cron')
|
|
57
|
+
return a.expression === b.expression;
|
|
58
|
+
if (a.mode === 'interval' && b.mode === 'interval') {
|
|
59
|
+
return a.every === b.every && a.unit === b.unit;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The authoring mode to open for a given value. A minutes/hours interval
|
|
65
|
+
* (or no value at all) cleanly matches the "every N" preset — and is
|
|
66
|
+
* already seeded correctly there by `seedFieldsFromValue` below — so those
|
|
67
|
+
* open `presets`. Any other `interval` (days/weeks, which presets cannot
|
|
68
|
+
* represent) opens directly in `interval` mode; any `cron` value opens
|
|
69
|
+
* directly in `cron` mode. Either way the destination mode's fields are
|
|
70
|
+
* seeded from the value, so the summary and preview are correct immediately
|
|
71
|
+
* instead of showing the presets default.
|
|
72
|
+
*/
|
|
73
|
+
function initialAuthoringMode(candidateValue) {
|
|
74
|
+
if (candidateValue === undefined)
|
|
75
|
+
return 'presets';
|
|
76
|
+
if (candidateValue.mode === 'cron')
|
|
77
|
+
return 'cron';
|
|
78
|
+
return candidateValue.unit === 'minutes' || candidateValue.unit === 'hours'
|
|
79
|
+
? 'presets'
|
|
80
|
+
: 'interval';
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Computes every field this component seeds from a `ScheduleValue` — shared
|
|
84
|
+
* by the initial seed below and the resync `$effect` (see `lastKnownValue`),
|
|
85
|
+
* so a later controlled `value` change is seeded exactly like the first
|
|
86
|
+
* render. `presetDailyTime`/`presetWeeklyDays`/`presetWeeklyTime`/
|
|
87
|
+
* `presetMonthlyDay`/`presetMonthlyTime` have no general inverse from an
|
|
88
|
+
* arbitrary cron expression (only `valueToInterval` exists), so both the
|
|
89
|
+
* initial seed and a resync reset them to the same neutral defaults.
|
|
90
|
+
*/
|
|
91
|
+
function seedFieldsFromValue(seededValue) {
|
|
92
|
+
const interval = valueToInterval(seededValue);
|
|
93
|
+
const isMinutesOrHours = interval !== undefined && (interval.unit === 'minutes' || interval.unit === 'hours');
|
|
94
|
+
return {
|
|
95
|
+
authoringMode: initialAuthoringMode(seededValue),
|
|
96
|
+
cronFields: valueToCronFields(seededValue),
|
|
97
|
+
intervalEvery: interval?.every ?? 15,
|
|
98
|
+
intervalUnit: interval?.unit ?? 'minutes',
|
|
99
|
+
presetKind: 'every',
|
|
100
|
+
presetEveryValue: isMinutesOrHours ? interval.every : 15,
|
|
101
|
+
presetEveryUnit: (isMinutesOrHours ? interval.unit : 'minutes'),
|
|
102
|
+
presetDailyTime: '09:00',
|
|
103
|
+
presetWeeklyDays: [],
|
|
104
|
+
presetWeeklyTime: '09:00',
|
|
105
|
+
presetMonthlyDay: 1,
|
|
106
|
+
presetMonthlyTime: '09:00',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const initialSeed = seedFieldsFromValue(seedValue);
|
|
110
|
+
let authoringMode = $state(initialSeed.authoringMode);
|
|
111
|
+
let presetKind = $state(initialSeed.presetKind);
|
|
112
|
+
let cronFields = $state(initialSeed.cronFields);
|
|
113
|
+
let intervalEvery = $state(initialSeed.intervalEvery);
|
|
114
|
+
let intervalUnit = $state(initialSeed.intervalUnit);
|
|
115
|
+
let presetEveryValue = $state(initialSeed.presetEveryValue);
|
|
116
|
+
let presetEveryUnit = $state(initialSeed.presetEveryUnit);
|
|
117
|
+
let presetDailyTime = $state(initialSeed.presetDailyTime);
|
|
118
|
+
let presetWeeklyDays = $state(initialSeed.presetWeeklyDays);
|
|
119
|
+
let presetWeeklyTime = $state(initialSeed.presetWeeklyTime);
|
|
120
|
+
let presetMonthlyDay = $state(initialSeed.presetMonthlyDay);
|
|
121
|
+
let presetMonthlyTime = $state(initialSeed.presetMonthlyTime);
|
|
122
|
+
function valueForPresets() {
|
|
123
|
+
switch (presetKind) {
|
|
124
|
+
case 'every':
|
|
125
|
+
return lowerEveryN(presetEveryValue, presetEveryUnit);
|
|
126
|
+
case 'daily':
|
|
127
|
+
return lowerDailyAt(presetDailyTime);
|
|
128
|
+
case 'weekly':
|
|
129
|
+
return lowerWeeklyAt(presetWeeklyDays, presetWeeklyTime);
|
|
130
|
+
case 'monthly':
|
|
131
|
+
return lowerMonthlyOnDay(presetMonthlyDay, presetMonthlyTime);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** The value the given authoring mode currently represents, from its own field state. */
|
|
135
|
+
function valueForMode(mode) {
|
|
136
|
+
if (mode === 'cron')
|
|
137
|
+
return { mode: 'cron', expression: joinCron(cronFields) };
|
|
138
|
+
if (mode === 'interval')
|
|
139
|
+
return { mode: 'interval', every: intervalEvery, unit: intervalUnit };
|
|
140
|
+
return valueForPresets();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The value the active authoring mode currently represents. This is ONLY
|
|
144
|
+
* ever `cron` or `interval` — presets are sugar that lower to one of the
|
|
145
|
+
* two via the matching `lower*` utility, so `mode: 'preset'` never appears.
|
|
146
|
+
*/
|
|
147
|
+
const currentValue = $derived(valueForMode(authoringMode));
|
|
148
|
+
/**
|
|
149
|
+
* Whether `currentValue` is safe to hand to the consumer's `computeNextFires`.
|
|
150
|
+
* In cron mode a mid-edit field can make the joined expression invalid (e.g.
|
|
151
|
+
* an out-of-range hour); a real cron-parsing callback would likely throw on
|
|
152
|
+
* that. Presets and interval mode always produce a structurally valid value.
|
|
153
|
+
*/
|
|
154
|
+
const currentValueIsValid = $derived(authoringMode !== 'cron' || cronFieldsValid(cronFields));
|
|
155
|
+
// `previewCount` is documented and schema-constrained as a positive
|
|
156
|
+
// integer, but it's still a public prop a consumer can hand a stray 0,
|
|
157
|
+
// negative, NaN, or fractional value to — normalize before it ever reaches
|
|
158
|
+
// `computeNextFires`, the same way `toPositiveInteger` guards field edits.
|
|
159
|
+
const resolvedPreviewCount = $derived(Number.isInteger(previewCount) && previewCount > 0 ? previewCount : 5);
|
|
160
|
+
/**
|
|
161
|
+
* Guards the next-fires preview two ways: (1) `computeNextFires` is only
|
|
162
|
+
* ever called with a value that has passed `cronFieldsValid` — never an
|
|
163
|
+
* in-progress, invalid cron edit (`status: 'invalid'`) — and (2) the call is
|
|
164
|
+
* wrapped in a try/catch so a consumer callback that throws for any other
|
|
165
|
+
* reason degrades to a generic unavailable state (`status: 'error'`)
|
|
166
|
+
* instead of crashing the component.
|
|
167
|
+
*/
|
|
168
|
+
const previewResult = $derived.by(() => {
|
|
169
|
+
if (!computeNextFires)
|
|
170
|
+
return { status: 'hidden' };
|
|
171
|
+
if (!currentValueIsValid)
|
|
172
|
+
return { status: 'invalid' };
|
|
173
|
+
try {
|
|
174
|
+
return { status: 'ok', fires: computeNextFires(currentValue, resolvedPreviewCount) };
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return { status: 'error' };
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
/**
|
|
181
|
+
* The last value this component knows the consumer has (starting from the
|
|
182
|
+
* initial `value`/default seed, then advancing to whatever the user last
|
|
183
|
+
* committed via `onchange`, then advancing again whenever the resync
|
|
184
|
+
* `$effect` below adopts a genuinely new controlled `value`). This is
|
|
185
|
+
* intentionally NOT `currentValue`: `currentValue` reflects whatever the
|
|
186
|
+
* active mode's fields would produce right now, even before the user has
|
|
187
|
+
* touched them (e.g. presets defaults to "every 15 minutes" until edited).
|
|
188
|
+
* Mode-switch seeding and the resync effect must compare against the value
|
|
189
|
+
* actually committed/known, not the untouched default of whichever mode
|
|
190
|
+
* happens to be active — otherwise switching straight from the initial
|
|
191
|
+
* `presets` default into cron mode would clobber a real initial cron
|
|
192
|
+
* `value` with "every 15 minutes" the moment you looked at it.
|
|
193
|
+
*
|
|
194
|
+
* Deliberately a plain (non-`$state`) variable: it is read only from
|
|
195
|
+
* plain functions and the effect below, never from `$derived` or the
|
|
196
|
+
* template, so it needs no reactivity of its own — and keeping it
|
|
197
|
+
* non-reactive means the resync effect's only real dependency is the
|
|
198
|
+
* `value` prop, not a self-write of its own tracked state.
|
|
199
|
+
*/
|
|
200
|
+
let lastKnownValue = seedValue;
|
|
201
|
+
/**
|
|
202
|
+
* The raw `value` prop as observed on the resync effect's most recent run.
|
|
203
|
+
* This is deliberately separate from `lastKnownValue`: it exists only to
|
|
204
|
+
* answer "did the *prop itself* actually change since I last looked?",
|
|
205
|
+
* independent of whatever this component's own local edits have done to
|
|
206
|
+
* `lastKnownValue`. See the effect below for why that distinction matters.
|
|
207
|
+
*/
|
|
208
|
+
let previousValueProp = value;
|
|
209
|
+
/**
|
|
210
|
+
* Two-way-controlled sync: when the CONSUMER hands in a `value` that is
|
|
211
|
+
* genuinely different from what this component last knew about, adopt it —
|
|
212
|
+
* re-seeding every field exactly like the initial seed (see
|
|
213
|
+
* `seedFieldsFromValue`). This is what makes `value` actually controlled:
|
|
214
|
+
* loading a saved schedule, a form reset, or a parent that normalizes or
|
|
215
|
+
* rejects an `onchange` all flow back in.
|
|
216
|
+
*
|
|
217
|
+
* The explicit `scheduleValuesEqual` comparison against `lastKnownValue` —
|
|
218
|
+
* not a bare `$effect(() => { ...reseed from value...})` — is load-bearing:
|
|
219
|
+
* without it, the routine controlled-component echo (parent stores
|
|
220
|
+
* whatever `onchange` just emitted and passes it straight back down,
|
|
221
|
+
* frequently as a freshly-constructed object with the same content) would
|
|
222
|
+
* look like a "new" value on every edit and wipe mid-edit state — e.g. an
|
|
223
|
+
* in-progress, not-yet-valid cron field — on every keystroke.
|
|
224
|
+
*
|
|
225
|
+
* `value === undefined` is treated as "reset to default", not "skip": a
|
|
226
|
+
* controlled parent that clears `value` back to `undefined` is a
|
|
227
|
+
* documented reset to the default/omitted state (e.g. a form reset) and
|
|
228
|
+
* must reseed to `defaultScheduleValue()`, exactly like a transition to
|
|
229
|
+
* any other genuinely new value.
|
|
230
|
+
*
|
|
231
|
+
* The `previousValueProp` reference check runs *before* any of that: this
|
|
232
|
+
* effect is only allowed to reseed on a genuine transition of the raw
|
|
233
|
+
* `value` prop, never merely because its resolved content (after the
|
|
234
|
+
* `?? defaultScheduleValue()` fallback) currently disagrees with
|
|
235
|
+
* `lastKnownValue`. That distinction is load-bearing for the uncontrolled
|
|
236
|
+
* case (no `value` prop, ever): `lastKnownValue` still advances on every
|
|
237
|
+
* local edit (via `emitChange`), so if this effect ever re-ran for a
|
|
238
|
+
* reason unrelated to `value` itself changing — e.g. a host test harness
|
|
239
|
+
* or framework integration that re-invokes effects on unrelated re-renders
|
|
240
|
+
* — a guard keyed only on `scheduleValuesEqual(default, lastKnownValue)`
|
|
241
|
+
* would misread "I have local edits the default doesn't have" as "the
|
|
242
|
+
* parent reset me to default" and wipe an in-progress, uncontrolled edit.
|
|
243
|
+
* Comparing the raw prop to what this effect saw last time is immune to
|
|
244
|
+
* that: for an uncontrolled consumer `value` is always `undefined`, so
|
|
245
|
+
* `previousValueProp` never disagrees with it, and the block below never
|
|
246
|
+
* runs at all — regardless of how many times the effect itself re-fires.
|
|
247
|
+
*/
|
|
248
|
+
$effect(() => {
|
|
249
|
+
const incoming = value;
|
|
250
|
+
const propChanged = incoming !== previousValueProp;
|
|
251
|
+
previousValueProp = incoming;
|
|
252
|
+
if (!propChanged)
|
|
253
|
+
return;
|
|
254
|
+
const resolved = incoming ?? defaultScheduleValue();
|
|
255
|
+
// A genuine reset (`value` transitioning to `undefined`) always reseeds back
|
|
256
|
+
// to the default, even when `lastKnownValue` already equals the default. A
|
|
257
|
+
// non-committing mode switch (browsing Cron/Interval without emitting) leaves
|
|
258
|
+
// `lastKnownValue` at the default while the visible mode/fields have moved on,
|
|
259
|
+
// so a content-equality short-circuit here would swallow the reset and strand
|
|
260
|
+
// the UI in the browsed mode. Content equality still guards the echo case for
|
|
261
|
+
// defined values (parent handing back exactly what we just emitted is a no-op).
|
|
262
|
+
if (incoming !== undefined && scheduleValuesEqual(resolved, lastKnownValue))
|
|
263
|
+
return;
|
|
264
|
+
const seed = seedFieldsFromValue(resolved);
|
|
265
|
+
authoringMode = seed.authoringMode;
|
|
266
|
+
cronFields = seed.cronFields;
|
|
267
|
+
intervalEvery = seed.intervalEvery;
|
|
268
|
+
intervalUnit = seed.intervalUnit;
|
|
269
|
+
presetKind = seed.presetKind;
|
|
270
|
+
presetEveryValue = seed.presetEveryValue;
|
|
271
|
+
presetEveryUnit = seed.presetEveryUnit;
|
|
272
|
+
presetDailyTime = seed.presetDailyTime;
|
|
273
|
+
presetWeeklyDays = seed.presetWeeklyDays;
|
|
274
|
+
presetWeeklyTime = seed.presetWeeklyTime;
|
|
275
|
+
presetMonthlyDay = seed.presetMonthlyDay;
|
|
276
|
+
presetMonthlyTime = seed.presetMonthlyTime;
|
|
277
|
+
lastKnownValue = resolved;
|
|
278
|
+
});
|
|
279
|
+
/**
|
|
280
|
+
* `lastKnownValue` is updated optimistically, *before* the consumer's
|
|
281
|
+
* `onchange` handler runs — this is what lets the resync effect above tell
|
|
282
|
+
* "the parent echoed back exactly what I just emitted" (no-op, keep
|
|
283
|
+
* mid-edit state) apart from "the parent handed me something genuinely
|
|
284
|
+
* different" (reseed). A validating/authorizing parent that rejects an
|
|
285
|
+
* edit is expected to express that by re-passing a `value` whose *content*
|
|
286
|
+
* differs from the emitted edit (e.g. its own prior value) — that flows
|
|
287
|
+
* through the same `scheduleValuesEqual` gate and correctly reverts the
|
|
288
|
+
* fields (see the "controlled parent that rejects an edit" test).
|
|
289
|
+
*
|
|
290
|
+
* The one case this does not cover: a parent that rejects by leaving
|
|
291
|
+
* `value` at the exact same object reference it already held. Svelte's
|
|
292
|
+
* prop reactivity never marks an unchanged reference dirty, so no effect
|
|
293
|
+
* re-runs at all — there is no signal for the child to observe. Detecting
|
|
294
|
+
* that would require polling `value` on every local edit instead of only
|
|
295
|
+
* when the prop itself changes, which reintroduces the race this whole
|
|
296
|
+
* mechanism was built to avoid: the child's own optimistic write to
|
|
297
|
+
* `lastKnownValue` happens synchronously in the same tick as the edit,
|
|
298
|
+
* strictly before the parent's (asynchronous, next-render) echo, so a
|
|
299
|
+
* same-tick comparison would misread "parent hasn't responded yet" as
|
|
300
|
+
* "parent rejected this" and revert the edit the user just made. Left
|
|
301
|
+
* unhandled by design — see PR discussion for the fuller tradeoff.
|
|
302
|
+
*/
|
|
303
|
+
function emitChange() {
|
|
304
|
+
lastKnownValue = currentValue;
|
|
305
|
+
onchange?.(currentValue);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Switching modes never emits a change by itself (browsing modes is
|
|
309
|
+
* exploratory, not a commitment) — it only re-seeds the destination mode's
|
|
310
|
+
* fields from `lastKnownValue`, losslessly where representable
|
|
311
|
+
* (`valueToCronFields` always succeeds; `valueToInterval` returns
|
|
312
|
+
* `undefined` for non-interval cron patterns, in which case the interval
|
|
313
|
+
* fields are left as they were).
|
|
314
|
+
*/
|
|
315
|
+
function handleAuthoringModeChange(nextMode) {
|
|
316
|
+
if (nextMode === authoringMode)
|
|
317
|
+
return;
|
|
318
|
+
authoringMode = nextMode;
|
|
319
|
+
if (nextMode === 'cron') {
|
|
320
|
+
cronFields = valueToCronFields(lastKnownValue);
|
|
321
|
+
}
|
|
322
|
+
else if (nextMode === 'interval') {
|
|
323
|
+
const interval = valueToInterval(lastKnownValue);
|
|
324
|
+
if (interval) {
|
|
325
|
+
intervalEvery = interval.every;
|
|
326
|
+
intervalUnit = interval.unit;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else if (nextMode === 'presets') {
|
|
330
|
+
// Same "lossless where representable" seeding as the initial mount and
|
|
331
|
+
// the resync effect: the only preset kind with a general inverse is
|
|
332
|
+
// "every N" at a minutes/hours cadence (`seedFieldsFromValue` already
|
|
333
|
+
// gates that through `valueToInterval` + the minutes/hours check).
|
|
334
|
+
// Daily/weekly/monthly and non-divisor/day/week intervals have no
|
|
335
|
+
// general inverse, so they fall back to the same neutral defaults used
|
|
336
|
+
// everywhere else a value gets seeded into the preset fields.
|
|
337
|
+
const seed = seedFieldsFromValue(lastKnownValue);
|
|
338
|
+
presetKind = seed.presetKind;
|
|
339
|
+
presetEveryValue = seed.presetEveryValue;
|
|
340
|
+
presetEveryUnit = seed.presetEveryUnit;
|
|
341
|
+
presetDailyTime = seed.presetDailyTime;
|
|
342
|
+
presetWeeklyDays = seed.presetWeeklyDays;
|
|
343
|
+
presetWeeklyTime = seed.presetWeeklyTime;
|
|
344
|
+
presetMonthlyDay = seed.presetMonthlyDay;
|
|
345
|
+
presetMonthlyTime = seed.presetMonthlyTime;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Unlike the top-level authoring-mode tabs, switching the preset KIND
|
|
350
|
+
* (Every N / Daily / Weekly / Monthly) changes what `currentValue` computes
|
|
351
|
+
* to immediately — each kind lowers its own already-filled-in fields to a
|
|
352
|
+
* value right away, there is no "browsing, not yet committed" state the way
|
|
353
|
+
* there is for an empty cron/interval panel. So this commits like any other
|
|
354
|
+
* field edit: it emits the newly derived value to a controlled parent.
|
|
355
|
+
*/
|
|
356
|
+
function handlePresetKindChange(nextKind) {
|
|
357
|
+
if (nextKind === presetKind)
|
|
358
|
+
return;
|
|
359
|
+
presetKind = nextKind;
|
|
360
|
+
emitChange();
|
|
361
|
+
}
|
|
362
|
+
function handleCronFieldChange(index, raw) {
|
|
363
|
+
const next = [...cronFields];
|
|
364
|
+
next[index] = raw;
|
|
365
|
+
cronFields = next;
|
|
366
|
+
if (cronFieldsValid(next))
|
|
367
|
+
emitChange();
|
|
368
|
+
}
|
|
369
|
+
// `ScheduleValue.every` is contractually a positive integer; NumberInput can
|
|
370
|
+
// yield decimals or nulls, so coerce every edit to `>= 1` whole units.
|
|
371
|
+
function toPositiveInteger(next) {
|
|
372
|
+
if (next === null || !Number.isFinite(next) || next < 1)
|
|
373
|
+
return 1;
|
|
374
|
+
return Math.trunc(next);
|
|
375
|
+
}
|
|
376
|
+
function handleIntervalEveryChange(next) {
|
|
377
|
+
intervalEvery = toPositiveInteger(next);
|
|
378
|
+
emitChange();
|
|
379
|
+
}
|
|
380
|
+
function handleIntervalUnitChange(event) {
|
|
381
|
+
intervalUnit = event.currentTarget.value;
|
|
382
|
+
emitChange();
|
|
383
|
+
}
|
|
384
|
+
function handlePresetEveryValueChange(next) {
|
|
385
|
+
presetEveryValue = toPositiveInteger(next);
|
|
386
|
+
emitChange();
|
|
387
|
+
}
|
|
388
|
+
function handlePresetEveryUnitChange(event) {
|
|
389
|
+
presetEveryUnit = event.currentTarget.value;
|
|
390
|
+
emitChange();
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* TimeField emits an empty string (via its native `change` event) when the
|
|
394
|
+
* user clears it, and `parseTime('')` silently defaults to midnight —
|
|
395
|
+
* accepting that here would let a user unintentionally submit a `00:00`
|
|
396
|
+
* cron just by clearing the field, with the field itself showing blank
|
|
397
|
+
* rather than "00:00". Reject the empty edit instead: don't touch the
|
|
398
|
+
* backing state at all, and don't emit. Because the preset time fields use
|
|
399
|
+
* a real two-way `bind:value` (not a one-way `value` prop), TimeField's own
|
|
400
|
+
* next read of `value` pulls the unchanged, last-committed time back
|
|
401
|
+
* through this setter's getter — so the field visually re-asserts the last
|
|
402
|
+
* valid time instead of drifting from the emitted cron.
|
|
403
|
+
*/
|
|
404
|
+
function acceptPresetTime(next, commit) {
|
|
405
|
+
if (!next)
|
|
406
|
+
return;
|
|
407
|
+
commit(next);
|
|
408
|
+
emitChange();
|
|
409
|
+
}
|
|
410
|
+
function handlePresetDailyTimeChange(next) {
|
|
411
|
+
acceptPresetTime(next, (time) => (presetDailyTime = time));
|
|
412
|
+
}
|
|
413
|
+
function toggleWeeklyDay(day) {
|
|
414
|
+
presetWeeklyDays = presetWeeklyDays.includes(day)
|
|
415
|
+
? presetWeeklyDays.filter((existing) => existing !== day)
|
|
416
|
+
: [...presetWeeklyDays, day];
|
|
417
|
+
emitChange();
|
|
418
|
+
}
|
|
419
|
+
function handlePresetWeeklyTimeChange(next) {
|
|
420
|
+
acceptPresetTime(next, (time) => (presetWeeklyTime = time));
|
|
421
|
+
}
|
|
422
|
+
function handlePresetMonthlyDayChange(next) {
|
|
423
|
+
presetMonthlyDay = next && next >= 1 ? Math.min(31, Math.trunc(next)) : 1;
|
|
424
|
+
emitChange();
|
|
425
|
+
}
|
|
426
|
+
function handlePresetMonthlyTimeChange(next) {
|
|
427
|
+
acceptPresetTime(next, (time) => (presetMonthlyTime = time));
|
|
428
|
+
}
|
|
429
|
+
const modeTabId = (mode) => `${baseId}-mode-${mode}-tab`;
|
|
430
|
+
const modePanelId = (mode) => `${baseId}-mode-${mode}-panel`;
|
|
431
|
+
</script>
|
|
432
|
+
|
|
433
|
+
<div
|
|
434
|
+
{...rest}
|
|
435
|
+
class={classNames('cinder-schedule-builder', className)}
|
|
436
|
+
role="group"
|
|
437
|
+
aria-label={resolvedAriaLabel}
|
|
438
|
+
aria-labelledby={normalizedAriaLabelledby}
|
|
439
|
+
data-sb-mode={authoringMode}
|
|
440
|
+
>
|
|
441
|
+
<SegmentedControl
|
|
442
|
+
id={`${baseId}-mode`}
|
|
443
|
+
label="Schedule authoring mode"
|
|
444
|
+
variant="tablist"
|
|
445
|
+
value={authoringMode}
|
|
446
|
+
onchange={handleAuthoringModeChange}
|
|
447
|
+
class="cinder-schedule-builder__mode-switch"
|
|
448
|
+
>
|
|
449
|
+
<Segment id={modeTabId('presets')} value="presets" controls={modePanelId('presets')}>
|
|
450
|
+
Presets
|
|
451
|
+
</Segment>
|
|
452
|
+
<Segment id={modeTabId('cron')} value="cron" controls={modePanelId('cron')}>Cron</Segment>
|
|
453
|
+
<Segment id={modeTabId('interval')} value="interval" controls={modePanelId('interval')}>
|
|
454
|
+
Interval
|
|
455
|
+
</Segment>
|
|
456
|
+
</SegmentedControl>
|
|
457
|
+
|
|
458
|
+
{#if authoringMode === 'presets'}
|
|
459
|
+
<div
|
|
460
|
+
id={modePanelId('presets')}
|
|
461
|
+
role="tabpanel"
|
|
462
|
+
aria-labelledby={modeTabId('presets')}
|
|
463
|
+
class="cinder-schedule-builder__panel"
|
|
464
|
+
data-sb-panel="presets"
|
|
465
|
+
>
|
|
466
|
+
<SegmentedControl
|
|
467
|
+
id={`${baseId}-preset-kind`}
|
|
468
|
+
label="Preset kind"
|
|
469
|
+
value={presetKind}
|
|
470
|
+
onchange={handlePresetKindChange}
|
|
471
|
+
class="cinder-schedule-builder__preset-kind"
|
|
472
|
+
>
|
|
473
|
+
<Segment id={`${baseId}-preset-kind-every`} value="every">Every N</Segment>
|
|
474
|
+
<Segment id={`${baseId}-preset-kind-daily`} value="daily">Daily</Segment>
|
|
475
|
+
<Segment id={`${baseId}-preset-kind-weekly`} value="weekly">Weekly</Segment>
|
|
476
|
+
<Segment id={`${baseId}-preset-kind-monthly`} value="monthly">Monthly</Segment>
|
|
477
|
+
</SegmentedControl>
|
|
478
|
+
|
|
479
|
+
{#if presetKind === 'every'}
|
|
480
|
+
<div class="cinder-schedule-builder__field-row">
|
|
481
|
+
<NumberInput
|
|
482
|
+
id={`${baseId}-preset-every-value`}
|
|
483
|
+
label="Every"
|
|
484
|
+
min={1}
|
|
485
|
+
step={1}
|
|
486
|
+
bind:value={() => presetEveryValue, handlePresetEveryValueChange}
|
|
487
|
+
/>
|
|
488
|
+
<Select
|
|
489
|
+
id={`${baseId}-preset-every-unit`}
|
|
490
|
+
label="Unit"
|
|
491
|
+
options={PRESET_EVERY_UNIT_OPTIONS}
|
|
492
|
+
value={presetEveryUnit}
|
|
493
|
+
onchange={handlePresetEveryUnitChange}
|
|
494
|
+
/>
|
|
495
|
+
</div>
|
|
496
|
+
{:else if presetKind === 'daily'}
|
|
497
|
+
<TimeField
|
|
498
|
+
id={`${baseId}-preset-daily-time`}
|
|
499
|
+
label="At"
|
|
500
|
+
bind:value={() => presetDailyTime, handlePresetDailyTimeChange}
|
|
501
|
+
/>
|
|
502
|
+
{:else if presetKind === 'weekly'}
|
|
503
|
+
<div class="cinder-schedule-builder__weekday-group" role="group" aria-label="Days of week">
|
|
504
|
+
{#each WEEKDAYS as day (day.value)}
|
|
505
|
+
<Chip
|
|
506
|
+
mode="toggle"
|
|
507
|
+
label={day.short}
|
|
508
|
+
aria-label={day.long}
|
|
509
|
+
pressed={presetWeeklyDays.includes(day.value)}
|
|
510
|
+
onpressedchange={() => toggleWeeklyDay(day.value)}
|
|
511
|
+
/>
|
|
512
|
+
{/each}
|
|
513
|
+
</div>
|
|
514
|
+
<TimeField
|
|
515
|
+
id={`${baseId}-preset-weekly-time`}
|
|
516
|
+
label="At"
|
|
517
|
+
bind:value={() => presetWeeklyTime, handlePresetWeeklyTimeChange}
|
|
518
|
+
/>
|
|
519
|
+
{:else}
|
|
520
|
+
<div class="cinder-schedule-builder__field-row">
|
|
521
|
+
<NumberInput
|
|
522
|
+
id={`${baseId}-preset-monthly-day`}
|
|
523
|
+
label="Day of month"
|
|
524
|
+
min={1}
|
|
525
|
+
max={31}
|
|
526
|
+
bind:value={() => presetMonthlyDay, handlePresetMonthlyDayChange}
|
|
527
|
+
/>
|
|
528
|
+
<TimeField
|
|
529
|
+
id={`${baseId}-preset-monthly-time`}
|
|
530
|
+
label="At"
|
|
531
|
+
bind:value={() => presetMonthlyTime, handlePresetMonthlyTimeChange}
|
|
532
|
+
/>
|
|
533
|
+
</div>
|
|
534
|
+
{/if}
|
|
535
|
+
</div>
|
|
536
|
+
{:else if authoringMode === 'cron'}
|
|
537
|
+
<div
|
|
538
|
+
id={modePanelId('cron')}
|
|
539
|
+
role="tabpanel"
|
|
540
|
+
aria-labelledby={modeTabId('cron')}
|
|
541
|
+
class="cinder-schedule-builder__panel"
|
|
542
|
+
data-sb-panel="cron"
|
|
543
|
+
>
|
|
544
|
+
<div class="cinder-schedule-builder__cron-fields">
|
|
545
|
+
{#each CRON_FIELDS as field, index (field.name)}
|
|
546
|
+
{@const fieldError = validateCronField(cronFields[index] ?? '*', index)}
|
|
547
|
+
<Input
|
|
548
|
+
id={`${baseId}-cron-field-${index}`}
|
|
549
|
+
label={field.name}
|
|
550
|
+
description={field.hint}
|
|
551
|
+
bind:value={
|
|
552
|
+
() => cronFields[index] ?? '*', (next) => handleCronFieldChange(index, next)
|
|
553
|
+
}
|
|
554
|
+
{...fieldError ? { error: fieldError } : {}}
|
|
555
|
+
/>
|
|
556
|
+
{/each}
|
|
557
|
+
</div>
|
|
558
|
+
</div>
|
|
559
|
+
{:else}
|
|
560
|
+
<div
|
|
561
|
+
id={modePanelId('interval')}
|
|
562
|
+
role="tabpanel"
|
|
563
|
+
aria-labelledby={modeTabId('interval')}
|
|
564
|
+
class="cinder-schedule-builder__panel"
|
|
565
|
+
data-sb-panel="interval"
|
|
566
|
+
>
|
|
567
|
+
<div class="cinder-schedule-builder__field-row">
|
|
568
|
+
<NumberInput
|
|
569
|
+
id={`${baseId}-interval-every`}
|
|
570
|
+
label="Every"
|
|
571
|
+
min={1}
|
|
572
|
+
step={1}
|
|
573
|
+
bind:value={() => intervalEvery, handleIntervalEveryChange}
|
|
574
|
+
/>
|
|
575
|
+
<Select
|
|
576
|
+
id={`${baseId}-interval-unit`}
|
|
577
|
+
label="Unit"
|
|
578
|
+
options={INTERVAL_UNIT_OPTIONS}
|
|
579
|
+
value={intervalUnit}
|
|
580
|
+
onchange={handleIntervalUnitChange}
|
|
581
|
+
/>
|
|
582
|
+
</div>
|
|
583
|
+
</div>
|
|
584
|
+
{/if}
|
|
585
|
+
|
|
586
|
+
<dl class="cinder-schedule-builder__summary">
|
|
587
|
+
<dt class="cinder-schedule-builder__section-label">Summary</dt>
|
|
588
|
+
<dd class="cinder-schedule-builder__summary-text">{describeValue(currentValue)}</dd>
|
|
589
|
+
</dl>
|
|
590
|
+
|
|
591
|
+
{#if previewResult.status !== 'hidden'}
|
|
592
|
+
<div class="cinder-schedule-builder__preview">
|
|
593
|
+
<span class="cinder-schedule-builder__section-label" id={`${baseId}-preview-label`}>
|
|
594
|
+
Upcoming fires
|
|
595
|
+
</span>
|
|
596
|
+
{#if previewResult.status === 'invalid'}
|
|
597
|
+
<p class="cinder-schedule-builder__empty">
|
|
598
|
+
Preview unavailable — fix the cron expression above.
|
|
599
|
+
</p>
|
|
600
|
+
{:else if previewResult.status === 'error'}
|
|
601
|
+
<p class="cinder-schedule-builder__empty">Preview unavailable.</p>
|
|
602
|
+
{:else if previewResult.fires.length > 0}
|
|
603
|
+
<ul
|
|
604
|
+
class="cinder-schedule-builder__preview-list"
|
|
605
|
+
aria-labelledby={`${baseId}-preview-label`}
|
|
606
|
+
>
|
|
607
|
+
{#each previewResult.fires as fire (fire.id)}
|
|
608
|
+
<li class="cinder-schedule-builder__preview-item">{fire.label}</li>
|
|
609
|
+
{/each}
|
|
610
|
+
</ul>
|
|
611
|
+
{:else}
|
|
612
|
+
<p class="cinder-schedule-builder__empty">No upcoming fires.</p>
|
|
613
|
+
{/if}
|
|
614
|
+
</div>
|
|
615
|
+
{/if}
|
|
616
|
+
|
|
617
|
+
<dl class="cinder-schedule-builder__timezone">
|
|
618
|
+
<dt class="cinder-schedule-builder__section-label">Timezone</dt>
|
|
619
|
+
<dd class="cinder-schedule-builder__timezone-value">
|
|
620
|
+
{#if timezone}
|
|
621
|
+
{@render timezone()}
|
|
622
|
+
{:else if timezoneLabel}
|
|
623
|
+
{timezoneLabel}
|
|
624
|
+
{:else}
|
|
625
|
+
<span class="cinder-schedule-builder__empty">Not set</span>
|
|
626
|
+
{/if}
|
|
627
|
+
</dd>
|
|
628
|
+
</dl>
|
|
629
|
+
</div>
|