1
0
forked from baron/baron-sso

custom claim 타입보정 UI. 대표테넌트 노출 보정

This commit is contained in:
2026-06-11 11:27:11 +09:00
parent 0bb3ccb850
commit f60b15a17b
37 changed files with 2952 additions and 417 deletions

View File

@@ -52,6 +52,7 @@ import { ClientDetailTabs } from "./ClientDetailTabs";
type RPClaimValueType =
| "text"
| "number"
| "float"
| "boolean"
| "array"
| "object"
@@ -167,7 +168,9 @@ function draftRowsToMetadata(rows: MetadataDraftRow[]) {
function draftRowValueToMetadataValue(row: MetadataDraftRow) {
const value = row.value.trim();
switch (row.valueType) {
case "number": {
case "number":
return /^-?\d+$/.test(value) ? Number.parseInt(value, 10) : value;
case "float": {
const parsed = Number(value);
return Number.isFinite(parsed) ? parsed : value;
}
@@ -200,6 +203,7 @@ function isRPClaimValueType(value: string): value is RPClaimValueType {
return (
value === "text" ||
value === "number" ||
value === "float" ||
value === "boolean" ||
value === "array" ||
value === "object" ||
@@ -268,10 +272,21 @@ function readRPClaimSchemas(
function rpClaimInputType(valueType: RPClaimValueType) {
if (valueType === "date") return "date";
if (valueType === "datetime") return "datetime-local";
if (valueType === "number") return "number";
return "text";
}
function rpClaimInputMode(valueType: RPClaimValueType) {
if (valueType === "number") return "numeric";
if (valueType === "float") return "decimal";
return undefined;
}
function rpClaimInputPattern(valueType: RPClaimValueType) {
if (valueType === "number") return "-?[0-9]*";
if (valueType === "float") return "-?(?:[0-9]+(?:\\.[0-9]+)?|\\.[0-9]+)";
return undefined;
}
function ClientConsentsPage() {
const params = useParams();
const clientId = params.id ?? "";
@@ -452,25 +467,6 @@ function ClientConsentsPage() {
);
};
const addMetadataDraftRow = () => {
setMetadataDraftRows((current) => [
...current,
{
id: `rp-metadata-${Date.now()}`,
key: "",
value: "",
valueType: "text",
readPermission: "admin_only",
writePermission: "admin_only",
schemaBacked: false,
},
]);
};
const removeMetadataDraftRow = (id: string) => {
setMetadataDraftRows((current) => current.filter((row) => row.id !== id));
};
if (error) {
const axiosError = error as AxiosError<{ error?: string }>;
if (axiosError.response?.status === 403) {
@@ -958,16 +954,6 @@ function ClientConsentsPage() {
</p>
</div>
<div className="flex gap-2">
{rpClaimSchemas.length === 0 && (
<Button
variant="outline"
className="gap-2"
onClick={addMetadataDraftRow}
>
<Edit3 className="h-4 w-4" />
{t("ui.common.add", "추가")}
</Button>
)}
<Button
variant="ghost"
className="gap-2"
@@ -1008,25 +994,9 @@ function ClientConsentsPage() {
key={row.id}
className="grid gap-3 md:grid-cols-[minmax(180px,0.8fr)_minmax(220px,1fr)_150px_150px_auto]"
>
{row.schemaBacked ? (
<div className="flex h-10 items-center rounded-md border bg-muted/30 px-3 font-mono text-xs">
{row.key}
</div>
) : (
<Input
value={row.key}
onChange={(event) =>
updateMetadataDraftRow(row.id, {
key: event.target.value,
})
}
className="font-mono text-xs"
placeholder={t(
"ui.dev.clients.consents.rp_claims.key_placeholder",
"claim_key",
)}
/>
)}
<div className="flex h-10 items-center rounded-md border bg-muted/30 px-3 font-mono text-xs">
{row.key}
</div>
{row.valueType === "boolean" ? (
<select
value={row.value === "false" ? "false" : "true"}
@@ -1061,6 +1031,8 @@ function ClientConsentsPage() {
) : (
<Input
type={rpClaimInputType(row.valueType)}
inputMode={rpClaimInputMode(row.valueType)}
pattern={rpClaimInputPattern(row.valueType)}
value={row.value}
onChange={(event) =>
updateMetadataDraftRow(row.id, {
@@ -1129,22 +1101,12 @@ function ClientConsentsPage() {
)}
</option>
</select>
{row.schemaBacked ? (
<Badge
variant="muted"
className="h-10 justify-center rounded-md px-3 font-mono text-xs"
>
{row.valueType}
</Badge>
) : (
<Button
variant="ghost"
size="icon"
onClick={() => removeMetadataDraftRow(row.id)}
>
<X className="h-4 w-4" />
</Button>
)}
<Badge
variant="muted"
className="h-10 justify-center rounded-md px-3 font-mono text-xs"
>
{row.valueType}
</Badge>
</div>
))
)}