forked from baron/baron-sso
org chart 연동기능 추가
This commit is contained in:
142
adminfront/src/features/users/orgChartPicker.ts
Normal file
142
adminfront/src/features/users/orgChartPicker.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
export type OrgChartTenantSelection = {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type TenantFilterTarget = {
|
||||
id?: string;
|
||||
slug?: string;
|
||||
type?: string;
|
||||
parentId?: string | null;
|
||||
};
|
||||
|
||||
type OrgChartPickerMessage = {
|
||||
type?: unknown;
|
||||
payload?: {
|
||||
selections?: Array<{
|
||||
type?: unknown;
|
||||
id?: unknown;
|
||||
name?: unknown;
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
type OrgChartTenantPickerOptions = {
|
||||
tenantId?: string;
|
||||
};
|
||||
|
||||
function isSystemTenant(tenant: TenantFilterTarget) {
|
||||
const slug = tenant.slug?.trim().toLowerCase();
|
||||
const type = tenant.type?.trim().toUpperCase();
|
||||
|
||||
return (
|
||||
!tenant.id?.trim() ||
|
||||
!tenant.slug?.trim() ||
|
||||
type === "SYSTEM" ||
|
||||
slug === "system" ||
|
||||
slug === "global"
|
||||
);
|
||||
}
|
||||
|
||||
function isInTenantSubtree<T extends TenantFilterTarget>(
|
||||
tenant: T,
|
||||
rootTenantId: string,
|
||||
tenantById: Map<string, T>,
|
||||
) {
|
||||
if (!rootTenantId) {
|
||||
return false;
|
||||
}
|
||||
if (tenant.id === rootTenantId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const visitedTenantIds = new Set<string>();
|
||||
let parentId = tenant.parentId ?? "";
|
||||
while (parentId) {
|
||||
if (parentId === rootTenantId) {
|
||||
return true;
|
||||
}
|
||||
if (visitedTenantIds.has(parentId)) {
|
||||
return false;
|
||||
}
|
||||
visitedTenantIds.add(parentId);
|
||||
parentId = tenantById.get(parentId)?.parentId ?? "";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function filterNonHanmacFamilyTenants<T extends TenantFilterTarget>(
|
||||
tenants: T[],
|
||||
hanmacFamilyTenantId?: string,
|
||||
) {
|
||||
const rootTenantId = hanmacFamilyTenantId?.trim() ?? "";
|
||||
const tenantById = new Map(
|
||||
tenants
|
||||
.filter((tenant) => tenant.id?.trim())
|
||||
.map((tenant) => [tenant.id as string, tenant]),
|
||||
);
|
||||
|
||||
return tenants.filter(
|
||||
(tenant) =>
|
||||
!isSystemTenant(tenant) &&
|
||||
!isInTenantSubtree(tenant, rootTenantId, tenantById),
|
||||
);
|
||||
}
|
||||
|
||||
export function buildOrgChartTenantPickerUrl(
|
||||
baseUrl?: string,
|
||||
options: OrgChartTenantPickerOptions = {},
|
||||
) {
|
||||
const normalizedBase = (baseUrl ?? "").replace(/\/+$/, "");
|
||||
const params = new URLSearchParams({
|
||||
mode: "single",
|
||||
select: "tenant",
|
||||
width: "400",
|
||||
height: "600",
|
||||
});
|
||||
const tenantId = options.tenantId?.trim();
|
||||
if (tenantId) {
|
||||
params.set("tenantId", tenantId);
|
||||
}
|
||||
|
||||
return `${normalizedBase}/embed/picker?${params.toString()}`;
|
||||
}
|
||||
|
||||
export function buildAuthenticatedOrgChartTenantPickerUrl(
|
||||
baseUrl?: string,
|
||||
options: OrgChartTenantPickerOptions = {},
|
||||
) {
|
||||
const normalizedBase = (baseUrl ?? "").replace(/\/+$/, "");
|
||||
const pickerUrl = buildOrgChartTenantPickerUrl("", options);
|
||||
const params = new URLSearchParams({
|
||||
auto: "1",
|
||||
returnTo: pickerUrl,
|
||||
});
|
||||
|
||||
return `${normalizedBase}/login?${params.toString()}`;
|
||||
}
|
||||
|
||||
export function parseOrgChartTenantSelection(
|
||||
message: unknown,
|
||||
): OrgChartTenantSelection | null {
|
||||
const data = message as OrgChartPickerMessage;
|
||||
if (data?.type !== "orgfront:picker:confirm") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const selection = data.payload?.selections?.[0];
|
||||
if (
|
||||
selection?.type !== "tenant" ||
|
||||
typeof selection.id !== "string" ||
|
||||
typeof selection.name !== "string" ||
|
||||
selection.id.trim() === ""
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: selection.id,
|
||||
name: selection.name,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user