@spunto/design-system 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -8
- package/package.json +1 -1
- package/src/components/projects/repo-list.tsx +22 -5
- package/src/components/projects/types.ts +7 -0
- package/src/components/workers/git-branch-chips.tsx +0 -21
- package/src/components/workers/index.ts +2 -2
- package/src/components/workers/types.ts +0 -6
- package/src/components/workers/worker-card.tsx +13 -11
package/README.md
CHANGED
|
@@ -120,14 +120,16 @@ panel are the same concept seen twice, so they share `/projects`.
|
|
|
120
120
|
differently: `WorkerStatusDot`/`WorkerStatusPill` (+`resolveWorkerStatus`,
|
|
121
121
|
`workerStatusConfig`), `SetupProgress` (+`setupProgress`, `phaseLabel`,
|
|
122
122
|
`setupTotalMs`), `StepIndicator`, `ResourceBars`, `GitBranchChips`/
|
|
123
|
-
`GitStatusSummary
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
`GitStatusSummary`, `TagChips` (+`tagColor`), `CreatorAvatar`.
|
|
124
|
+
- **One list of repositories, drawn as given.** `gitStatus` answers "what is
|
|
125
|
+
this worker working on", and the *tense* of that answer belongs to the caller:
|
|
126
|
+
the live checkout once it's known, the branches the worker was asked to check
|
|
127
|
+
out while it isn't (setup in flight, stopped worker). The card doesn't hold a
|
|
128
|
+
second, worker-level branch and doesn't decide when the list is meaningful —
|
|
129
|
+
only the caller knows whether its own data is still fresh. Keep the same
|
|
130
|
+
`path` for both tenses (Spunto clones into `/workspace/<workspacePath>`, which
|
|
131
|
+
is what `git-status` reports) and the transition is a value change on the same
|
|
132
|
+
chip.
|
|
131
133
|
- **Types are structural**, never the apps' OpenAPI types: the dashboard and
|
|
132
134
|
Spunto Lite model a worker differently, so `WorkerCardWorker` asks for the
|
|
133
135
|
minimum, everything optional but `id`, and an unknown state falls back to
|
package/package.json
CHANGED
|
@@ -130,10 +130,15 @@ export function RepoList({
|
|
|
130
130
|
return (
|
|
131
131
|
<div className={cn("@container/repos space-y-2", className)}>
|
|
132
132
|
{repos.length > 0 && (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
// The header mirrors the ROW's flex rules rather than being a grid of
|
|
134
|
+
// its own — the rows stopped being a grid when they had to wrap on a
|
|
135
|
+
// phone, and a grid header over flex rows puts every label next to the
|
|
136
|
+
// wrong field. `size-8` spacer = the width of the row's icon button.
|
|
137
|
+
<div className="mb-1 hidden gap-2 px-1 text-xs text-muted-foreground @min-[34rem]/repos:flex">
|
|
138
|
+
<span className="min-w-0 flex-1">Repository</span>
|
|
139
|
+
<span className="min-w-0 flex-1">Workspace path</span>
|
|
140
|
+
<span className="min-w-0 flex-1 @min-[30rem]/repos:max-w-[9rem]">Branch</span>
|
|
141
|
+
<span className="size-8 shrink-0" />
|
|
137
142
|
</div>
|
|
138
143
|
)}
|
|
139
144
|
|
|
@@ -194,6 +199,17 @@ export function RepoList({
|
|
|
194
199
|
onChange={(e) => patch(repo.id, { workspacePath: e.target.value, workspacePathTouched: true })}
|
|
195
200
|
/>
|
|
196
201
|
|
|
202
|
+
<Input
|
|
203
|
+
placeholder="default"
|
|
204
|
+
aria-label="Branch"
|
|
205
|
+
title="Branch checked out when a worker clones this repo — empty for the remote's default branch"
|
|
206
|
+
// Narrower than the other two and last to get space: a branch name
|
|
207
|
+
// is short, and "default" is the answer most rows keep.
|
|
208
|
+
className="min-w-0 flex-1 font-mono text-xs @min-[30rem]/repos:max-w-[9rem]"
|
|
209
|
+
value={repo.branch ?? ""}
|
|
210
|
+
onChange={(e) => patch(repo.id, { branch: e.target.value })}
|
|
211
|
+
/>
|
|
212
|
+
|
|
197
213
|
<Button
|
|
198
214
|
type="button"
|
|
199
215
|
variant="ghost"
|
|
@@ -235,7 +251,8 @@ export function RepoList({
|
|
|
235
251
|
</div>
|
|
236
252
|
|
|
237
253
|
<p className="text-xs text-muted-foreground">
|
|
238
|
-
Cloned into <code>/workspace/<path></code> at worker startup
|
|
254
|
+
Cloned into <code>/workspace/<path></code> at worker startup, on the branch set here (empty = the
|
|
255
|
+
remote's default).{" "}
|
|
239
256
|
{connectUrl &&
|
|
240
257
|
(github?.connected ? (
|
|
241
258
|
<a href={connectUrl} className="underline underline-offset-2">
|
|
@@ -27,6 +27,13 @@ export interface ProjectRepo {
|
|
|
27
27
|
installationId?: number
|
|
28
28
|
/** Raw clone URL, `git` provider only. */
|
|
29
29
|
cloneUrl?: string
|
|
30
|
+
/**
|
|
31
|
+
* Branch checked out when a worker clones this repo. Empty/absent = the
|
|
32
|
+
* remote's default — which is why it's a plain optional string and not a
|
|
33
|
+
* required field with a magic "main" default: we don't know the remote's
|
|
34
|
+
* default, and guessing it wrong is worse than deferring to it.
|
|
35
|
+
*/
|
|
36
|
+
branch?: string
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
/** A devcontainer feature, as the form carries it. */
|
|
@@ -77,27 +77,6 @@ export function GitBranchChips({ repos, repoHref, className }: GitBranchChipsPro
|
|
|
77
77
|
)
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
export interface RequestedBranchChipProps {
|
|
81
|
-
branch: string
|
|
82
|
-
className?: string
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* The branch a worker was *asked* to check out, as a lone chip — no repo name,
|
|
87
|
-
* because at that point nothing is cloned yet and there is none to show. Same
|
|
88
|
-
* shell as the chips above on purpose: it's the placeholder they replace once
|
|
89
|
-
* the live status arrives, and a different-looking chip would read as a
|
|
90
|
-
* different kind of information.
|
|
91
|
-
*/
|
|
92
|
-
export function RequestedBranchChip({ branch, className }: RequestedBranchChipProps) {
|
|
93
|
-
return (
|
|
94
|
-
<span data-slot="requested-branch-chip" className={cn(CHIP, className)} title={`Requested branch: ${branch}`}>
|
|
95
|
-
<GitBranchIcon className="h-2.5 w-2.5 shrink-0" />
|
|
96
|
-
<span className="min-w-0 truncate">{branch}</span>
|
|
97
|
-
</span>
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
80
|
/** Amber for local work not yet committed/pushed, muted for what's merely behind. */
|
|
102
81
|
function RepoCounters({ repo }: { repo: GitRepoStatus }) {
|
|
103
82
|
return (
|
|
@@ -18,8 +18,8 @@ export type { SetupProgressProps, StepState } from "./setup-progress"
|
|
|
18
18
|
export { ResourceBars } from "./resource-bars"
|
|
19
19
|
export type { ResourceBarsProps, WorkerStats } from "./resource-bars"
|
|
20
20
|
|
|
21
|
-
export { GitBranchChips, GitStatusSummary,
|
|
22
|
-
export type { GitBranchChipsProps, GitRepoStatus, GitStatusSummaryProps
|
|
21
|
+
export { GitBranchChips, GitStatusSummary, repoName } from "./git-branch-chips"
|
|
22
|
+
export type { GitBranchChipsProps, GitRepoStatus, GitStatusSummaryProps } from "./git-branch-chips"
|
|
23
23
|
|
|
24
24
|
export { TagChips } from "./tag-chips"
|
|
25
25
|
export type { TagChipsProps } from "./tag-chips"
|
|
@@ -31,12 +31,6 @@ export interface WorkerCardWorker {
|
|
|
31
31
|
/** Docker-level state: `running` | `stopped` | `exited` | `created` | `not_found` | `error`. */
|
|
32
32
|
dockerState?: string | null
|
|
33
33
|
createdAt?: string | null
|
|
34
|
-
/**
|
|
35
|
-
* Branch asked for at creation — what the worker is *going to* check out. The
|
|
36
|
-
* live per-repo status (`gitStatus`) says what it *did* check out, and takes
|
|
37
|
-
* over as soon as it exists.
|
|
38
|
-
*/
|
|
39
|
-
branch?: string | null
|
|
40
34
|
projectVersion?: number | null
|
|
41
35
|
tags?: string[] | null
|
|
42
36
|
setupStatus?: WorkerSetupStatus | null
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import { cn, formatDuration, formatRelativeTime } from "../../utils"
|
|
15
15
|
import { buttonVariants } from "../button-variants"
|
|
16
16
|
import { CreatorAvatar } from "./creator-avatar"
|
|
17
|
-
import { GitBranchChips,
|
|
17
|
+
import { GitBranchChips, type GitRepoStatus } from "./git-branch-chips"
|
|
18
18
|
import { ResourceBars, type WorkerStats } from "./resource-bars"
|
|
19
19
|
import { SetupProgress, setupTotalMs } from "./setup-progress"
|
|
20
20
|
import { TagChips } from "./tag-chips"
|
|
@@ -42,7 +42,14 @@ export interface WorkerCardProps {
|
|
|
42
42
|
nodeOnline?: boolean
|
|
43
43
|
/** Live container stats. Absent → no resource bars (the usual case for a stopped worker). */
|
|
44
44
|
stats?: WorkerStats | null
|
|
45
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* What this worker is working on, as one list of repositories — drawn as
|
|
47
|
+
* given. Which tense that list is in belongs to the caller: the live checkout
|
|
48
|
+
* once it's known, the branches the worker was *asked* to check out while it
|
|
49
|
+
* isn't (setup in flight, worker stopped). The card doesn't second-guess it,
|
|
50
|
+
* because only the caller knows whether its own data is still meaningful.
|
|
51
|
+
* Absent/empty → no chips.
|
|
52
|
+
*/
|
|
46
53
|
gitStatus?: GitRepoStatus[] | null
|
|
47
54
|
/** Chip → URL (e.g. code-server at that folder). Returning undefined renders a static chip. */
|
|
48
55
|
repoHref?: (repo: GitRepoStatus) => string | undefined
|
|
@@ -121,9 +128,10 @@ export function WorkerCard({
|
|
|
121
128
|
|
|
122
129
|
// Live detail is only meaningful once the container is up *and* done setting
|
|
123
130
|
// up: mid-setup a stale "running" from docker would show stats for a worker
|
|
124
|
-
// that isn't usable yet.
|
|
131
|
+
// that isn't usable yet. That guard is for `stats`, which the card reads as
|
|
132
|
+
// live-or-nothing; `gitStatus` is drawn as given (see the prop).
|
|
125
133
|
const settled = status.running && !status.settingUp
|
|
126
|
-
const repos =
|
|
134
|
+
const repos = gitStatus ?? []
|
|
127
135
|
const outdated =
|
|
128
136
|
!status.settingUp &&
|
|
129
137
|
worker.projectVersion != null &&
|
|
@@ -209,16 +217,10 @@ export function WorkerCard({
|
|
|
209
217
|
</div>
|
|
210
218
|
)}
|
|
211
219
|
|
|
212
|
-
{repos.length > 0
|
|
220
|
+
{repos.length > 0 && (
|
|
213
221
|
<div className="px-4 pb-3">
|
|
214
222
|
<GitBranchChips repos={repos} repoHref={repoHref} />
|
|
215
223
|
</div>
|
|
216
|
-
) : (
|
|
217
|
-
worker.branch && (
|
|
218
|
-
<div className="px-4 pb-3">
|
|
219
|
-
<RequestedBranchChip branch={worker.branch} />
|
|
220
|
-
</div>
|
|
221
|
-
)
|
|
222
224
|
)}
|
|
223
225
|
|
|
224
226
|
{settled && stats && (
|