@stigmer/react 0.0.89 → 0.0.91
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/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -1
- package/identity-provider/CreateIdentityProviderForm.js +60 -2
- package/identity-provider/CreateIdentityProviderForm.js.map +1 -1
- package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
- package/identity-provider/IdentityProviderDetailPanel.js +87 -4
- package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
- package/identity-provider/IdentityProviderListPanel.js +5 -3
- package/identity-provider/IdentityProviderListPanel.js.map +1 -1
- package/identity-provider/IdentityProviderWizard.d.ts.map +1 -1
- package/identity-provider/IdentityProviderWizard.js +59 -4
- package/identity-provider/IdentityProviderWizard.js.map +1 -1
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -1
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/package.json +7 -7
- package/platform-client/CreatePlatformClientForm.d.ts +42 -0
- package/platform-client/CreatePlatformClientForm.d.ts.map +1 -0
- package/platform-client/CreatePlatformClientForm.js +148 -0
- package/platform-client/CreatePlatformClientForm.js.map +1 -0
- package/platform-client/PlatformClientDetailPanel.d.ts +51 -0
- package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -0
- package/platform-client/PlatformClientDetailPanel.js +247 -0
- package/platform-client/PlatformClientDetailPanel.js.map +1 -0
- package/platform-client/PlatformClientListPanel.d.ts +41 -0
- package/platform-client/PlatformClientListPanel.d.ts.map +1 -0
- package/platform-client/PlatformClientListPanel.js +123 -0
- package/platform-client/PlatformClientListPanel.js.map +1 -0
- package/platform-client/PlatformClientSecretAlert.d.ts +39 -0
- package/platform-client/PlatformClientSecretAlert.d.ts.map +1 -0
- package/platform-client/PlatformClientSecretAlert.js +74 -0
- package/platform-client/PlatformClientSecretAlert.js.map +1 -0
- package/platform-client/index.d.ts +11 -0
- package/platform-client/index.d.ts.map +1 -0
- package/platform-client/index.js +11 -0
- package/platform-client/index.js.map +1 -0
- package/platform-client/useCreatePlatformClient.d.ts +42 -0
- package/platform-client/useCreatePlatformClient.d.ts.map +1 -0
- package/platform-client/useCreatePlatformClient.js +49 -0
- package/platform-client/useCreatePlatformClient.js.map +1 -0
- package/platform-client/useDeletePlatformClient.d.ts +31 -0
- package/platform-client/useDeletePlatformClient.d.ts.map +1 -0
- package/platform-client/useDeletePlatformClient.js +42 -0
- package/platform-client/useDeletePlatformClient.js.map +1 -0
- package/platform-client/usePlatformClient.d.ts +37 -0
- package/platform-client/usePlatformClient.d.ts.map +1 -0
- package/platform-client/usePlatformClient.js +62 -0
- package/platform-client/usePlatformClient.js.map +1 -0
- package/platform-client/usePlatformClientList.d.ts +42 -0
- package/platform-client/usePlatformClientList.d.ts.map +1 -0
- package/platform-client/usePlatformClientList.js +71 -0
- package/platform-client/usePlatformClientList.js.map +1 -0
- package/platform-client/useRotatePlatformClientSecret.d.ts +35 -0
- package/platform-client/useRotatePlatformClientSecret.d.ts.map +1 -0
- package/platform-client/useRotatePlatformClientSecret.js +43 -0
- package/platform-client/useRotatePlatformClientSecret.js.map +1 -0
- package/platform-client/useUpdatePlatformClient.d.ts +39 -0
- package/platform-client/useUpdatePlatformClient.d.ts.map +1 -0
- package/platform-client/useUpdatePlatformClient.js +50 -0
- package/platform-client/useUpdatePlatformClient.js.map +1 -0
- package/src/identity-provider/CreateIdentityProviderForm.tsx +220 -0
- package/src/identity-provider/IdentityProviderDetailPanel.tsx +288 -6
- package/src/identity-provider/IdentityProviderListPanel.tsx +9 -2
- package/src/identity-provider/IdentityProviderWizard.tsx +231 -25
- package/src/index.ts +26 -0
- package/src/platform-client/CreatePlatformClientForm.tsx +519 -0
- package/src/platform-client/PlatformClientDetailPanel.tsx +898 -0
- package/src/platform-client/PlatformClientListPanel.tsx +413 -0
- package/src/platform-client/PlatformClientSecretAlert.tsx +252 -0
- package/src/platform-client/index.ts +49 -0
- package/src/platform-client/useCreatePlatformClient.ts +77 -0
- package/src/platform-client/useDeletePlatformClient.ts +64 -0
- package/src/platform-client/usePlatformClient.ts +86 -0
- package/src/platform-client/usePlatformClientList.ts +96 -0
- package/src/platform-client/useRotatePlatformClientSecret.ts +68 -0
- package/src/platform-client/useUpdatePlatformClient.ts +70 -0
- package/src/test/index.ts +6 -0
- package/src/{demo → test}/samples.ts +1 -1
- package/styles.css +1 -1
- package/test/__tests__/samples.test.d.ts.map +1 -0
- package/{demo → test}/__tests__/samples.test.js.map +1 -1
- package/test/index.d.ts +2 -0
- package/test/index.d.ts.map +1 -0
- package/test/index.js +6 -0
- package/test/index.js.map +1 -0
- package/{demo → test}/samples.d.ts +1 -1
- package/{demo → test}/samples.d.ts.map +1 -1
- package/{demo → test}/samples.js +1 -1
- package/{demo → test}/samples.js.map +1 -1
- package/demo/__tests__/demo-client.test.d.ts +0 -2
- package/demo/__tests__/demo-client.test.d.ts.map +0 -1
- package/demo/__tests__/demo-client.test.js +0 -133
- package/demo/__tests__/demo-client.test.js.map +0 -1
- package/demo/__tests__/fixtures.test.d.ts +0 -2
- package/demo/__tests__/fixtures.test.d.ts.map +0 -1
- package/demo/__tests__/fixtures.test.js +0 -135
- package/demo/__tests__/fixtures.test.js.map +0 -1
- package/demo/__tests__/samples.test.d.ts.map +0 -1
- package/demo/client.d.ts +0 -29
- package/demo/client.d.ts.map +0 -1
- package/demo/client.js +0 -52
- package/demo/client.js.map +0 -1
- package/demo/fixtures.d.ts +0 -194
- package/demo/fixtures.d.ts.map +0 -1
- package/demo/fixtures.js +0 -267
- package/demo/fixtures.js.map +0 -1
- package/demo/index.d.ts +0 -6
- package/demo/index.d.ts.map +0 -1
- package/demo/index.js +0 -6
- package/demo/index.js.map +0 -1
- package/demo/transport.d.ts +0 -59
- package/demo/transport.d.ts.map +0 -1
- package/demo/transport.js +0 -75
- package/demo/transport.js.map +0 -1
- package/demo/types.d.ts +0 -62
- package/demo/types.d.ts.map +0 -1
- package/demo/types.js +0 -16
- package/demo/types.js.map +0 -1
- package/src/demo/__tests__/demo-client.test.tsx +0 -213
- package/src/demo/__tests__/fixtures.test.ts +0 -214
- package/src/demo/client.ts +0 -78
- package/src/demo/fixtures.ts +0 -409
- package/src/demo/index.ts +0 -12
- package/src/demo/transport.ts +0 -116
- package/src/demo/types.ts +0 -69
- /package/src/{demo → test}/__tests__/samples.test.ts +0 -0
- /package/{demo → test}/__tests__/samples.test.d.ts +0 -0
- /package/{demo → test}/__tests__/samples.test.js +0 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useState, } from "react";
|
|
4
|
+
import { cn } from "@stigmer/theme";
|
|
5
|
+
import { getUserMessage } from "@stigmer/sdk";
|
|
6
|
+
import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
7
|
+
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
8
|
+
import { useUpdatePlatformClient } from "./useUpdatePlatformClient";
|
|
9
|
+
import { useRotatePlatformClientSecret } from "./useRotatePlatformClientSecret";
|
|
10
|
+
import { useDeletePlatformClient } from "./useDeletePlatformClient";
|
|
11
|
+
/**
|
|
12
|
+
* View and edit panel for an existing platform client.
|
|
13
|
+
*
|
|
14
|
+
* In **view mode**, displays all configuration fields in a structured
|
|
15
|
+
* label/value layout with "Edit", "Rotate Secret", and "Delete"
|
|
16
|
+
* actions.
|
|
17
|
+
*
|
|
18
|
+
* In **edit mode**, mutable spec fields become editable: JIT
|
|
19
|
+
* provisioning toggles, expiry, auto-grant role, and allowed
|
|
20
|
+
* origins. Credential fields (`clientId`, `secretFingerprint`) are
|
|
21
|
+
* read-only. "Save" submits the update; "Cancel" discards changes.
|
|
22
|
+
*
|
|
23
|
+
* Secret rotation triggers `onSecretRotated` with the full
|
|
24
|
+
* {@link PlatformClientCreateResponse} so the parent can show the
|
|
25
|
+
* one-time secret alert.
|
|
26
|
+
*
|
|
27
|
+
* All visual properties flow through `--stgm-*` design tokens.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <PlatformClientDetailPanel
|
|
32
|
+
* platformClient={pc}
|
|
33
|
+
* onUpdated={(updated) => refetch()}
|
|
34
|
+
* onSecretRotated={(resp) => setFlow({ phase: "revealing", resp })}
|
|
35
|
+
* onDeleted={() => setFlow({ phase: "idle" })}
|
|
36
|
+
* onBack={() => setFlow({ phase: "idle" })}
|
|
37
|
+
* />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function PlatformClientDetailPanel({ platformClient, onUpdated, onSecretRotated, onDeleted, onBack, className, }) {
|
|
41
|
+
const spec = platformClient.spec;
|
|
42
|
+
const meta = platformClient.metadata;
|
|
43
|
+
const { update, isUpdating, error: updateError, clearError: clearUpdateError } = useUpdatePlatformClient();
|
|
44
|
+
const { rotateSecret, isRotating, error: rotateError, clearError: clearRotateError } = useRotatePlatformClientSecret();
|
|
45
|
+
const { deletePlatformClient, isDeleting, error: deleteError } = useDeletePlatformClient();
|
|
46
|
+
const [mode, setMode] = useState("view");
|
|
47
|
+
const [confirmingDelete, setConfirmingDelete] = useState(false);
|
|
48
|
+
const [confirmingRotate, setConfirmingRotate] = useState(false);
|
|
49
|
+
const isBusy = isUpdating || isRotating || isDeleting;
|
|
50
|
+
// Edit form state
|
|
51
|
+
const [neverExpires, setNeverExpires] = useState(spec?.neverExpires ?? true);
|
|
52
|
+
const [expiresAt, setExpiresAt] = useState(() => {
|
|
53
|
+
if (spec?.expiresAt) {
|
|
54
|
+
return toDatetimeLocalValue(timestampDate(spec.expiresAt));
|
|
55
|
+
}
|
|
56
|
+
return "";
|
|
57
|
+
});
|
|
58
|
+
const [autoProvision, setAutoProvision] = useState(spec?.autoProvisionAccounts ?? false);
|
|
59
|
+
const [autoGrant, setAutoGrant] = useState(spec?.autoGrantOnOrg ?? false);
|
|
60
|
+
const [autoGrantRole, setAutoGrantRole] = useState(spec?.autoGrantRole ?? IamRole.iam_role_unspecified);
|
|
61
|
+
const [origins, setOrigins] = useState([...(spec?.allowedOrigins ?? [])]);
|
|
62
|
+
const [originInput, setOriginInput] = useState("");
|
|
63
|
+
const handleAutoProvisionChange = useCallback((v) => {
|
|
64
|
+
setAutoProvision(v);
|
|
65
|
+
if (!v) {
|
|
66
|
+
setAutoGrant(false);
|
|
67
|
+
setAutoGrantRole(IamRole.iam_role_unspecified);
|
|
68
|
+
}
|
|
69
|
+
}, []);
|
|
70
|
+
const handleAutoGrantChange = useCallback((v) => {
|
|
71
|
+
setAutoGrant(v);
|
|
72
|
+
if (v)
|
|
73
|
+
setAutoProvision(true);
|
|
74
|
+
if (!v)
|
|
75
|
+
setAutoGrantRole(IamRole.iam_role_unspecified);
|
|
76
|
+
}, []);
|
|
77
|
+
const addOrigin = useCallback(() => {
|
|
78
|
+
const trimmed = originInput.trim();
|
|
79
|
+
if (trimmed && !origins.includes(trimmed)) {
|
|
80
|
+
setOrigins((prev) => [...prev, trimmed]);
|
|
81
|
+
}
|
|
82
|
+
setOriginInput("");
|
|
83
|
+
}, [originInput, origins]);
|
|
84
|
+
const handleOriginKeyDown = useCallback((e) => {
|
|
85
|
+
if (e.key === "Enter") {
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
addOrigin();
|
|
88
|
+
}
|
|
89
|
+
}, [addOrigin]);
|
|
90
|
+
const removeOrigin = useCallback((origin) => {
|
|
91
|
+
setOrigins((prev) => prev.filter((o) => o !== origin));
|
|
92
|
+
}, []);
|
|
93
|
+
const enterEdit = useCallback(() => {
|
|
94
|
+
setNeverExpires(spec?.neverExpires ?? true);
|
|
95
|
+
setExpiresAt(spec?.expiresAt
|
|
96
|
+
? toDatetimeLocalValue(timestampDate(spec.expiresAt))
|
|
97
|
+
: "");
|
|
98
|
+
setAutoProvision(spec?.autoProvisionAccounts ?? false);
|
|
99
|
+
setAutoGrant(spec?.autoGrantOnOrg ?? false);
|
|
100
|
+
setAutoGrantRole(spec?.autoGrantRole ?? IamRole.iam_role_unspecified);
|
|
101
|
+
setOrigins([...(spec?.allowedOrigins ?? [])]);
|
|
102
|
+
setOriginInput("");
|
|
103
|
+
clearUpdateError();
|
|
104
|
+
setMode("edit");
|
|
105
|
+
}, [spec, clearUpdateError]);
|
|
106
|
+
const cancelEdit = useCallback(() => {
|
|
107
|
+
clearUpdateError();
|
|
108
|
+
setMode("view");
|
|
109
|
+
}, [clearUpdateError]);
|
|
110
|
+
const handleSave = useCallback(async (e) => {
|
|
111
|
+
e.preventDefault();
|
|
112
|
+
clearUpdateError();
|
|
113
|
+
try {
|
|
114
|
+
const updated = await update({
|
|
115
|
+
name: meta?.name ?? "",
|
|
116
|
+
slug: meta?.slug,
|
|
117
|
+
org: meta?.org ?? "",
|
|
118
|
+
neverExpires,
|
|
119
|
+
...(!neverExpires &&
|
|
120
|
+
expiresAt && {
|
|
121
|
+
expiresAt: new Date(expiresAt).toISOString(),
|
|
122
|
+
}),
|
|
123
|
+
autoProvisionAccounts: autoProvision,
|
|
124
|
+
autoGrantOnOrg: autoGrant,
|
|
125
|
+
...(autoGrant &&
|
|
126
|
+
autoGrantRole !== IamRole.iam_role_unspecified && {
|
|
127
|
+
autoGrantRole,
|
|
128
|
+
}),
|
|
129
|
+
allowedOrigins: origins,
|
|
130
|
+
});
|
|
131
|
+
setMode("view");
|
|
132
|
+
onUpdated?.(updated);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// error state is managed by useUpdatePlatformClient
|
|
136
|
+
}
|
|
137
|
+
}, [
|
|
138
|
+
meta,
|
|
139
|
+
neverExpires,
|
|
140
|
+
expiresAt,
|
|
141
|
+
autoProvision,
|
|
142
|
+
autoGrant,
|
|
143
|
+
autoGrantRole,
|
|
144
|
+
origins,
|
|
145
|
+
update,
|
|
146
|
+
clearUpdateError,
|
|
147
|
+
onUpdated,
|
|
148
|
+
]);
|
|
149
|
+
const handleRotateSecret = useCallback(async () => {
|
|
150
|
+
clearRotateError();
|
|
151
|
+
try {
|
|
152
|
+
const response = await rotateSecret(meta?.id ?? "");
|
|
153
|
+
setConfirmingRotate(false);
|
|
154
|
+
onSecretRotated?.(response);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// error state is managed by the hook
|
|
158
|
+
}
|
|
159
|
+
}, [meta?.id, rotateSecret, clearRotateError, onSecretRotated]);
|
|
160
|
+
const handleDelete = useCallback(async () => {
|
|
161
|
+
try {
|
|
162
|
+
await deletePlatformClient({ resourceId: meta?.id ?? "" });
|
|
163
|
+
onDeleted?.();
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// error state is surfaced via the hook
|
|
167
|
+
}
|
|
168
|
+
}, [meta?.id, deletePlatformClient, onDeleted]);
|
|
169
|
+
const createdAt = platformClient.status?.audit?.specAudit?.createdAt;
|
|
170
|
+
const updatedAt = platformClient.status?.audit?.specAudit?.updatedAt;
|
|
171
|
+
return (_jsxs("div", { className: cn("space-y-4", className), children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [onBack && (_jsxs("button", { type: "button", onClick: onBack, className: "text-muted-foreground hover:text-foreground mb-1 flex items-center gap-1 text-xs transition-colors", children: [_jsx(ArrowLeftIcon, {}), "Back to list"] })), _jsx("h3", { className: "text-foreground truncate text-sm font-semibold", children: meta?.name ?? "Platform Client" }), _jsxs("div", { className: "flex items-center gap-2", children: [meta?.slug && (_jsx("span", { className: "text-muted-foreground font-mono text-xs", children: meta.slug })), spec?.autoProvisionAccounts && (_jsx("span", { className: "inline-flex items-center rounded-full border border-primary/30 bg-primary-subtle px-2 py-0.5 text-[0.65rem] font-medium text-primary", children: "JIT" }))] })] }), mode === "view" && (_jsx("button", { type: "button", onClick: enterEdit, className: cn("shrink-0 rounded-md px-2.5 py-1.5 text-xs font-medium", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "transition-colors"), children: "Edit" }))] }), mode === "view" ? (_jsx(ViewMode, { spec: spec, createdAt: createdAt, updatedAt: updatedAt })) : (_jsxs("form", { onSubmit: handleSave, className: "space-y-3", children: [_jsxs("div", { className: "rounded-md border border-border/60 bg-muted/30 px-3 py-2 space-y-1", children: [_jsx("p", { className: "text-[0.65rem] font-medium text-muted-foreground", children: "Client ID" }), _jsx("p", { className: "font-mono text-xs text-foreground", children: spec?.clientId ?? "—" })] }), _jsxs("fieldset", { className: "space-y-2", disabled: isUpdating, children: [_jsx("legend", { className: "text-xs font-medium text-foreground", children: "Expiry" }), _jsx(ToggleSwitch, { checked: neverExpires, onChange: setNeverExpires, label: "Never expires", disabled: isUpdating }), !neverExpires && (_jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-pc-edit-expires-at", className: "text-xs font-medium text-foreground", children: "Expires at" }), _jsx("input", { id: "stgm-pc-edit-expires-at", type: "datetime-local", value: expiresAt, onChange: (e) => setExpiresAt(e.target.value), disabled: isUpdating, className: cn("w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50") })] }))] }), _jsxs("fieldset", { className: "space-y-2.5", disabled: isUpdating, children: [_jsx("hr", { className: "border-border/40" }), _jsx("legend", { className: "text-xs font-medium text-foreground", children: "JIT provisioning" }), _jsx(ToggleSwitch, { checked: autoProvision, onChange: handleAutoProvisionChange, label: "Auto-provision accounts", hint: "Create a Stigmer identity account automatically on first token mint", disabled: isUpdating }), _jsx(ToggleSwitch, { checked: autoGrant, onChange: handleAutoGrantChange, label: "Auto-grant on organization", hint: "Grant a role on the owning organization when an account is provisioned", disabled: isUpdating || !autoProvision }), autoGrant && (_jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-pc-edit-grant-role", className: "text-xs font-medium text-foreground", children: "Auto-grant role" }), _jsx("select", { id: "stgm-pc-edit-grant-role", value: String(autoGrantRole), onChange: (e) => setAutoGrantRole(Number(e.target.value)), disabled: isUpdating, className: cn("w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50"), children: JIT_ROLE_OPTIONS.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })] }))] }), _jsxs("fieldset", { className: "space-y-2", disabled: isUpdating, children: [_jsx("hr", { className: "border-border/40" }), _jsx("legend", { className: "text-xs font-medium text-foreground", children: "Allowed origins" }), _jsx("p", { className: "text-[0.65rem] text-muted-foreground", children: "Browser origins permitted to use tokens minted by this client. Leave empty to allow all origins." }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: originInput, onChange: (e) => setOriginInput(e.target.value), onKeyDown: handleOriginKeyDown, onBlur: () => {
|
|
172
|
+
if (originInput.trim())
|
|
173
|
+
addOrigin();
|
|
174
|
+
}, placeholder: "https://example.com", disabled: isUpdating, className: cn("min-w-0 flex-1 rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground", "placeholder:text-muted-foreground", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50") }), _jsx("button", { type: "button", onClick: addOrigin, disabled: isUpdating || !originInput.trim(), className: cn("shrink-0 rounded-md px-2.5 py-1.5 text-xs font-medium", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50", "transition-colors"), children: "Add" })] }), origins.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5", children: origins.map((origin) => (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-border/60 bg-muted/40 px-2 py-0.5 text-[0.65rem] font-mono text-foreground", children: [origin, _jsx("button", { type: "button", onClick: () => removeOrigin(origin), disabled: isUpdating, "aria-label": `Remove ${origin}`, className: "text-muted-foreground hover:text-destructive transition-colors", children: _jsx(XIcon, {}) })] }, origin))) }))] }), updateError && (_jsx("p", { className: "text-destructive text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("div", { className: "flex items-center gap-2 pt-1", children: [_jsxs("button", { type: "submit", disabled: isUpdating, className: cn("inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium", "bg-primary text-primary-foreground hover:bg-primary/90", "disabled:pointer-events-none disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, {}), "Save changes"] }), _jsx("button", { type: "button", onClick: cancelEdit, disabled: isUpdating, className: cn("rounded-md px-2.5 py-1.5 text-xs", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] })), mode === "view" && (_jsxs("div", { className: "space-y-2 pt-2", children: [_jsx("hr", { className: "border-border/40" }), confirmingRotate ? (_jsxs("div", { className: "flex items-center justify-between rounded-md border border-warning/30 bg-warning/5 px-3 py-2", children: [_jsxs("p", { className: "text-xs text-foreground", children: ["Rotate secret? The current secret will be", _jsx("span", { className: "font-medium", children: " permanently invalidated" }), "."] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsxs("button", { type: "button", onClick: handleRotateSecret, disabled: isBusy, className: cn("inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium", "bg-primary text-primary-foreground hover:bg-primary/90", "disabled:pointer-events-none disabled:opacity-50"), children: [isRotating && _jsx(SpinnerIcon, {}), "Rotate"] }), _jsx("button", { type: "button", onClick: () => {
|
|
175
|
+
setConfirmingRotate(false);
|
|
176
|
+
clearRotateError();
|
|
177
|
+
}, disabled: isBusy, className: cn("rounded-md px-2.5 py-1 text-xs", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] })) : (_jsx("button", { type: "button", onClick: () => setConfirmingRotate(true), disabled: isBusy, className: cn("rounded-md px-2.5 py-1.5 text-xs font-medium", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50", "transition-colors"), children: "Rotate secret" })), rotateError && (_jsx("p", { className: "text-destructive text-[0.65rem]", role: "alert", children: getUserMessage(rotateError) })), confirmingDelete ? (_jsxs("div", { className: "flex items-center justify-between rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("p", { className: "text-xs text-foreground", children: ["Delete", " ", _jsx("span", { className: "font-medium", children: meta?.name }), "? This action is permanent."] }), deleteError && (_jsx("p", { className: "mt-0.5 text-[0.65rem] text-destructive", children: getUserMessage(deleteError) }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsxs("button", { type: "button", onClick: handleDelete, disabled: isBusy, className: cn("inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium", "bg-destructive text-destructive-foreground hover:bg-destructive/90", "disabled:pointer-events-none disabled:opacity-50"), children: [isDeleting && _jsx(SpinnerIcon, {}), "Delete"] }), _jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), disabled: isBusy, className: cn("rounded-md px-2.5 py-1 text-xs", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] })) : (_jsx("button", { type: "button", onClick: () => setConfirmingDelete(true), disabled: isBusy, className: cn("rounded-md px-2.5 py-1.5 text-xs font-medium", "text-destructive hover:text-destructive-foreground hover:bg-destructive/90", "disabled:pointer-events-none disabled:opacity-50", "transition-colors"), children: "Delete platform client" }))] }))] }));
|
|
178
|
+
}
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// View mode
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
function ViewMode({ spec, createdAt, updatedAt, }) {
|
|
183
|
+
return (_jsxs("dl", { className: "space-y-2.5", children: [_jsx(Field, { label: "Client ID", value: spec?.clientId, mono: true }), _jsx(Field, { label: "Secret fingerprint", value: spec?.secretFingerprint
|
|
184
|
+
? `••••${spec.secretFingerprint.slice(-4)}`
|
|
185
|
+
: undefined, mono: true }), spec?.neverExpires ? (_jsx(Field, { label: "Expiry", value: "Never expires" })) : spec?.expiresAt ? (_jsx(Field, { label: "Expires", value: formatDate(timestampDate(spec.expiresAt)) })) : null, _jsx("hr", { className: "border-border/40" }), _jsx(Field, { label: "Auto-provision accounts", value: spec?.autoProvisionAccounts ? "Enabled" : "Disabled" }), _jsx(Field, { label: "Auto-grant on organization", value: spec?.autoGrantOnOrg ? "Enabled" : "Disabled" }), spec?.autoGrantOnOrg && (_jsx(Field, { label: "Auto-grant role", value: formatIamRole(spec.autoGrantRole) })), (spec?.allowedOrigins.length ?? 0) > 0 && (_jsxs(_Fragment, { children: [_jsx("hr", { className: "border-border/40" }), _jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground text-[0.65rem] font-medium", children: "Allowed origins" }), _jsx("dd", { className: "mt-0.5 flex flex-wrap gap-1.5", children: spec.allowedOrigins.map((origin) => (_jsx("span", { className: "inline-block rounded-full border border-border/60 bg-muted/40 px-2 py-0.5 text-[0.65rem] font-mono text-foreground", children: origin }, origin))) })] })] })), _jsxs("div", { className: "flex gap-6", children: [createdAt && (_jsx(Field, { label: "Created", value: formatDate(timestampDate(createdAt)) })), updatedAt && (_jsx(Field, { label: "Updated", value: formatDate(timestampDate(updatedAt)) }))] })] }));
|
|
186
|
+
}
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
// Shared primitives
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
function Field({ label, value, mono, }) {
|
|
191
|
+
if (!value)
|
|
192
|
+
return null;
|
|
193
|
+
return (_jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground text-[0.65rem] font-medium", children: label }), _jsx("dd", { className: cn("text-foreground mt-0.5 break-all text-xs", mono && "font-mono"), children: value })] }));
|
|
194
|
+
}
|
|
195
|
+
function ToggleSwitch({ checked, onChange, label, hint, disabled, }) {
|
|
196
|
+
return (_jsxs("div", { className: "space-y-0.5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", role: "switch", "aria-checked": checked, onClick: () => onChange(!checked), disabled: disabled, className: cn("relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors", checked ? "bg-primary" : "bg-muted", "disabled:pointer-events-none disabled:opacity-50"), children: _jsx("span", { className: cn("pointer-events-none inline-block h-4 w-4 rounded-full bg-background shadow-sm ring-0 transition-transform", checked ? "translate-x-4" : "translate-x-0") }) }), _jsx("span", { className: "text-xs font-medium text-foreground", children: label })] }), hint && (_jsx("p", { className: "pl-11 text-[0.65rem] text-muted-foreground", children: hint }))] }));
|
|
197
|
+
}
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// Constants
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
const JIT_ROLE_OPTIONS = [
|
|
202
|
+
{ value: String(IamRole.iam_role_unspecified), label: "Default (viewer)" },
|
|
203
|
+
{ value: String(IamRole.viewer), label: "Viewer" },
|
|
204
|
+
{ value: String(IamRole.member), label: "Member" },
|
|
205
|
+
{ value: String(IamRole.admin), label: "Admin" },
|
|
206
|
+
];
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Helpers
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
function formatIamRole(role) {
|
|
211
|
+
switch (role) {
|
|
212
|
+
case IamRole.viewer:
|
|
213
|
+
return "Viewer";
|
|
214
|
+
case IamRole.member:
|
|
215
|
+
return "Member";
|
|
216
|
+
case IamRole.admin:
|
|
217
|
+
return "Admin";
|
|
218
|
+
case IamRole.owner:
|
|
219
|
+
return "Owner";
|
|
220
|
+
default:
|
|
221
|
+
return "Viewer (default)";
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function formatDate(date) {
|
|
225
|
+
return date.toLocaleDateString(undefined, {
|
|
226
|
+
month: "short",
|
|
227
|
+
day: "numeric",
|
|
228
|
+
year: "numeric",
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
function toDatetimeLocalValue(date) {
|
|
232
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
233
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
234
|
+
}
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
236
|
+
// Icons
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
function XIcon() {
|
|
239
|
+
return (_jsx("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": "true", children: _jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) }));
|
|
240
|
+
}
|
|
241
|
+
function ArrowLeftIcon() {
|
|
242
|
+
return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M10 3L5 8l5 5" }) }));
|
|
243
|
+
}
|
|
244
|
+
function SpinnerIcon() {
|
|
245
|
+
return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M8 2a6 6 0 1 0 6 6" }) }));
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=PlatformClientDetailPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlatformClientDetailPanel.js","sourceRoot":"","sources":["../../src/platform-client/PlatformClientDetailPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { PlatformClient } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
|
|
2
|
+
/** Props for {@link PlatformClientListPanel}. */
|
|
3
|
+
export interface PlatformClientListPanelProps {
|
|
4
|
+
/** Organization slug whose platform clients should be listed. */
|
|
5
|
+
readonly org: string;
|
|
6
|
+
/** Fired when the user wants to edit a platform client. */
|
|
7
|
+
readonly onEdit?: (pc: PlatformClient) => void;
|
|
8
|
+
/** Expose the refetch function so parents can trigger a list refresh. */
|
|
9
|
+
readonly onRefetchRef?: (refetch: () => void) => void;
|
|
10
|
+
/** Additional CSS class names for the root container. */
|
|
11
|
+
readonly className?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Displays a list of {@link PlatformClient} resources for an
|
|
15
|
+
* organization with inline delete confirmation.
|
|
16
|
+
*
|
|
17
|
+
* Each row shows the client name, `client_id` (monospace), secret
|
|
18
|
+
* fingerprint, expiry status, and creation date. A delete button
|
|
19
|
+
* triggers an inline confirmation flow.
|
|
20
|
+
*
|
|
21
|
+
* Platform clients are admin-level resources with small cardinality
|
|
22
|
+
* (typically 1–5 per org), so the list is rendered without pagination.
|
|
23
|
+
*
|
|
24
|
+
* All visual properties flow through `--stgm-*` design tokens.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <PlatformClientListPanel org="acme" />
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <PlatformClientListPanel
|
|
34
|
+
* org="acme"
|
|
35
|
+
* onEdit={(pc) => setFlow({ phase: "editing", platformClient: pc })}
|
|
36
|
+
* onRefetchRef={(refetch) => { listRefetchRef.current = refetch; }}
|
|
37
|
+
* />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function PlatformClientListPanel({ org, onEdit, onRefetchRef, className, }: PlatformClientListPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
//# sourceMappingURL=PlatformClientListPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlatformClientListPanel.d.ts","sourceRoot":"","sources":["../../src/platform-client/PlatformClientListPanel.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yDAAyD,CAAC;AAI9F,iDAAiD;AACjD,MAAM,WAAW,4BAA4B;IAC3C,iEAAiE;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C,yEAAyE;IACzE,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACtD,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,GAAG,EACH,MAAM,EACN,YAAY,EACZ,SAAS,GACV,EAAE,4BAA4B,2CAwE9B"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useState } from "react";
|
|
4
|
+
import { cn } from "@stigmer/theme";
|
|
5
|
+
import { getUserMessage } from "@stigmer/sdk";
|
|
6
|
+
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
7
|
+
import { usePlatformClientList } from "./usePlatformClientList";
|
|
8
|
+
import { useDeletePlatformClient } from "./useDeletePlatformClient";
|
|
9
|
+
/**
|
|
10
|
+
* Displays a list of {@link PlatformClient} resources for an
|
|
11
|
+
* organization with inline delete confirmation.
|
|
12
|
+
*
|
|
13
|
+
* Each row shows the client name, `client_id` (monospace), secret
|
|
14
|
+
* fingerprint, expiry status, and creation date. A delete button
|
|
15
|
+
* triggers an inline confirmation flow.
|
|
16
|
+
*
|
|
17
|
+
* Platform clients are admin-level resources with small cardinality
|
|
18
|
+
* (typically 1–5 per org), so the list is rendered without pagination.
|
|
19
|
+
*
|
|
20
|
+
* All visual properties flow through `--stgm-*` design tokens.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <PlatformClientListPanel org="acme" />
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* <PlatformClientListPanel
|
|
30
|
+
* org="acme"
|
|
31
|
+
* onEdit={(pc) => setFlow({ phase: "editing", platformClient: pc })}
|
|
32
|
+
* onRefetchRef={(refetch) => { listRefetchRef.current = refetch; }}
|
|
33
|
+
* />
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function PlatformClientListPanel({ org, onEdit, onRefetchRef, className, }) {
|
|
37
|
+
const { platformClients, isLoading, error, refetch } = usePlatformClientList(org);
|
|
38
|
+
const [confirmingId, setConfirmingId] = useState(null);
|
|
39
|
+
if (onRefetchRef) {
|
|
40
|
+
onRefetchRef(refetch);
|
|
41
|
+
}
|
|
42
|
+
if (isLoading) {
|
|
43
|
+
return (_jsx("div", { className: cn("space-y-2", className), "aria-busy": "true", "aria-label": "Loading platform clients", children: Array.from({ length: 2 }, (_, i) => (_jsx("div", { className: "bg-muted/40 h-14 animate-pulse rounded-lg" }, i))) }));
|
|
44
|
+
}
|
|
45
|
+
if (error) {
|
|
46
|
+
return (_jsx("p", { className: cn("text-destructive text-xs", className), role: "alert", children: getUserMessage(error) }));
|
|
47
|
+
}
|
|
48
|
+
if (platformClients.length === 0) {
|
|
49
|
+
return (_jsx("p", { className: cn("text-muted-foreground py-4 text-center text-xs", className), children: "No platform clients configured." }));
|
|
50
|
+
}
|
|
51
|
+
return (_jsx("div", { className: cn("space-y-2", className), role: "list", "aria-label": "Platform clients", children: platformClients.map((pc) => {
|
|
52
|
+
const id = pc.metadata?.id ?? "";
|
|
53
|
+
return (_jsx(PlatformClientRow, { platformClient: pc, isConfirming: confirmingId === id, onEdit: onEdit ? () => onEdit(pc) : undefined, onConfirmDelete: () => setConfirmingId(id), onCancelDelete: () => setConfirmingId(null), onDeleted: () => {
|
|
54
|
+
setConfirmingId(null);
|
|
55
|
+
refetch();
|
|
56
|
+
} }, id));
|
|
57
|
+
}) }));
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// PlatformClientRow (internal)
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
function PlatformClientRow({ platformClient, isConfirming, onEdit, onConfirmDelete, onCancelDelete, onDeleted, }) {
|
|
63
|
+
const { deletePlatformClient, isDeleting, error } = useDeletePlatformClient();
|
|
64
|
+
const id = platformClient.metadata?.id ?? "";
|
|
65
|
+
const spec = platformClient.spec;
|
|
66
|
+
const name = platformClient.metadata?.name ?? "Unnamed client";
|
|
67
|
+
const clientId = spec?.clientId ?? "";
|
|
68
|
+
const fingerprint = spec?.secretFingerprint ?? "";
|
|
69
|
+
const createdAt = platformClient.status?.audit?.specAudit?.createdAt;
|
|
70
|
+
const handleDelete = useCallback(async () => {
|
|
71
|
+
try {
|
|
72
|
+
await deletePlatformClient({ resourceId: id });
|
|
73
|
+
onDeleted();
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// error state is surfaced via the hook
|
|
77
|
+
}
|
|
78
|
+
}, [id, deletePlatformClient, onDeleted]);
|
|
79
|
+
if (isConfirming) {
|
|
80
|
+
return (_jsxs("div", { role: "listitem", className: "flex items-center justify-between rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("p", { className: "text-xs text-foreground", children: ["Delete ", _jsx("span", { className: "font-medium", children: name }), "?", clientId && (_jsxs("span", { className: "ml-1 text-muted-foreground", children: ["This will invalidate client ID", " ", _jsx("code", { className: "font-mono", children: clientId }), "."] }))] }), error && (_jsx("p", { className: "mt-0.5 text-[0.65rem] text-destructive", children: getUserMessage(error) }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsxs("button", { type: "button", onClick: handleDelete, disabled: isDeleting, className: cn("inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium", "bg-destructive text-destructive-foreground hover:bg-destructive/90", "disabled:pointer-events-none disabled:opacity-50"), children: [isDeleting && _jsx(SpinnerIcon, {}), "Delete"] }), _jsx("button", { type: "button", onClick: onCancelDelete, disabled: isDeleting, className: cn("rounded-md px-2.5 py-1 text-xs", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] }));
|
|
81
|
+
}
|
|
82
|
+
return (_jsxs("div", { role: "listitem", className: "flex items-center gap-3 rounded-lg border border-border/60 px-3 py-2.5 hover:border-border transition-colors", children: [_jsx(KeyIcon, {}), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate text-sm font-medium text-foreground", children: name }), clientId && (_jsx("span", { className: "block truncate text-xs text-muted-foreground font-mono", children: clientId }))] }), _jsxs("div", { className: "hidden sm:flex shrink-0 items-center gap-3 text-xs text-muted-foreground", children: [fingerprint && (_jsxs("span", { className: "font-mono", title: `Secret fingerprint: ${fingerprint}`, children: ["\u2022\u2022\u2022\u2022", fingerprint.slice(-4)] })), _jsx(ExpiryBadge, { spec: spec }), spec?.autoProvisionAccounts && (_jsx("span", { className: "inline-flex items-center rounded-full border border-primary/30 bg-primary-subtle px-2 py-0.5 text-[0.65rem] font-medium text-primary", children: "JIT" })), createdAt && (_jsx("span", { title: `Created ${timestampDate(createdAt).toISOString()}`, children: formatShortDate(timestampDate(createdAt)) }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [onEdit && (_jsx("button", { type: "button", onClick: onEdit, "aria-label": `Edit ${name}`, className: cn("shrink-0 rounded p-1", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "transition-colors"), children: _jsx(PencilIcon, {}) })), _jsx("button", { type: "button", onClick: onConfirmDelete, "aria-label": `Delete ${name}`, className: cn("shrink-0 rounded p-1", "text-muted-foreground hover:text-destructive hover:bg-destructive/10", "transition-colors"), children: _jsx(TrashIcon, {}) })] })] }));
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// ExpiryBadge (internal)
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
function ExpiryBadge({ spec }) {
|
|
88
|
+
if (spec?.neverExpires) {
|
|
89
|
+
return (_jsx("span", { className: "text-[0.65rem] text-muted-foreground", children: "No expiry" }));
|
|
90
|
+
}
|
|
91
|
+
if (spec?.expiresAt) {
|
|
92
|
+
const date = timestampDate(spec.expiresAt);
|
|
93
|
+
const isExpired = date < new Date();
|
|
94
|
+
return (_jsx("span", { className: cn("text-[0.65rem]", isExpired ? "text-destructive font-medium" : "text-muted-foreground"), title: `Expires ${date.toISOString()}`, children: isExpired ? "Expired" : `Exp ${formatShortDate(date)}` }));
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Formatting helpers
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
function formatShortDate(date) {
|
|
102
|
+
return date.toLocaleDateString(undefined, {
|
|
103
|
+
month: "short",
|
|
104
|
+
day: "numeric",
|
|
105
|
+
year: "numeric",
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Icons
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
function KeyIcon() {
|
|
112
|
+
return (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", className: "shrink-0 text-muted-foreground", children: [_jsx("circle", { cx: "10.5", cy: "5.5", r: "3" }), _jsx("path", { d: "M8.5 7.5L3 13l-.5-2.5L5 10l1-1-1-1 3.5.5z" })] }));
|
|
113
|
+
}
|
|
114
|
+
function PencilIcon() {
|
|
115
|
+
return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M11 2.5l2.5 2.5L5 13.5H2.5V11L11 2.5z" }) }));
|
|
116
|
+
}
|
|
117
|
+
function TrashIcon() {
|
|
118
|
+
return (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M2.5 4h11M5.5 4V2.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1V4" }), _jsx("path", { d: "M12.5 4v9a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V4" }), _jsx("line", { x1: "6.5", y1: "7", x2: "6.5", y2: "11" }), _jsx("line", { x1: "9.5", y1: "7", x2: "9.5", y2: "11" })] }));
|
|
119
|
+
}
|
|
120
|
+
function SpinnerIcon() {
|
|
121
|
+
return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M8 2a6 6 0 1 0 6 6" }) }));
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=PlatformClientListPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlatformClientListPanel.js","sourceRoot":"","sources":["../../src/platform-client/PlatformClientListPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Props for {@link PlatformClientSecretAlert}. */
|
|
2
|
+
export interface PlatformClientSecretAlertProps {
|
|
3
|
+
/** The `client_id` to display alongside the secret for pairing context. */
|
|
4
|
+
readonly clientId: string;
|
|
5
|
+
/** The raw client secret value to display. Shown exactly once. */
|
|
6
|
+
readonly clientSecret: string;
|
|
7
|
+
/** Whether this alert follows a creation or a secret rotation. */
|
|
8
|
+
readonly context: "created" | "rotated";
|
|
9
|
+
/** Fired when the user dismisses the alert. */
|
|
10
|
+
readonly onDismiss: () => void;
|
|
11
|
+
/** Additional CSS class names for the root container. */
|
|
12
|
+
readonly className?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* One-time reveal component displayed after a platform client is
|
|
16
|
+
* created or its secret is rotated.
|
|
17
|
+
*
|
|
18
|
+
* Shows both the `client_id` (read-only, for context) and the raw
|
|
19
|
+
* `client_secret` with a **Copy** button. The secret is only
|
|
20
|
+
* available once — the server never returns it again — so this
|
|
21
|
+
* component prominently warns the user to copy it immediately.
|
|
22
|
+
*
|
|
23
|
+
* This is a standalone alert component, not a modal — the parent
|
|
24
|
+
* decides how to present and position it.
|
|
25
|
+
*
|
|
26
|
+
* All visual properties flow through `--stgm-*` design tokens.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <PlatformClientSecretAlert
|
|
31
|
+
* clientId="stgm_pc_abc123"
|
|
32
|
+
* clientSecret="stgm_secret_xyz..."
|
|
33
|
+
* context="created"
|
|
34
|
+
* onDismiss={() => setFlow({ phase: "idle" })}
|
|
35
|
+
* />
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function PlatformClientSecretAlert({ clientId, clientSecret, context, onDismiss, className, }: PlatformClientSecretAlertProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
//# sourceMappingURL=PlatformClientSecretAlert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlatformClientSecretAlert.d.ts","sourceRoot":"","sources":["../../src/platform-client/PlatformClientSecretAlert.tsx"],"names":[],"mappings":"AAKA,mDAAmD;AACnD,MAAM,WAAW,8BAA8B;IAC7C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;IACxC,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,SAAS,EACT,SAAS,GACV,EAAE,8BAA8B,2CA2FhC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useState } from "react";
|
|
4
|
+
import { cn } from "@stigmer/theme";
|
|
5
|
+
const COPIED_FEEDBACK_MS = 2000;
|
|
6
|
+
/**
|
|
7
|
+
* One-time reveal component displayed after a platform client is
|
|
8
|
+
* created or its secret is rotated.
|
|
9
|
+
*
|
|
10
|
+
* Shows both the `client_id` (read-only, for context) and the raw
|
|
11
|
+
* `client_secret` with a **Copy** button. The secret is only
|
|
12
|
+
* available once — the server never returns it again — so this
|
|
13
|
+
* component prominently warns the user to copy it immediately.
|
|
14
|
+
*
|
|
15
|
+
* This is a standalone alert component, not a modal — the parent
|
|
16
|
+
* decides how to present and position it.
|
|
17
|
+
*
|
|
18
|
+
* All visual properties flow through `--stgm-*` design tokens.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <PlatformClientSecretAlert
|
|
23
|
+
* clientId="stgm_pc_abc123"
|
|
24
|
+
* clientSecret="stgm_secret_xyz..."
|
|
25
|
+
* context="created"
|
|
26
|
+
* onDismiss={() => setFlow({ phase: "idle" })}
|
|
27
|
+
* />
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function PlatformClientSecretAlert({ clientId, clientSecret, context, onDismiss, className, }) {
|
|
31
|
+
const [copiedField, setCopiedField] = useState(null);
|
|
32
|
+
const handleCopy = useCallback(async (value, field) => {
|
|
33
|
+
try {
|
|
34
|
+
await navigator.clipboard.writeText(value);
|
|
35
|
+
setCopiedField(field);
|
|
36
|
+
setTimeout(() => setCopiedField(null), COPIED_FEEDBACK_MS);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
const el = document.getElementById(field === "secret"
|
|
40
|
+
? "stgm-pc-secret-reveal"
|
|
41
|
+
: "stgm-pc-client-id-reveal");
|
|
42
|
+
if (el) {
|
|
43
|
+
const selection = window.getSelection();
|
|
44
|
+
const range = document.createRange();
|
|
45
|
+
range.selectNodeContents(el);
|
|
46
|
+
selection?.removeAllRanges();
|
|
47
|
+
selection?.addRange(range);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, []);
|
|
51
|
+
const title = context === "created"
|
|
52
|
+
? "Platform client created"
|
|
53
|
+
: "Client secret rotated";
|
|
54
|
+
return (_jsxs("div", { role: "alert", className: cn("rounded-lg border border-primary/30 bg-primary-subtle p-4", className), children: [_jsxs("div", { className: "mb-3 flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: title }), _jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: "Copy the client secret now. It will not be shown again." })] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: cn("shrink-0 rounded p-1", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "transition-colors"), children: _jsx(CloseIcon, {}) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(CopyableField, { id: "stgm-pc-client-id-reveal", label: "Client ID", value: clientId, copied: copiedField === "id", onCopy: () => handleCopy(clientId, "id") }), _jsx(CopyableField, { id: "stgm-pc-secret-reveal", label: "Client secret", value: clientSecret, copied: copiedField === "secret", onCopy: () => handleCopy(clientSecret, "secret") })] }), _jsxs("div", { role: "status", "aria-live": "polite", "aria-atomic": "true", className: "sr-only", children: [copiedField === "id" && "Client ID copied to clipboard", copiedField === "secret" && "Client secret copied to clipboard"] })] }));
|
|
55
|
+
}
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// CopyableField (internal)
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
function CopyableField({ id, label, value, copied, onCopy, }) {
|
|
60
|
+
return (_jsxs("div", { children: [_jsx("span", { className: "text-[0.65rem] font-medium text-muted-foreground", children: label }), _jsxs("div", { className: "mt-0.5 flex items-center gap-2", children: [_jsx("code", { id: id, className: cn("min-w-0 flex-1 select-all truncate rounded-md", "border border-input bg-background px-2.5 py-1.5", "font-mono text-xs text-foreground"), children: value }), _jsxs("button", { type: "button", onClick: onCopy, "aria-label": `Copy ${label}`, className: cn("inline-flex shrink-0 items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium", "bg-primary text-primary-foreground hover:bg-primary/90", "transition-colors"), children: [copied ? _jsx(CheckIcon, {}) : _jsx(CopyIcon, {}), copied ? "Copied" : "Copy"] })] })] }));
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Icons
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
function CopyIcon() {
|
|
66
|
+
return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { x: "5", y: "5", width: "9", height: "9", rx: "1.5" }), _jsx("path", { d: "M5 11H3.5A1.5 1.5 0 0 1 2 9.5V3.5A1.5 1.5 0 0 1 3.5 2h6A1.5 1.5 0 0 1 11 3.5V5" })] }));
|
|
67
|
+
}
|
|
68
|
+
function CheckIcon() {
|
|
69
|
+
return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M3 8.5l3.5 3.5L13 5" }) }));
|
|
70
|
+
}
|
|
71
|
+
function CloseIcon() {
|
|
72
|
+
return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", "aria-hidden": "true", children: _jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) }));
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=PlatformClientSecretAlert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlatformClientSecretAlert.js","sourceRoot":"","sources":["../../src/platform-client/PlatformClientSecretAlert.tsx"],"names":[],"mappings":"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"}
|