@godxjp/ui 0.1.1 → 2.1.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/BRAND.md +286 -0
- package/CHANGELOG.md +94 -0
- package/README.md +189 -33
- package/dist/components/primitives.d.ts +266 -0
- package/dist/components/primitives.js +252 -0
- package/dist/components/primitives.js.map +1 -0
- package/dist/components/screens.d.ts +51 -0
- package/dist/components/screens.js +806 -0
- package/dist/components/screens.js.map +1 -0
- package/dist/components/shell.d.ts +112 -0
- package/dist/components/shell.js +768 -0
- package/dist/components/shell.js.map +1 -0
- package/dist/data.d.ts +35 -0
- package/dist/data.js +93 -0
- package/dist/data.js.map +1 -0
- package/dist/hooks.d.ts +25 -0
- package/dist/hooks.js +144 -0
- package/dist/hooks.js.map +1 -0
- package/dist/i18n.d.ts +9 -0
- package/dist/i18n.js +409 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +14 -2650
- package/dist/index.js +726 -5295
- package/dist/index.js.map +1 -1
- package/package.json +76 -94
- package/src/tokens/tokens.css +765 -0
- package/src/styles/theme.css +0 -678
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
import { Activity, BugPlay, Rocket, TrendingUp, GitBranch, ArrowLeft, ChevronRight, Send } from 'lucide-react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { useState } from 'react';
|
|
7
|
+
import * as Popover from '@radix-ui/react-popover';
|
|
8
|
+
|
|
9
|
+
var ACTIVITY = [
|
|
10
|
+
{ id: "a1", type: "deploy", who: "satoshi", what: "production deploy v0.42.0", when: "12m" },
|
|
11
|
+
{ id: "a2", type: "issue", who: "naoki", what: "moved GK-310 to In Review", when: "32m" },
|
|
12
|
+
{ id: "a3", type: "plan", who: "anh", what: "PDCA-Q2-001 entered Check", when: "1h" }
|
|
13
|
+
];
|
|
14
|
+
function DashboardScreen({ product }) {
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
const totalIssues = product.projects.reduce((s, p) => s + p.openIssues, 0);
|
|
17
|
+
const totalPrs = product.projects.reduce((s, p) => s + p.prs, 0);
|
|
18
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19
|
+
/* @__PURE__ */ jsx("div", { className: "page-header", children: /* @__PURE__ */ jsxs("div", { children: [
|
|
20
|
+
/* @__PURE__ */ jsxs("h1", { className: "page-title", children: [
|
|
21
|
+
product.name,
|
|
22
|
+
" \xB7 ",
|
|
23
|
+
t("nav.dashboard")
|
|
24
|
+
] }),
|
|
25
|
+
/* @__PURE__ */ jsx("p", { className: "page-subtitle", children: product.desc })
|
|
26
|
+
] }) }),
|
|
27
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-4 gap-3 mb-6", children: [
|
|
28
|
+
/* @__PURE__ */ jsx(Kpi, { label: t("kpi.activeDevs"), value: String(product.devs), icon: Activity, delta: "+1" }),
|
|
29
|
+
/* @__PURE__ */ jsx(Kpi, { label: t("kpi.openIssues"), value: String(totalIssues), icon: BugPlay, delta: `${totalPrs} PR` }),
|
|
30
|
+
/* @__PURE__ */ jsx(Kpi, { label: t("kpi.deployments"), value: "14", icon: Rocket, delta: "+3" }),
|
|
31
|
+
/* @__PURE__ */ jsx(Kpi, { label: t("kpi.uptime"), value: "99.94%", icon: TrendingUp, delta: "30d" })
|
|
32
|
+
] }),
|
|
33
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-3", children: [
|
|
34
|
+
/* @__PURE__ */ jsxs("section", { className: "card col-span-2", children: [
|
|
35
|
+
/* @__PURE__ */ jsx("header", { className: "card-header", children: /* @__PURE__ */ jsx("h2", { className: "card-title", children: t("kpi.recentActivity") }) }),
|
|
36
|
+
/* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-1", children: ACTIVITY.map((a) => /* @__PURE__ */ jsxs("li", { className: "log-line", children: [
|
|
37
|
+
/* @__PURE__ */ jsx("span", { className: "time", children: a.when }),
|
|
38
|
+
/* @__PURE__ */ jsx("span", { className: `src ${a.type === "deploy" ? "ok" : a.type === "plan" ? "" : "warn"}`, children: a.who }),
|
|
39
|
+
/* @__PURE__ */ jsx("span", { children: a.what })
|
|
40
|
+
] }, a.id)) })
|
|
41
|
+
] }),
|
|
42
|
+
/* @__PURE__ */ jsxs("section", { className: "card", children: [
|
|
43
|
+
/* @__PURE__ */ jsx("header", { className: "card-header", children: /* @__PURE__ */ jsx("h2", { className: "card-title", children: t("kpi.quickActions") }) }),
|
|
44
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
45
|
+
/* @__PURE__ */ jsx("button", { className: "btn btn-secondary justify-start", children: t("nav.plans") }),
|
|
46
|
+
/* @__PURE__ */ jsx("button", { className: "btn btn-secondary justify-start", children: t("nav.issues") }),
|
|
47
|
+
/* @__PURE__ */ jsx("button", { className: "btn btn-secondary justify-start", children: t("nav.ideas") }),
|
|
48
|
+
/* @__PURE__ */ jsx("button", { className: "btn btn-secondary justify-start", children: t("nav.gantt") })
|
|
49
|
+
] })
|
|
50
|
+
] })
|
|
51
|
+
] })
|
|
52
|
+
] });
|
|
53
|
+
}
|
|
54
|
+
function Kpi({
|
|
55
|
+
label,
|
|
56
|
+
value,
|
|
57
|
+
icon: Icon,
|
|
58
|
+
delta
|
|
59
|
+
}) {
|
|
60
|
+
return /* @__PURE__ */ jsxs("div", { className: "kpi", children: [
|
|
61
|
+
/* @__PURE__ */ jsxs("span", { className: "kpi-label", children: [
|
|
62
|
+
/* @__PURE__ */ jsx(Icon, { size: 14 }),
|
|
63
|
+
" ",
|
|
64
|
+
label
|
|
65
|
+
] }),
|
|
66
|
+
/* @__PURE__ */ jsx("span", { className: "kpi-value", children: value }),
|
|
67
|
+
delta && /* @__PURE__ */ jsx("span", { className: "kpi-delta", children: delta })
|
|
68
|
+
] });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/data/products.ts
|
|
72
|
+
var PROJECT_KIND = {
|
|
73
|
+
service: { color: "oklch(60% 0.137 163)", label: "API" },
|
|
74
|
+
web: { color: "oklch(56% 0.15 240)", label: "Web" },
|
|
75
|
+
desktop: { color: "oklch(48% 0.16 285)", label: "Desktop" },
|
|
76
|
+
workstation: { color: "oklch(50% 0.16 30)", label: "Workstation" },
|
|
77
|
+
mobile: { color: "oklch(58% 0.18 25)", label: "Mobile" },
|
|
78
|
+
library: { color: "oklch(50% 0.05 250)", label: "Library" },
|
|
79
|
+
infra: { color: "oklch(45% 0.05 260)", label: "Infra" }
|
|
80
|
+
};
|
|
81
|
+
function ProjectsListScreen({ product, onSelect }) {
|
|
82
|
+
const { t } = useTranslation();
|
|
83
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
84
|
+
/* @__PURE__ */ jsxs("div", { className: "page-header", children: [
|
|
85
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
86
|
+
/* @__PURE__ */ jsx("h1", { className: "page-title", children: t("nav.projects") }),
|
|
87
|
+
/* @__PURE__ */ jsxs("p", { className: "page-subtitle", children: [
|
|
88
|
+
product.name,
|
|
89
|
+
" \xB7 ",
|
|
90
|
+
product.projects.length,
|
|
91
|
+
" ",
|
|
92
|
+
t("nav.projects").toLowerCase()
|
|
93
|
+
] })
|
|
94
|
+
] }),
|
|
95
|
+
/* @__PURE__ */ jsx("div", { className: "page-actions", children: /* @__PURE__ */ jsxs("button", { className: "btn btn-primary", children: [
|
|
96
|
+
"+ ",
|
|
97
|
+
t("common.new")
|
|
98
|
+
] }) })
|
|
99
|
+
] }),
|
|
100
|
+
/* @__PURE__ */ jsx("div", { className: "card p-0 overflow-hidden", children: /* @__PURE__ */ jsxs("table", { className: "table", children: [
|
|
101
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
102
|
+
/* @__PURE__ */ jsx("th", { children: "Project" }),
|
|
103
|
+
/* @__PURE__ */ jsx("th", { children: "Stack" }),
|
|
104
|
+
/* @__PURE__ */ jsx("th", { children: "Kind" }),
|
|
105
|
+
/* @__PURE__ */ jsx("th", { className: "num", children: "Devs" }),
|
|
106
|
+
/* @__PURE__ */ jsx("th", { className: "num", children: "Issues" }),
|
|
107
|
+
/* @__PURE__ */ jsx("th", { className: "num", children: "PR" }),
|
|
108
|
+
/* @__PURE__ */ jsx("th", { children: "Branch" }),
|
|
109
|
+
/* @__PURE__ */ jsx("th", { children: "Last commit" })
|
|
110
|
+
] }) }),
|
|
111
|
+
/* @__PURE__ */ jsx("tbody", { children: product.projects.map((p) => /* @__PURE__ */ jsxs("tr", { onClick: () => onSelect(p), className: "cursor-pointer", children: [
|
|
112
|
+
/* @__PURE__ */ jsx("td", { className: "font-medium", children: p.name }),
|
|
113
|
+
/* @__PURE__ */ jsx("td", { className: "muted", children: p.stack }),
|
|
114
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("span", { className: "chip", style: { color: PROJECT_KIND[p.kind].color }, children: PROJECT_KIND[p.kind].label }) }),
|
|
115
|
+
/* @__PURE__ */ jsx("td", { className: "num", children: p.devs }),
|
|
116
|
+
/* @__PURE__ */ jsx("td", { className: "num", children: p.openIssues }),
|
|
117
|
+
/* @__PURE__ */ jsx("td", { className: "num", children: p.prs }),
|
|
118
|
+
/* @__PURE__ */ jsx("td", { className: "mono", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
119
|
+
/* @__PURE__ */ jsx(GitBranch, { size: 11 }),
|
|
120
|
+
" ",
|
|
121
|
+
p.branch
|
|
122
|
+
] }) }),
|
|
123
|
+
/* @__PURE__ */ jsx("td", { className: "muted", children: p.lastCommit })
|
|
124
|
+
] }, p.id)) })
|
|
125
|
+
] }) })
|
|
126
|
+
] });
|
|
127
|
+
}
|
|
128
|
+
function cn(...inputs) {
|
|
129
|
+
return twMerge(clsx(inputs));
|
|
130
|
+
}
|
|
131
|
+
var PLANS = [
|
|
132
|
+
{ id: "PDCA-Q2-001", number: 1, title: "OAuth migration kickoff", phase: "check", health: "at-risk", owner: "satoshi", due: "2026-06-30", progress: 64 },
|
|
133
|
+
{ id: "PDCA-Q2-002", number: 2, title: "Forge-service extraction (Plan #19)", phase: "do", health: "ok", owner: "naoki", due: "2026-07-14", progress: 41 },
|
|
134
|
+
{ id: "PDCA-Q2-003", number: 3, title: "Sandbox secrets via Vault (Plan #38)", phase: "plan", health: "ok", owner: "anh", due: "2026-08-01", progress: 12 },
|
|
135
|
+
{ id: "PDCA-Q2-004", number: 4, title: "Knowledge-service slug routing (Plan #18)", phase: "act", health: "ok", owner: "kira", due: "2026-05-31", progress: 92 }
|
|
136
|
+
];
|
|
137
|
+
var PHASE_LABEL = { plan: "Plan", do: "Do", check: "Check", act: "Act" };
|
|
138
|
+
var HEALTH_TONE = {
|
|
139
|
+
ok: "badge-success",
|
|
140
|
+
"at-risk": "badge-warning",
|
|
141
|
+
"off-track": "badge-error"
|
|
142
|
+
};
|
|
143
|
+
function PlansScreen({ onOpenPlan }) {
|
|
144
|
+
const { t } = useTranslation();
|
|
145
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
146
|
+
/* @__PURE__ */ jsxs("div", { className: "page-header", children: [
|
|
147
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
148
|
+
/* @__PURE__ */ jsx("h1", { className: "page-title", children: t("nav.plans") }),
|
|
149
|
+
/* @__PURE__ */ jsxs("p", { className: "page-subtitle", children: [
|
|
150
|
+
PLANS.length,
|
|
151
|
+
" plans \xB7 PDCA cycle"
|
|
152
|
+
] })
|
|
153
|
+
] }),
|
|
154
|
+
/* @__PURE__ */ jsx("div", { className: "page-actions", children: /* @__PURE__ */ jsxs("button", { className: "btn btn-primary", children: [
|
|
155
|
+
"+ ",
|
|
156
|
+
t("common.new")
|
|
157
|
+
] }) })
|
|
158
|
+
] }),
|
|
159
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: PLANS.map((plan) => /* @__PURE__ */ jsxs(
|
|
160
|
+
"button",
|
|
161
|
+
{
|
|
162
|
+
type: "button",
|
|
163
|
+
onClick: () => onOpenPlan(plan.id),
|
|
164
|
+
className: "card text-left hover:border-primary transition-colors",
|
|
165
|
+
children: [
|
|
166
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
167
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs font-mono text-muted-foreground", children: [
|
|
168
|
+
"#",
|
|
169
|
+
plan.id
|
|
170
|
+
] }),
|
|
171
|
+
/* @__PURE__ */ jsxs("span", { className: "badge badge-neutral", children: [
|
|
172
|
+
/* @__PURE__ */ jsx("span", { className: "dot" }),
|
|
173
|
+
" ",
|
|
174
|
+
PHASE_LABEL[plan.phase]
|
|
175
|
+
] }),
|
|
176
|
+
/* @__PURE__ */ jsxs("span", { className: cn("badge", HEALTH_TONE[plan.health]), children: [
|
|
177
|
+
/* @__PURE__ */ jsx("span", { className: "dot" }),
|
|
178
|
+
plan.health
|
|
179
|
+
] })
|
|
180
|
+
] }),
|
|
181
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-medium mb-2", children: plan.title }),
|
|
182
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground mb-3", children: [
|
|
183
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
184
|
+
"@",
|
|
185
|
+
plan.owner
|
|
186
|
+
] }),
|
|
187
|
+
/* @__PURE__ */ jsx("span", { children: "\xB7" }),
|
|
188
|
+
/* @__PURE__ */ jsx("span", { children: plan.due })
|
|
189
|
+
] }),
|
|
190
|
+
/* @__PURE__ */ jsx("div", { className: "h-1.5 bg-surface-3 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "h-full bg-primary transition-all", style: { width: `${plan.progress}%` } }) }),
|
|
191
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground mt-1 block tnum", children: [
|
|
192
|
+
plan.progress,
|
|
193
|
+
"%"
|
|
194
|
+
] })
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
plan.id
|
|
198
|
+
)) })
|
|
199
|
+
] });
|
|
200
|
+
}
|
|
201
|
+
var ISSUES = [
|
|
202
|
+
{ id: "GK-301", status: "backlog", title: "Notify SSE handshake retries when token expired", type: "bug", priority: "high", assignee: "satoshi" },
|
|
203
|
+
{ id: "GK-310", status: "in-progress", title: "Wire sticky QuickComposer for backlog-style edits", type: "feature", priority: "medium", assignee: "naoki" },
|
|
204
|
+
{ id: "GK-311", status: "in-progress", title: "Tweaks panel keyboard shortcut conflict", type: "task", priority: "low", assignee: "anh" },
|
|
205
|
+
{ id: "GK-302", status: "review", title: "Forge nav grouping per audience", type: "task", priority: "medium", assignee: "kira" },
|
|
206
|
+
{ id: "GK-298", status: "done", title: "Drop NOT NULL project_id on plans/issues", type: "bug", priority: "urgent", assignee: "satoshi" }
|
|
207
|
+
];
|
|
208
|
+
var COLS = [
|
|
209
|
+
{ id: "backlog", label: "Backlog" },
|
|
210
|
+
{ id: "in-progress", label: "In progress" },
|
|
211
|
+
{ id: "review", label: "Review" },
|
|
212
|
+
{ id: "done", label: "Done" }
|
|
213
|
+
];
|
|
214
|
+
var PRIO_DOT = {
|
|
215
|
+
low: "var(--muted-foreground)",
|
|
216
|
+
medium: "var(--info)",
|
|
217
|
+
high: "var(--warning)",
|
|
218
|
+
urgent: "var(--destructive)"
|
|
219
|
+
};
|
|
220
|
+
function IssuesScreen({ onOpenIssue }) {
|
|
221
|
+
const { t } = useTranslation();
|
|
222
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
223
|
+
/* @__PURE__ */ jsxs("div", { className: "page-header", children: [
|
|
224
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
225
|
+
/* @__PURE__ */ jsx("h1", { className: "page-title", children: t("nav.issues") }),
|
|
226
|
+
/* @__PURE__ */ jsxs("p", { className: "page-subtitle", children: [
|
|
227
|
+
ISSUES.length,
|
|
228
|
+
" issues"
|
|
229
|
+
] })
|
|
230
|
+
] }),
|
|
231
|
+
/* @__PURE__ */ jsx("div", { className: "page-actions", children: /* @__PURE__ */ jsxs("button", { className: "btn btn-primary", children: [
|
|
232
|
+
"+ ",
|
|
233
|
+
t("common.new")
|
|
234
|
+
] }) })
|
|
235
|
+
] }),
|
|
236
|
+
/* @__PURE__ */ jsx("div", { className: "kanban", children: COLS.map((col) => {
|
|
237
|
+
const rows = ISSUES.filter((i) => i.status === col.id);
|
|
238
|
+
return /* @__PURE__ */ jsxs("div", { className: "kanban-col", children: [
|
|
239
|
+
/* @__PURE__ */ jsxs("div", { className: "kanban-col-head", children: [
|
|
240
|
+
/* @__PURE__ */ jsx("span", { children: col.label }),
|
|
241
|
+
/* @__PURE__ */ jsx("span", { className: "kanban-col-count", children: rows.length })
|
|
242
|
+
] }),
|
|
243
|
+
rows.map((issue) => /* @__PURE__ */ jsxs(
|
|
244
|
+
"button",
|
|
245
|
+
{
|
|
246
|
+
type: "button",
|
|
247
|
+
onClick: () => onOpenIssue(issue.id),
|
|
248
|
+
className: "issue-card text-left",
|
|
249
|
+
children: [
|
|
250
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
251
|
+
/* @__PURE__ */ jsx("span", { className: "issue-id", children: issue.id }),
|
|
252
|
+
/* @__PURE__ */ jsx(
|
|
253
|
+
"span",
|
|
254
|
+
{
|
|
255
|
+
className: "dot",
|
|
256
|
+
style: { background: PRIO_DOT[issue.priority] },
|
|
257
|
+
"aria-label": issue.priority
|
|
258
|
+
}
|
|
259
|
+
),
|
|
260
|
+
/* @__PURE__ */ jsx("span", { className: "chip ml-auto", children: issue.type })
|
|
261
|
+
] }),
|
|
262
|
+
/* @__PURE__ */ jsx("span", { className: "issue-title", children: issue.title }),
|
|
263
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
264
|
+
"@",
|
|
265
|
+
issue.assignee
|
|
266
|
+
] })
|
|
267
|
+
]
|
|
268
|
+
},
|
|
269
|
+
issue.id
|
|
270
|
+
))
|
|
271
|
+
] }, col.id);
|
|
272
|
+
}) })
|
|
273
|
+
] });
|
|
274
|
+
}
|
|
275
|
+
var DEFAULT_TOC = [
|
|
276
|
+
{ id: "intro", label: "Introduction" },
|
|
277
|
+
{ id: "stack", label: "Stack" },
|
|
278
|
+
{ id: "deployment", label: "Deployment" },
|
|
279
|
+
{ id: "onboarding", label: "Onboarding" }
|
|
280
|
+
];
|
|
281
|
+
function WikiScreen({ toc = DEFAULT_TOC, children, meta }) {
|
|
282
|
+
const { t } = useTranslation();
|
|
283
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
284
|
+
/* @__PURE__ */ jsxs("div", { className: "page-header", children: [
|
|
285
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
286
|
+
/* @__PURE__ */ jsx("h1", { className: "page-title", children: t("nav.wiki") }),
|
|
287
|
+
/* @__PURE__ */ jsx("p", { className: "page-subtitle", children: "Living documentation" })
|
|
288
|
+
] }),
|
|
289
|
+
/* @__PURE__ */ jsx("div", { className: "page-actions", children: /* @__PURE__ */ jsxs("button", { className: "btn btn-primary", children: [
|
|
290
|
+
"+ ",
|
|
291
|
+
t("common.new")
|
|
292
|
+
] }) })
|
|
293
|
+
] }),
|
|
294
|
+
/* @__PURE__ */ jsxs("div", { className: "wiki-layout", children: [
|
|
295
|
+
/* @__PURE__ */ jsx("nav", { className: "wiki-toc", "aria-label": "Table of contents", children: toc.map((entry, i) => /* @__PURE__ */ jsx("a", { href: `#${entry.id}`, className: i === 0 ? "active" : void 0, children: entry.label }, entry.id)) }),
|
|
296
|
+
/* @__PURE__ */ jsx("article", { className: "prose", children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
297
|
+
/* @__PURE__ */ jsx("h1", { id: "intro", children: "GoDX Forge \u2014 Engineering handbook" }),
|
|
298
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
299
|
+
"This wiki is a living reference for everyone working on the GoDX Forge platform. It mirrors the source-of-truth documentation that lives in ",
|
|
300
|
+
/* @__PURE__ */ jsx("code", { children: "docs/" }),
|
|
301
|
+
"; edits here are commits."
|
|
302
|
+
] }),
|
|
303
|
+
/* @__PURE__ */ jsx("h2", { id: "stack", children: "Stack" }),
|
|
304
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
305
|
+
"Each frontend service consumes ",
|
|
306
|
+
/* @__PURE__ */ jsx("code", { children: "@godxjp/ui" }),
|
|
307
|
+
" for tokens, primitives, shell, i18n. Backend kernel lives in",
|
|
308
|
+
" ",
|
|
309
|
+
/* @__PURE__ */ jsx("code", { children: "services/_sdk/" }),
|
|
310
|
+
" (Go)."
|
|
311
|
+
] }),
|
|
312
|
+
/* @__PURE__ */ jsxs("ul", { children: [
|
|
313
|
+
/* @__PURE__ */ jsx("li", { children: "React 19 \xB7 Vite \xB7 TypeScript" }),
|
|
314
|
+
/* @__PURE__ */ jsxs("li", { children: [
|
|
315
|
+
"Tailwind v4 with CSS-first ",
|
|
316
|
+
/* @__PURE__ */ jsx("code", { children: "@theme" }),
|
|
317
|
+
" bridge"
|
|
318
|
+
] }),
|
|
319
|
+
/* @__PURE__ */ jsx("li", { children: "i18next auto-detect + JA fallback" })
|
|
320
|
+
] }),
|
|
321
|
+
/* @__PURE__ */ jsx("h2", { id: "deployment", children: "Deployment" }),
|
|
322
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
323
|
+
"Compose-orchestrated; subdomains route through Caddy per",
|
|
324
|
+
/* @__PURE__ */ jsx("code", { children: "deploy/docker/Caddyfile" }),
|
|
325
|
+
"."
|
|
326
|
+
] }),
|
|
327
|
+
/* @__PURE__ */ jsx("h2", { id: "onboarding", children: "Onboarding" }),
|
|
328
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
329
|
+
"See ",
|
|
330
|
+
/* @__PURE__ */ jsx("code", { children: "docs/onboarding/dev.md" }),
|
|
331
|
+
" for the day-0 checklist."
|
|
332
|
+
] })
|
|
333
|
+
] }) }),
|
|
334
|
+
/* @__PURE__ */ jsx("aside", { className: "text-xs text-muted-foreground", "aria-label": "Meta", children: meta ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
335
|
+
/* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wider mb-2", children: "Updated" }),
|
|
336
|
+
/* @__PURE__ */ jsx("p", { children: "2 hours ago by @satoshi" })
|
|
337
|
+
] }) })
|
|
338
|
+
] })
|
|
339
|
+
] });
|
|
340
|
+
}
|
|
341
|
+
var IDEAS = [
|
|
342
|
+
{ id: "IDEA-12", title: "Bulk action on issues board", problem: "Triaging 30+ issues requires clicking each card. Need shift-click multi-select + bulk move/edit.", appetite: "1w", status: "under_review", votes: 7, pitched_by: "satoshi" },
|
|
343
|
+
{ id: "IDEA-13", title: "Sandbox snapshot for AI debugging", problem: "When agent goes off the rails I want to time-travel the sandbox FS to a known-good state.", appetite: "6w", status: "draft", votes: 4, pitched_by: "naoki" },
|
|
344
|
+
{ id: "IDEA-14", title: "Workspace dark-mode default detection", problem: "First-load flicker as theme resolves from localStorage \u2014 should follow system pref pre-hydration.", appetite: "3d", status: "scored", votes: 2, pitched_by: "anh" }
|
|
345
|
+
];
|
|
346
|
+
var STATUS_TONE = {
|
|
347
|
+
draft: "badge-neutral",
|
|
348
|
+
under_review: "badge-info",
|
|
349
|
+
scored: "badge-warning",
|
|
350
|
+
accepted: "badge-success",
|
|
351
|
+
rejected: "badge-error"
|
|
352
|
+
};
|
|
353
|
+
var STATUS_LABEL = {
|
|
354
|
+
draft: "Draft",
|
|
355
|
+
under_review: "Review",
|
|
356
|
+
scored: "Scored",
|
|
357
|
+
accepted: "Accepted",
|
|
358
|
+
rejected: "Rejected"
|
|
359
|
+
};
|
|
360
|
+
function IdeasScreen() {
|
|
361
|
+
const { t } = useTranslation();
|
|
362
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
363
|
+
/* @__PURE__ */ jsxs("div", { className: "page-header", children: [
|
|
364
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
365
|
+
/* @__PURE__ */ jsx("h1", { className: "page-title", children: t("nav.ideas") }),
|
|
366
|
+
/* @__PURE__ */ jsx("p", { className: "page-subtitle", children: "Shape Up \u2014 problem \xB7 appetite \xB7 solution" })
|
|
367
|
+
] }),
|
|
368
|
+
/* @__PURE__ */ jsx("div", { className: "page-actions", children: /* @__PURE__ */ jsxs("button", { className: "btn btn-primary", children: [
|
|
369
|
+
"+ ",
|
|
370
|
+
t("common.new")
|
|
371
|
+
] }) })
|
|
372
|
+
] }),
|
|
373
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-3", children: IDEAS.map((idea) => /* @__PURE__ */ jsxs("article", { className: "card flex flex-col gap-2", children: [
|
|
374
|
+
/* @__PURE__ */ jsxs("header", { className: "flex items-center gap-2", children: [
|
|
375
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-muted-foreground", children: idea.id }),
|
|
376
|
+
/* @__PURE__ */ jsxs("span", { className: `badge ${STATUS_TONE[idea.status]}`, children: [
|
|
377
|
+
/* @__PURE__ */ jsx("span", { className: "dot" }),
|
|
378
|
+
" ",
|
|
379
|
+
STATUS_LABEL[idea.status]
|
|
380
|
+
] }),
|
|
381
|
+
/* @__PURE__ */ jsxs("span", { className: "chip ml-auto", children: [
|
|
382
|
+
"\u23F1 ",
|
|
383
|
+
idea.appetite
|
|
384
|
+
] })
|
|
385
|
+
] }),
|
|
386
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-medium", children: idea.title }),
|
|
387
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground line-clamp-3", children: idea.problem }),
|
|
388
|
+
/* @__PURE__ */ jsxs("footer", { className: "flex items-center gap-2 text-[10px] text-muted-foreground mt-auto pt-2 border-t border-border", children: [
|
|
389
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
390
|
+
"@",
|
|
391
|
+
idea.pitched_by
|
|
392
|
+
] }),
|
|
393
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-auto", children: [
|
|
394
|
+
"\u25B2 ",
|
|
395
|
+
idea.votes
|
|
396
|
+
] })
|
|
397
|
+
] })
|
|
398
|
+
] }, idea.id)) })
|
|
399
|
+
] });
|
|
400
|
+
}
|
|
401
|
+
var PHASES = [
|
|
402
|
+
{ id: "plan", description: "Frame the goal + design contract" },
|
|
403
|
+
{ id: "do", description: "Execute + track progress" },
|
|
404
|
+
{ id: "check", description: "Measure outcomes + review" },
|
|
405
|
+
{ id: "act", description: "Standardize + roll out" }
|
|
406
|
+
];
|
|
407
|
+
var LINKED_TASKS = [
|
|
408
|
+
{ id: "GK-310", title: "Wire sticky QuickComposer", owner: "naoki", state: "in-progress" },
|
|
409
|
+
{ id: "GK-301", title: "SSE retry on token expire", owner: "satoshi", state: "review" },
|
|
410
|
+
{ id: "GK-302", title: "Forge nav grouping", owner: "kira", state: "review" }
|
|
411
|
+
];
|
|
412
|
+
var KPI = [
|
|
413
|
+
{ label: "Activation rate", value: "62%", delta: "+8" },
|
|
414
|
+
{ label: "Time to first plan", value: "4m12s", delta: "-22s" },
|
|
415
|
+
{ label: "Plans per dev", value: "1.4", delta: "+0.3" },
|
|
416
|
+
{ label: "Hypothesis hit", value: "3/5", delta: "" }
|
|
417
|
+
];
|
|
418
|
+
var ADOPTION = [
|
|
419
|
+
{ tag: "ADOPT", title: "Sticky QuickComposer is now default", color: "var(--success)" },
|
|
420
|
+
{ tag: "TRY", title: "Markdown preview in modal \u2014 gather 1 sprint feedback", color: "var(--info)" },
|
|
421
|
+
{ tag: "DROP", title: "Auto-save every keystroke (too aggressive)", color: "var(--destructive)" },
|
|
422
|
+
{ tag: "PARK", title: "AI-suggested labels (waiting on plan #21 G18)", color: "var(--muted-foreground)" }
|
|
423
|
+
];
|
|
424
|
+
function PlanDetailScreen({ planId, onBack, onOpenIssue }) {
|
|
425
|
+
const { t } = useTranslation();
|
|
426
|
+
const [phase, setPhase] = useState("check");
|
|
427
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
428
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-4 text-xs", children: [
|
|
429
|
+
/* @__PURE__ */ jsx("button", { onClick: onBack, className: "tb-icon-btn", "aria-label": t("common.back"), children: /* @__PURE__ */ jsx(ArrowLeft, { size: 14 }) }),
|
|
430
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t("nav.plans") }),
|
|
431
|
+
/* @__PURE__ */ jsx(ChevronRight, { size: 12, className: "text-muted-foreground" }),
|
|
432
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: planId })
|
|
433
|
+
] }),
|
|
434
|
+
/* @__PURE__ */ jsxs("div", { className: "page-header", children: [
|
|
435
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
436
|
+
/* @__PURE__ */ jsx("h1", { className: "page-title", children: "OAuth migration kickoff" }),
|
|
437
|
+
/* @__PURE__ */ jsx("p", { className: "page-subtitle", children: "Q2 PDCA \u2014 moving the legacy admin login chain to OIDC end-to-end" })
|
|
438
|
+
] }),
|
|
439
|
+
/* @__PURE__ */ jsx("div", { className: "page-actions", children: /* @__PURE__ */ jsxs("span", { className: "badge badge-warning", children: [
|
|
440
|
+
/* @__PURE__ */ jsx("span", { className: "dot" }),
|
|
441
|
+
" at risk"
|
|
442
|
+
] }) })
|
|
443
|
+
] }),
|
|
444
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-2 mb-6", children: PHASES.map((p, idx) => {
|
|
445
|
+
const active = p.id === phase;
|
|
446
|
+
return /* @__PURE__ */ jsxs(
|
|
447
|
+
"button",
|
|
448
|
+
{
|
|
449
|
+
type: "button",
|
|
450
|
+
onClick: () => setPhase(p.id),
|
|
451
|
+
className: cn("relative card text-left transition-colors", active && "border-primary"),
|
|
452
|
+
"aria-current": active,
|
|
453
|
+
children: [
|
|
454
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: [
|
|
455
|
+
"Step ",
|
|
456
|
+
idx + 1
|
|
457
|
+
] }),
|
|
458
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-medium mt-1", children: t(`pdca.${p.id}`) }),
|
|
459
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: p.description }),
|
|
460
|
+
idx < PHASES.length - 1 && /* @__PURE__ */ jsx(
|
|
461
|
+
ChevronRight,
|
|
462
|
+
{
|
|
463
|
+
size: 14,
|
|
464
|
+
className: "absolute -right-2.5 top-1/2 -translate-y-1/2 bg-background border border-border rounded-full text-muted-foreground"
|
|
465
|
+
}
|
|
466
|
+
)
|
|
467
|
+
]
|
|
468
|
+
},
|
|
469
|
+
p.id
|
|
470
|
+
);
|
|
471
|
+
}) }),
|
|
472
|
+
phase === "plan" && /* @__PURE__ */ jsxs("section", { className: "card", children: [
|
|
473
|
+
/* @__PURE__ */ jsx("h2", { className: "card-title mb-3", children: t("pdca.hypothesis") }),
|
|
474
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "Replacing the legacy admin password form with the OIDC chain will cut authentication failures by 40% within one quarter." }),
|
|
475
|
+
/* @__PURE__ */ jsx("h3", { className: "card-title mt-6 mb-2", children: t("pdca.metrics") }),
|
|
476
|
+
/* @__PURE__ */ jsxs("ul", { className: "text-sm list-disc pl-5", children: [
|
|
477
|
+
/* @__PURE__ */ jsx("li", { children: "Auth failures < 0.5% of attempts" }),
|
|
478
|
+
/* @__PURE__ */ jsx("li", { children: "Time-to-sign-in < 3s p95" }),
|
|
479
|
+
/* @__PURE__ */ jsx("li", { children: "Zero password resets logged for SSO users" })
|
|
480
|
+
] }),
|
|
481
|
+
/* @__PURE__ */ jsx("h3", { className: "card-title mt-6 mb-2", children: t("pdca.risks") }),
|
|
482
|
+
/* @__PURE__ */ jsxs("ul", { className: "text-sm list-disc pl-5 text-muted-foreground", children: [
|
|
483
|
+
/* @__PURE__ */ jsx("li", { children: "Identity-portal cookie domain drift between envs" }),
|
|
484
|
+
/* @__PURE__ */ jsx("li", { children: "RFC 9457 problem-detail rollout coupling" })
|
|
485
|
+
] })
|
|
486
|
+
] }),
|
|
487
|
+
phase === "do" && /* @__PURE__ */ jsxs("section", { className: "card", children: [
|
|
488
|
+
/* @__PURE__ */ jsx("h2", { className: "card-title mb-3", children: t("pdca.linkedTasks") }),
|
|
489
|
+
/* @__PURE__ */ jsxs("table", { className: "table", children: [
|
|
490
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
491
|
+
/* @__PURE__ */ jsx("th", { children: "ID" }),
|
|
492
|
+
/* @__PURE__ */ jsx("th", { children: "Title" }),
|
|
493
|
+
/* @__PURE__ */ jsx("th", { children: "Owner" }),
|
|
494
|
+
/* @__PURE__ */ jsx("th", { children: "State" })
|
|
495
|
+
] }) }),
|
|
496
|
+
/* @__PURE__ */ jsx("tbody", { children: LINKED_TASKS.map((task) => /* @__PURE__ */ jsxs("tr", { onClick: () => onOpenIssue(task.id), className: "cursor-pointer", children: [
|
|
497
|
+
/* @__PURE__ */ jsx("td", { className: "mono", children: task.id }),
|
|
498
|
+
/* @__PURE__ */ jsx("td", { children: task.title }),
|
|
499
|
+
/* @__PURE__ */ jsxs("td", { className: "muted", children: [
|
|
500
|
+
"@",
|
|
501
|
+
task.owner
|
|
502
|
+
] }),
|
|
503
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsxs("span", { className: "badge badge-neutral", children: [
|
|
504
|
+
/* @__PURE__ */ jsx("span", { className: "dot" }),
|
|
505
|
+
" ",
|
|
506
|
+
task.state
|
|
507
|
+
] }) })
|
|
508
|
+
] }, task.id)) })
|
|
509
|
+
] })
|
|
510
|
+
] }),
|
|
511
|
+
phase === "check" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
512
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-3 mb-4", children: KPI.map((k) => /* @__PURE__ */ jsxs("div", { className: "kpi", children: [
|
|
513
|
+
/* @__PURE__ */ jsx("span", { className: "kpi-label", children: k.label }),
|
|
514
|
+
/* @__PURE__ */ jsx("span", { className: "kpi-value", children: k.value }),
|
|
515
|
+
k.delta && /* @__PURE__ */ jsx("span", { className: cn("kpi-delta", k.delta.startsWith("-") && "down"), children: k.delta })
|
|
516
|
+
] }, k.label)) }),
|
|
517
|
+
/* @__PURE__ */ jsxs("section", { className: "card", children: [
|
|
518
|
+
/* @__PURE__ */ jsx("h2", { className: "card-title mb-3", children: t("pdca.review") }),
|
|
519
|
+
/* @__PURE__ */ jsx(Sparkline, {})
|
|
520
|
+
] })
|
|
521
|
+
] }),
|
|
522
|
+
phase === "act" && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: ADOPTION.map((a) => /* @__PURE__ */ jsxs("div", { className: "card flex flex-col gap-2", children: [
|
|
523
|
+
/* @__PURE__ */ jsx(
|
|
524
|
+
"span",
|
|
525
|
+
{
|
|
526
|
+
className: "text-[10px] font-medium uppercase tracking-wider",
|
|
527
|
+
style: { color: a.color },
|
|
528
|
+
children: a.tag
|
|
529
|
+
}
|
|
530
|
+
),
|
|
531
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: a.title })
|
|
532
|
+
] }, a.tag)) })
|
|
533
|
+
] });
|
|
534
|
+
}
|
|
535
|
+
function Sparkline() {
|
|
536
|
+
const points = [12, 14, 16, 13, 18, 22, 19, 24, 28, 26, 30, 34, 31, 38];
|
|
537
|
+
const max = Math.max(...points);
|
|
538
|
+
const path = points.map((y, i) => `${i === 0 ? "M" : "L"}${i / (points.length - 1) * 100},${100 - y / max * 80}`).join(" ");
|
|
539
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 100 100", preserveAspectRatio: "none", className: "spark", style: { height: 80 }, children: [
|
|
540
|
+
/* @__PURE__ */ jsx("path", { d: `${path} L100,100 L0,100 Z`, className: "area" }),
|
|
541
|
+
/* @__PURE__ */ jsx("path", { d: path, className: "line" })
|
|
542
|
+
] });
|
|
543
|
+
}
|
|
544
|
+
var STATUS_LABEL2 = {
|
|
545
|
+
backlog: "Backlog",
|
|
546
|
+
"in-progress": "In progress",
|
|
547
|
+
review: "Review",
|
|
548
|
+
done: "Done",
|
|
549
|
+
abandoned: "Abandoned"
|
|
550
|
+
};
|
|
551
|
+
var PRIORITY_LABEL = {
|
|
552
|
+
low: "P3",
|
|
553
|
+
medium: "P2",
|
|
554
|
+
high: "P1",
|
|
555
|
+
urgent: "P0"
|
|
556
|
+
};
|
|
557
|
+
var TEAM = ["satoshi", "naoki", "anh", "kira"];
|
|
558
|
+
var COMMENTS = [
|
|
559
|
+
{ id: "c1", who: "satoshi", when: "2h", body: "Cloned latest design; QuickComposer collapse is 52px, expand on focus." },
|
|
560
|
+
{ id: "c2", who: "naoki", when: "1h", body: "Picked P1 \u2014 release window is tight." },
|
|
561
|
+
{ id: "c3", who: "anh", when: "12m", body: "Backend ON CONFLICT works; reproduced count 1\u21922 via curl." }
|
|
562
|
+
];
|
|
563
|
+
function IssueDetailScreen({ issueId, onBack, onOpenPlan }) {
|
|
564
|
+
const { t } = useTranslation();
|
|
565
|
+
const [tab, setTab] = useState("conversation");
|
|
566
|
+
const [composerOpen, setComposerOpen] = useState(false);
|
|
567
|
+
const [body, setBody] = useState("");
|
|
568
|
+
const [status, setStatus] = useState("in-progress");
|
|
569
|
+
const [assignee, setAssignee] = useState(TEAM[0]);
|
|
570
|
+
const [priority, setPriority] = useState("medium");
|
|
571
|
+
const initial = { status: "in-progress", assignee: TEAM[0], priority: "medium" };
|
|
572
|
+
const hasChanges = status !== initial.status || assignee !== initial.assignee || priority !== initial.priority;
|
|
573
|
+
return /* @__PURE__ */ jsxs(
|
|
574
|
+
"div",
|
|
575
|
+
{
|
|
576
|
+
className: "flex flex-col",
|
|
577
|
+
style: { minHeight: "calc(100vh - var(--header-height))" },
|
|
578
|
+
children: [
|
|
579
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
580
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-4 text-xs", children: [
|
|
581
|
+
/* @__PURE__ */ jsx("button", { onClick: onBack, className: "tb-icon-btn", "aria-label": t("common.back"), children: /* @__PURE__ */ jsx(ArrowLeft, { size: 14 }) }),
|
|
582
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t("nav.issues") }),
|
|
583
|
+
/* @__PURE__ */ jsx(ChevronRight, { size: 12, className: "text-muted-foreground" }),
|
|
584
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: issueId })
|
|
585
|
+
] }),
|
|
586
|
+
/* @__PURE__ */ jsxs("div", { className: "page-header", children: [
|
|
587
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
588
|
+
/* @__PURE__ */ jsx("h1", { className: "page-title", children: "Wire sticky QuickComposer for backlog-style edits" }),
|
|
589
|
+
/* @__PURE__ */ jsx("p", { className: "page-subtitle", children: "@naoki opened \xB7 2 days ago" })
|
|
590
|
+
] }),
|
|
591
|
+
/* @__PURE__ */ jsxs("div", { className: "page-actions", children: [
|
|
592
|
+
/* @__PURE__ */ jsxs("span", { className: "badge badge-info", children: [
|
|
593
|
+
/* @__PURE__ */ jsx("span", { className: "dot" }),
|
|
594
|
+
" ",
|
|
595
|
+
STATUS_LABEL2[status]
|
|
596
|
+
] }),
|
|
597
|
+
/* @__PURE__ */ jsx("span", { className: "badge badge-warning", children: PRIORITY_LABEL[priority] })
|
|
598
|
+
] })
|
|
599
|
+
] }),
|
|
600
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-6", style: { gridTemplateColumns: "1fr 240px" }, children: [
|
|
601
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
602
|
+
/* @__PURE__ */ jsxs("div", { className: "tabs mb-4", children: [
|
|
603
|
+
/* @__PURE__ */ jsx("button", { className: "tab", "data-active": tab === "conversation", onClick: () => setTab("conversation"), children: t("issue.conversation") }),
|
|
604
|
+
/* @__PURE__ */ jsx("button", { className: "tab", "data-active": tab === "checklist", onClick: () => setTab("checklist"), children: t("issue.checklist") }),
|
|
605
|
+
/* @__PURE__ */ jsx("button", { className: "tab", "data-active": tab === "code", onClick: () => setTab("code"), children: t("issue.codeChanges") }),
|
|
606
|
+
/* @__PURE__ */ jsx("button", { className: "tab", "data-active": tab === "history", onClick: () => setTab("history"), children: t("issue.history") })
|
|
607
|
+
] }),
|
|
608
|
+
tab === "conversation" && /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-3", children: COMMENTS.map((c) => /* @__PURE__ */ jsxs("li", { className: "card", children: [
|
|
609
|
+
/* @__PURE__ */ jsxs("header", { className: "flex items-center gap-2 text-xs text-muted-foreground mb-2", children: [
|
|
610
|
+
/* @__PURE__ */ jsx("span", { className: "avatar", style: { width: 24, height: 24, fontSize: 10 }, children: c.who[0]?.toUpperCase() }),
|
|
611
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium text-foreground", children: [
|
|
612
|
+
"@",
|
|
613
|
+
c.who
|
|
614
|
+
] }),
|
|
615
|
+
/* @__PURE__ */ jsx("span", { children: "\xB7" }),
|
|
616
|
+
/* @__PURE__ */ jsx("span", { children: c.when })
|
|
617
|
+
] }),
|
|
618
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: c.body })
|
|
619
|
+
] }, c.id)) }),
|
|
620
|
+
tab === "checklist" && /* @__PURE__ */ jsx("div", { className: "card", children: /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-2 text-sm", children: [
|
|
621
|
+
/* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
622
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", defaultChecked: true }),
|
|
623
|
+
" Sticky composer renders at 52px"
|
|
624
|
+
] }) }),
|
|
625
|
+
/* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
626
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", defaultChecked: true }),
|
|
627
|
+
" Expand on focus, collapse on outside click"
|
|
628
|
+
] }) }),
|
|
629
|
+
/* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
630
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox" }),
|
|
631
|
+
" Status/assignee/priority pickers"
|
|
632
|
+
] }) }),
|
|
633
|
+
/* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
634
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox" }),
|
|
635
|
+
" \u2318+Enter submit"
|
|
636
|
+
] }) })
|
|
637
|
+
] }) }),
|
|
638
|
+
tab === "code" && /* @__PURE__ */ jsxs("div", { className: "diff", children: [
|
|
639
|
+
/* @__PURE__ */ jsxs("div", { className: "diff-row ctx", children: [
|
|
640
|
+
/* @__PURE__ */ jsx("span", { className: "ln", children: "12" }),
|
|
641
|
+
/* @__PURE__ */ jsx("span", { className: "ln", children: "12" }),
|
|
642
|
+
/* @__PURE__ */ jsx("span", { className: "body", children: "function App() {" })
|
|
643
|
+
] }),
|
|
644
|
+
/* @__PURE__ */ jsxs("div", { className: "diff-row del", children: [
|
|
645
|
+
/* @__PURE__ */ jsx("span", { className: "ln", children: "13" }),
|
|
646
|
+
/* @__PURE__ */ jsx("span", { className: "ln" }),
|
|
647
|
+
/* @__PURE__ */ jsx("span", { className: "body", children: " const [open, setOpen] = useState(false);" })
|
|
648
|
+
] }),
|
|
649
|
+
/* @__PURE__ */ jsxs("div", { className: "diff-row add", children: [
|
|
650
|
+
/* @__PURE__ */ jsx("span", { className: "ln" }),
|
|
651
|
+
/* @__PURE__ */ jsx("span", { className: "ln", children: "13" }),
|
|
652
|
+
/* @__PURE__ */ jsx("span", { className: "body", children: " const [composerOpen, setComposerOpen] = useState(false);" })
|
|
653
|
+
] }),
|
|
654
|
+
/* @__PURE__ */ jsxs("div", { className: "diff-row ctx", children: [
|
|
655
|
+
/* @__PURE__ */ jsx("span", { className: "ln", children: "14" }),
|
|
656
|
+
/* @__PURE__ */ jsx("span", { className: "ln", children: "14" }),
|
|
657
|
+
/* @__PURE__ */ jsx("span", { className: "body", children: " return <Shell />;" })
|
|
658
|
+
] })
|
|
659
|
+
] }),
|
|
660
|
+
tab === "history" && /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-1 text-xs", children: [
|
|
661
|
+
/* @__PURE__ */ jsxs("li", { className: "log-line", children: [
|
|
662
|
+
/* @__PURE__ */ jsx("span", { className: "time", children: "2d" }),
|
|
663
|
+
/* @__PURE__ */ jsx("span", { className: "src", children: "@naoki" }),
|
|
664
|
+
/* @__PURE__ */ jsx("span", { children: "opened the issue" })
|
|
665
|
+
] }),
|
|
666
|
+
/* @__PURE__ */ jsxs("li", { className: "log-line", children: [
|
|
667
|
+
/* @__PURE__ */ jsx("span", { className: "time", children: "1d" }),
|
|
668
|
+
/* @__PURE__ */ jsx("span", { className: "src ok", children: "@satoshi" }),
|
|
669
|
+
/* @__PURE__ */ jsx("span", { children: "moved to In progress" })
|
|
670
|
+
] }),
|
|
671
|
+
/* @__PURE__ */ jsxs("li", { className: "log-line", children: [
|
|
672
|
+
/* @__PURE__ */ jsx("span", { className: "time", children: "2h" }),
|
|
673
|
+
/* @__PURE__ */ jsx("span", { className: "src warn", children: "@anh" }),
|
|
674
|
+
/* @__PURE__ */ jsx("span", { children: "changed priority to P1" })
|
|
675
|
+
] })
|
|
676
|
+
] })
|
|
677
|
+
] }),
|
|
678
|
+
/* @__PURE__ */ jsxs("aside", { className: "flex flex-col gap-3 text-xs", children: [
|
|
679
|
+
/* @__PURE__ */ jsxs(SidebarField, { label: t("issue.assignee"), children: [
|
|
680
|
+
"@",
|
|
681
|
+
assignee
|
|
682
|
+
] }),
|
|
683
|
+
/* @__PURE__ */ jsxs(SidebarField, { label: t("issue.labels"), children: [
|
|
684
|
+
/* @__PURE__ */ jsx("span", { className: "chip", children: "design-system" }),
|
|
685
|
+
/* @__PURE__ */ jsx("span", { className: "chip", children: "frontend" })
|
|
686
|
+
] }),
|
|
687
|
+
/* @__PURE__ */ jsx(SidebarField, { label: t("issue.milestone"), children: "2026-Q2 release" }),
|
|
688
|
+
/* @__PURE__ */ jsx(SidebarField, { label: t("issue.sprint"), children: "Sprint 12" }),
|
|
689
|
+
/* @__PURE__ */ jsx(SidebarField, { label: t("issue.points"), children: "5" }),
|
|
690
|
+
/* @__PURE__ */ jsx(SidebarField, { label: t("issue.relatedPlan"), children: /* @__PURE__ */ jsx("button", { onClick: () => onOpenPlan("PDCA-Q2-001"), className: "underline text-primary", children: "PDCA-Q2-001" }) })
|
|
691
|
+
] })
|
|
692
|
+
] })
|
|
693
|
+
] }),
|
|
694
|
+
/* @__PURE__ */ jsx(
|
|
695
|
+
"div",
|
|
696
|
+
{
|
|
697
|
+
className: "sticky bottom-0 mt-6 py-2 border-t border-border bg-background/85 backdrop-blur",
|
|
698
|
+
style: { marginLeft: "calc(var(--spacing-6) * -1)", marginRight: "calc(var(--spacing-6) * -1)", paddingLeft: "var(--spacing-6)", paddingRight: "var(--spacing-6)" },
|
|
699
|
+
children: !composerOpen ? /* @__PURE__ */ jsxs(
|
|
700
|
+
"button",
|
|
701
|
+
{
|
|
702
|
+
type: "button",
|
|
703
|
+
className: "flex w-full items-center gap-2 text-xs text-muted-foreground hover:text-foreground py-1",
|
|
704
|
+
onClick: () => setComposerOpen(true),
|
|
705
|
+
children: [
|
|
706
|
+
/* @__PURE__ */ jsx("span", { className: "avatar", style: { width: 24, height: 24, fontSize: 10 }, children: "S" }),
|
|
707
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
708
|
+
issueId,
|
|
709
|
+
" \xB7 ",
|
|
710
|
+
t("issue.addComment")
|
|
711
|
+
] }),
|
|
712
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-auto flex items-center gap-2", children: [
|
|
713
|
+
/* @__PURE__ */ jsx("span", { className: "chip", children: STATUS_LABEL2[status] }),
|
|
714
|
+
/* @__PURE__ */ jsx("span", { className: "chip", children: PRIORITY_LABEL[priority] }),
|
|
715
|
+
/* @__PURE__ */ jsx("kbd", { className: "kbd", children: "C" })
|
|
716
|
+
] })
|
|
717
|
+
]
|
|
718
|
+
}
|
|
719
|
+
) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
720
|
+
/* @__PURE__ */ jsx(
|
|
721
|
+
"textarea",
|
|
722
|
+
{
|
|
723
|
+
autoFocus: true,
|
|
724
|
+
value: body,
|
|
725
|
+
onChange: (e) => setBody(e.target.value),
|
|
726
|
+
placeholder: t("issue.addComment"),
|
|
727
|
+
rows: 3,
|
|
728
|
+
className: "input",
|
|
729
|
+
onBlur: (e) => {
|
|
730
|
+
if (!e.currentTarget.value && !e.relatedTarget) {
|
|
731
|
+
setComposerOpen(false);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
),
|
|
736
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
737
|
+
/* @__PURE__ */ jsx(PillPicker, { label: t("issue.status"), value: STATUS_LABEL2[status], changed: status !== initial.status, children: Object.keys(STATUS_LABEL2).map((s) => /* @__PURE__ */ jsx("button", { type: "button", className: "sw-pop-item w-full text-left", onClick: () => setStatus(s), children: STATUS_LABEL2[s] }, s)) }),
|
|
738
|
+
/* @__PURE__ */ jsx(PillPicker, { label: t("issue.assignee"), value: `@${assignee}`, changed: assignee !== initial.assignee, children: TEAM.map((u) => /* @__PURE__ */ jsxs("button", { type: "button", className: "sw-pop-item w-full text-left", onClick: () => setAssignee(u), children: [
|
|
739
|
+
"@",
|
|
740
|
+
u
|
|
741
|
+
] }, u)) }),
|
|
742
|
+
/* @__PURE__ */ jsx(PillPicker, { label: t("issue.priority"), value: PRIORITY_LABEL[priority], changed: priority !== initial.priority, children: Object.keys(PRIORITY_LABEL).map((p) => /* @__PURE__ */ jsx("button", { type: "button", className: "sw-pop-item w-full text-left", onClick: () => setPriority(p), children: PRIORITY_LABEL[p] }, p)) }),
|
|
743
|
+
hasChanges && /* @__PURE__ */ jsxs("span", { className: "badge badge-attention", children: [
|
|
744
|
+
"\u21BB ",
|
|
745
|
+
t("issue.submitWithChanges")
|
|
746
|
+
] }),
|
|
747
|
+
/* @__PURE__ */ jsxs(
|
|
748
|
+
"button",
|
|
749
|
+
{
|
|
750
|
+
type: "button",
|
|
751
|
+
className: "btn btn-primary btn-sm ml-auto",
|
|
752
|
+
onClick: () => {
|
|
753
|
+
setBody("");
|
|
754
|
+
setComposerOpen(false);
|
|
755
|
+
},
|
|
756
|
+
disabled: !body.trim(),
|
|
757
|
+
children: [
|
|
758
|
+
/* @__PURE__ */ jsx(Send, { size: 12 }),
|
|
759
|
+
" ",
|
|
760
|
+
t("common.submit")
|
|
761
|
+
]
|
|
762
|
+
}
|
|
763
|
+
)
|
|
764
|
+
] })
|
|
765
|
+
] })
|
|
766
|
+
}
|
|
767
|
+
)
|
|
768
|
+
]
|
|
769
|
+
}
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
function SidebarField({ label, children }) {
|
|
773
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
774
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: label }),
|
|
775
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1", children })
|
|
776
|
+
] });
|
|
777
|
+
}
|
|
778
|
+
function PillPicker({
|
|
779
|
+
label,
|
|
780
|
+
value,
|
|
781
|
+
changed,
|
|
782
|
+
children
|
|
783
|
+
}) {
|
|
784
|
+
return /* @__PURE__ */ jsxs(Popover.Root, { children: [
|
|
785
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
786
|
+
"button",
|
|
787
|
+
{
|
|
788
|
+
type: "button",
|
|
789
|
+
className: cn(
|
|
790
|
+
"chip text-xs cursor-pointer",
|
|
791
|
+
changed && "border border-[var(--attention)] text-[var(--attention)]"
|
|
792
|
+
),
|
|
793
|
+
children: [
|
|
794
|
+
label,
|
|
795
|
+
": ",
|
|
796
|
+
value
|
|
797
|
+
]
|
|
798
|
+
}
|
|
799
|
+
) }),
|
|
800
|
+
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Content, { className: "sw-pop", align: "start", sideOffset: 4, style: { width: 200 }, children: /* @__PURE__ */ jsx("div", { className: "sw-pop-list", children }) }) })
|
|
801
|
+
] });
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
export { DashboardScreen, IdeasScreen, IssueDetailScreen, IssuesScreen, PlanDetailScreen, PlansScreen, ProjectsListScreen, WikiScreen };
|
|
805
|
+
//# sourceMappingURL=screens.js.map
|
|
806
|
+
//# sourceMappingURL=screens.js.map
|