@runwisp/ui 1.5.1 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -7
- package/src/lib/actions/fold-to-fit.test.ts +36 -0
- package/src/lib/actions/fold-to-fit.ts +89 -0
- package/src/lib/actions/modal-dialog.test.ts +47 -0
- package/src/lib/actions/modal-dialog.ts +48 -0
- package/src/lib/components/AccordionItem.svelte +16 -5
- package/src/lib/components/Badge.svelte +3 -24
- package/src/lib/components/Button.svelte +2 -9
- package/src/lib/components/CodeBlock.svelte +7 -6
- package/src/lib/components/Drawer.svelte +22 -30
- package/src/lib/components/DurationInput.svelte +6 -25
- package/src/lib/components/FilterBar.svelte +2 -6
- package/src/lib/components/Link.svelte +9 -4
- package/src/lib/components/LogConsole.svelte +95 -418
- package/src/lib/components/Modal.svelte +7 -30
- package/src/lib/components/Spinner.svelte +10 -5
- package/src/lib/components/StatusIndicator.svelte +37 -104
- package/src/lib/components/Tabs.svelte +15 -1
- package/src/lib/components/dashboard/RunActions.svelte +156 -0
- package/src/lib/components/dashboard/RunConsoleFrame.svelte +319 -0
- package/src/lib/components/dashboard/RunDetailPanel.svelte +130 -717
- package/src/lib/components/dashboard/RunFacts.svelte +119 -0
- package/src/lib/components/dashboard/RunFilterChips.svelte +52 -0
- package/src/lib/components/dashboard/RunFilterPopover.svelte +4 -5
- package/src/lib/components/dashboard/RunHeaderLine.svelte +295 -0
- package/src/lib/components/dashboard/RunListSkeleton.svelte +43 -0
- package/src/lib/components/dashboard/RunRow.svelte +202 -0
- package/src/lib/components/dashboard/RunsList.svelte +265 -543
- package/src/lib/components/dashboard/bulk-selection.svelte.test.ts +42 -0
- package/src/lib/components/dashboard/bulk-selection.svelte.ts +50 -0
- package/src/lib/components/dashboard/cron-format.test.ts +9 -0
- package/src/lib/components/dashboard/cron-format.ts +5 -1
- package/src/lib/components/dashboard/run-filters.test.ts +60 -0
- package/src/lib/components/dashboard/run-filters.ts +78 -6
- package/src/lib/components/dashboard/run-helpers.test.ts +122 -12
- package/src/lib/components/dashboard/run-helpers.ts +122 -6
- package/src/lib/components/dashboard/status-config.ts +18 -0
- package/src/lib/components/dashboard/types.ts +6 -0
- package/src/lib/index.ts +13 -2
- package/src/lib/log-console/AnsiLine.svelte +12 -0
- package/src/lib/log-console/FrameHistoryBlock.svelte +57 -0
- package/src/lib/log-console/LogCache.svelte.test.ts +135 -0
- package/src/lib/log-console/LogConsoleFooter.svelte +88 -0
- package/src/lib/log-console/LogFetcher.svelte.test.ts +159 -0
- package/src/lib/log-console/frame-history.svelte.test.ts +47 -0
- package/src/lib/log-console/frame-history.svelte.ts +71 -0
- package/src/lib/log-console/wrap-layout.svelte.test.ts +92 -0
- package/src/lib/log-console/wrap-layout.svelte.ts +188 -0
- package/src/lib/utils/format.test.ts +122 -0
- package/src/lib/utils/format.ts +97 -4
- package/src/lib/utils/toast.svelte.test.ts +46 -0
- package/src/lib/utils/typing-target.ts +10 -0
- package/src/stories/Accordion.stories.svelte +60 -1
- package/src/stories/CodeBlock.stories.svelte +13 -0
- package/src/stories/Link.stories.svelte +25 -1
- package/src/stories/Tabs.stories.svelte +17 -0
|
@@ -3,11 +3,32 @@
|
|
|
3
3
|
|
|
4
4
|
<script module>
|
|
5
5
|
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
6
|
-
import { LifeBuoy, Trash } from "@lucide/svelte";
|
|
6
|
+
import { LifeBuoy, Pencil, Trash } from "@lucide/svelte";
|
|
7
7
|
import Accordion from "$lib/components/Accordion.svelte";
|
|
8
8
|
import AccordionItem from "$lib/components/AccordionItem.svelte";
|
|
9
9
|
import Toggle from "$lib/components/Toggle.svelte";
|
|
10
10
|
|
|
11
|
+
const blocks = [
|
|
12
|
+
{
|
|
13
|
+
label: "Node.js 22",
|
|
14
|
+
enabled: true,
|
|
15
|
+
frameClass: "border-outline bg-surface-raised",
|
|
16
|
+
run: "RUN apk add --no-cache nodejs npm",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
label: "Python 3.12",
|
|
20
|
+
enabled: false,
|
|
21
|
+
frameClass: "border-outline-faint bg-surface",
|
|
22
|
+
run: "RUN apk add --no-cache python3",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: "Go 1.27 (stale)",
|
|
26
|
+
enabled: true,
|
|
27
|
+
frameClass: "border-warning-soft-border bg-warning-soft/30",
|
|
28
|
+
run: "RUN apk add --no-cache go",
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
11
32
|
const { Story } = defineMeta({
|
|
12
33
|
title: "Navigation/Accordion",
|
|
13
34
|
component: Accordion,
|
|
@@ -59,3 +80,41 @@
|
|
|
59
80
|
<pre class="font-mono text-xs">RUN apk add --no-cache nodejs npm</pre>
|
|
60
81
|
</AccordionItem>
|
|
61
82
|
</Story>
|
|
83
|
+
|
|
84
|
+
<!-- `leading` sits before the title and never toggles the panel; `frameClass`
|
|
85
|
+
tints the frame by state. -->
|
|
86
|
+
<Story name="Framed with leading control and tint" asChild>
|
|
87
|
+
<div class="flex max-w-lg flex-col gap-2">
|
|
88
|
+
{#each blocks as block (block.label)}
|
|
89
|
+
<AccordionItem
|
|
90
|
+
variant="framed"
|
|
91
|
+
frameClass={block.frameClass}
|
|
92
|
+
class={block.enabled ? "" : "opacity-60"}
|
|
93
|
+
>
|
|
94
|
+
{#snippet leading()}
|
|
95
|
+
<Toggle checked={block.enabled} size="sm" />
|
|
96
|
+
{/snippet}
|
|
97
|
+
{#snippet title()}
|
|
98
|
+
<span class="block truncate">{block.label}</span>
|
|
99
|
+
{/snippet}
|
|
100
|
+
{#snippet actions()}
|
|
101
|
+
<button
|
|
102
|
+
type="button"
|
|
103
|
+
aria-label="Edit"
|
|
104
|
+
class="rounded-[3px] p-1 text-on-surface-faint hover:bg-surface-sunken hover:text-on-surface"
|
|
105
|
+
>
|
|
106
|
+
<Pencil size={14} />
|
|
107
|
+
</button>
|
|
108
|
+
<button
|
|
109
|
+
type="button"
|
|
110
|
+
aria-label="Remove"
|
|
111
|
+
class="rounded-[3px] p-1 text-on-surface-faint hover:bg-danger-soft hover:text-danger-surface"
|
|
112
|
+
>
|
|
113
|
+
<Trash size={14} />
|
|
114
|
+
</button>
|
|
115
|
+
{/snippet}
|
|
116
|
+
<pre class="font-mono text-xs">{block.run}</pre>
|
|
117
|
+
</AccordionItem>
|
|
118
|
+
{/each}
|
|
119
|
+
</div>
|
|
120
|
+
</Story>
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
const helloTask = '[tasks.hello]\ncron = "*/5 * * * *"\nrun = "echo hello"';
|
|
9
9
|
const backupTask = '[tasks.backup]\ncron = "0 3 * * *"\nkeep_runs = 60';
|
|
10
|
+
const longLine =
|
|
11
|
+
"export RUNWISP_STATION_TOKEN=rw_live_8f2c1d9e4b7a6053c1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4";
|
|
10
12
|
|
|
11
13
|
const { Story } = defineMeta({
|
|
12
14
|
title: "Data Display/CodeBlock",
|
|
@@ -40,6 +42,17 @@
|
|
|
40
42
|
<CodeBlock variant="surface" size="sm" copyable={false} code={helloTask} />
|
|
41
43
|
</Story>
|
|
42
44
|
|
|
45
|
+
<!-- A line wider than the block scrolls without running under the copy button. -->
|
|
46
|
+
<Story name="Long line" asChild>
|
|
47
|
+
<div class="flex max-w-md flex-col gap-3">
|
|
48
|
+
<CodeBlock code={longLine} />
|
|
49
|
+
<CodeBlock code={longLine} size="sm" prompt="$" />
|
|
50
|
+
<CodeBlock code={longLine} variant="surface" />
|
|
51
|
+
<CodeBlock code={longLine} variant="surface" size="sm" />
|
|
52
|
+
<CodeBlock code="runwisp station" size="sm" />
|
|
53
|
+
</div>
|
|
54
|
+
</Story>
|
|
55
|
+
|
|
43
56
|
<!-- Rich children render the markup; `code` keeps the copied text plain. -->
|
|
44
57
|
<Story name="Highlighted children" asChild>
|
|
45
58
|
<!-- No whitespace between the line spans: inside <pre> it would render as blank lines. -->
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
component: Link,
|
|
11
11
|
tags: ["autodocs"],
|
|
12
12
|
argTypes: {
|
|
13
|
-
variant: {
|
|
13
|
+
variant: {
|
|
14
|
+
control: "select",
|
|
15
|
+
options: ["default", "muted", "primary", "danger", "unstyled"],
|
|
16
|
+
},
|
|
14
17
|
underline: { control: "select", options: ["always", "hover", "none"] },
|
|
15
18
|
},
|
|
16
19
|
});
|
|
@@ -36,3 +39,24 @@
|
|
|
36
39
|
Task configuration docs →
|
|
37
40
|
</Link>
|
|
38
41
|
</Story>
|
|
42
|
+
|
|
43
|
+
<!-- `unstyled` adds nothing beyond `class`: the row brings its own layout and colours. -->
|
|
44
|
+
<Story name="Unstyled nav row" asChild>
|
|
45
|
+
<nav class="w-64 space-y-0.5">
|
|
46
|
+
<Link
|
|
47
|
+
href="#tasks"
|
|
48
|
+
variant="unstyled"
|
|
49
|
+
aria-current="page"
|
|
50
|
+
class="flex items-center gap-3 rounded-sm bg-primary-soft px-3 py-2 font-mono text-sm text-primary-soft-text"
|
|
51
|
+
>
|
|
52
|
+
Tasks
|
|
53
|
+
</Link>
|
|
54
|
+
<Link
|
|
55
|
+
href="#runners"
|
|
56
|
+
variant="unstyled"
|
|
57
|
+
class="flex items-center gap-3 rounded-sm px-3 py-2 font-mono text-sm text-on-surface-muted hover:bg-surface-sunken hover:text-primary"
|
|
58
|
+
>
|
|
59
|
+
Runners
|
|
60
|
+
</Link>
|
|
61
|
+
</nav>
|
|
62
|
+
</Story>
|
|
@@ -32,6 +32,14 @@
|
|
|
32
32
|
{ id: "settings", label: "Settings", icon: Settings },
|
|
33
33
|
];
|
|
34
34
|
|
|
35
|
+
const deployTabs = [
|
|
36
|
+
{ id: "binary", label: "Linux binary" },
|
|
37
|
+
{ id: "docker", label: "Docker run" },
|
|
38
|
+
{ id: "compose", label: "Docker Compose" },
|
|
39
|
+
{ id: "kubernetes", label: "Kubernetes manifest" },
|
|
40
|
+
{ id: "systemd", label: "systemd unit" },
|
|
41
|
+
];
|
|
42
|
+
|
|
35
43
|
const disabledTabs = [
|
|
36
44
|
{ id: "active", label: "Active" },
|
|
37
45
|
{ id: "completed", label: "Completed" },
|
|
@@ -105,3 +113,12 @@
|
|
|
105
113
|
{/snippet}
|
|
106
114
|
</Tabs>
|
|
107
115
|
</Story>
|
|
116
|
+
|
|
117
|
+
<!-- `scrollable` keeps every label on one line and scrolls the bar sideways. -->
|
|
118
|
+
<Story name="Scrollable" asChild>
|
|
119
|
+
<div class="flex max-w-xs flex-col gap-4">
|
|
120
|
+
<Tabs tabs={deployTabs} variant="enclosed" scrollable />
|
|
121
|
+
<Tabs tabs={deployTabs} variant="pills" scrollable />
|
|
122
|
+
<Tabs tabs={deployTabs} variant="underline" scrollable />
|
|
123
|
+
</div>
|
|
124
|
+
</Story>
|