1
0
forked from baron/baron-sso

웍스 동기화 이력확인 기능추가

This commit is contained in:
2026-06-02 10:41:33 +09:00
parent 75f192fb24
commit 565ef6b685
11 changed files with 3986 additions and 10 deletions

View File

@@ -54,6 +54,7 @@ import {
retryWorksmobileJob,
type WorksmobileComparisonItem,
type WorksmobileCredentialBatch,
type WorksmobileOutboxItem,
} from "../../../lib/adminApi";
import { t } from "../../../lib/i18n";
import {
@@ -93,6 +94,70 @@ export function createWorksmobileCredentialBatchId() {
return `worksmobile-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
}
function worksmobileJobPayloadString(job: WorksmobileOutboxItem, key: string) {
const value = job.payload?.[key];
return typeof value === "string" ? value.trim() : "";
}
function worksmobileJobRequestSummary(job: WorksmobileOutboxItem) {
const summary = job.payload?.requestSummary;
if (!summary || typeof summary !== "object" || Array.isArray(summary)) {
return {};
}
return summary as Record<string, unknown>;
}
function worksmobileSummaryString(
summary: Record<string, unknown>,
key: string,
) {
const value = summary[key];
if (typeof value === "string") {
return value.trim();
}
if (typeof value === "number" && Number.isFinite(value)) {
return String(value);
}
return "";
}
function formatWorksmobileJobTarget(job: WorksmobileOutboxItem) {
const summary = worksmobileJobRequestSummary(job);
return (
worksmobileJobPayloadString(job, "displayName") ||
worksmobileSummaryString(summary, "displayName") ||
worksmobileSummaryString(summary, "orgUnitName") ||
worksmobileJobPayloadString(job, "name") ||
worksmobileJobPayloadString(job, "loginEmail") ||
worksmobileJobPayloadString(job, "email") ||
job.resourceId
);
}
function formatWorksmobileJobTargetSubtext(job: WorksmobileOutboxItem) {
const summary = worksmobileJobRequestSummary(job);
return (
worksmobileJobPayloadString(job, "loginEmail") ||
worksmobileSummaryString(summary, "email") ||
worksmobileJobPayloadString(job, "email") ||
worksmobileJobPayloadString(job, "externalKey") ||
worksmobileSummaryString(summary, "orgUnitExternalKey") ||
job.resourceId
);
}
function formatWorksmobileJobSummaryParts(job: WorksmobileOutboxItem) {
const summary = worksmobileJobRequestSummary(job);
const parts = [
worksmobileJobPayloadString(job, "primaryLeafOrgName"),
worksmobileJobPayloadString(job, "matchLocalPart"),
worksmobileSummaryString(summary, "parentOrgUnitId"),
worksmobileSummaryString(summary, "employeeNumber"),
worksmobileSummaryString(summary, "task"),
].filter(Boolean);
return Array.from(new Set(parts));
}
export function TenantWorksmobilePage() {
const params = useParams<{ tenantId: string }>();
const tenantId = params.tenantId ?? "";
@@ -643,9 +708,10 @@ export function TenantWorksmobilePage() {
<Table>
<TableHeader>
<TableRow>
<TableHead>resource</TableHead>
<TableHead>action</TableHead>
<TableHead>status</TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead> </TableHead>
<TableHead></TableHead>
<TableHead>retry</TableHead>
<TableHead className="w-24" />
</TableRow>
@@ -654,9 +720,31 @@ export function TenantWorksmobilePage() {
{(overview?.recentJobs ?? []).map((job) => (
<TableRow key={job.id}>
<TableCell>
{job.resourceType}:{job.resourceId}
<div className="font-medium">
{formatWorksmobileJobTarget(job)}
</div>
<div className="text-xs text-muted-foreground">
{job.resourceType}:
{formatWorksmobileJobTargetSubtext(job)}
</div>
</TableCell>
<TableCell>
<Badge variant="outline">{job.action}</Badge>
</TableCell>
<TableCell>
<div className="flex max-w-md flex-wrap gap-1">
{formatWorksmobileJobSummaryParts(job).map((part) => (
<Badge key={part} variant="secondary">
{part}
</Badge>
))}
{formatWorksmobileJobSummaryParts(job).length === 0 && (
<span className="text-xs text-muted-foreground">
{job.resourceId}
</span>
)}
</div>
</TableCell>
<TableCell>{job.action}</TableCell>
<TableCell>{job.status}</TableCell>
<TableCell>{job.retryCount}</TableCell>
<TableCell>