feat: add access module boundary migrations
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import type { ApiSettings, MailProfileScope, MailProfilesUiCapability, MailProfileTargetOption } from "@govoplan/core-webui";
|
||||
import { fetchGroups, fetchUsers } from "../../api/admin";
|
||||
import { fetchGroupsDelta, fetchUsersDelta, type GroupSummary, type UserAdminItem } from "../../api/admin";
|
||||
import { Card } from "@govoplan/core-webui";
|
||||
import { AdminPageLayout, adminErrorMessage } from "@govoplan/core-webui";
|
||||
import { AdminPageLayout, adminErrorMessage, useDeltaWatermarks } from "@govoplan/core-webui";
|
||||
import { usePlatformUiCapability } from "@govoplan/core-webui";
|
||||
import { loadDeltaRows } from "./utils/deltaRows";
|
||||
|
||||
type Props = {
|
||||
settings: ApiSettings;
|
||||
@@ -13,32 +14,32 @@ type Props = {
|
||||
canWritePolicy: boolean;
|
||||
};
|
||||
|
||||
const copy: Record<Props["scopeType"], { title: string; description: string; targetLabel?: string; profileTitle: string; policyTitle: string }> = {
|
||||
const copy: Record<Props["scopeType"], {title: string;description: string;targetLabel?: string;profileTitle: string;policyTitle: string;}> = {
|
||||
system: {
|
||||
title: "System mail profiles",
|
||||
description: "Instance-level mail server profiles and policy limits inherited by every tenant.",
|
||||
profileTitle: "System profiles",
|
||||
policyTitle: "System mail profile policy"
|
||||
title: "i18n:govoplan-access.system_mail_profiles.5af3eb64",
|
||||
description: "i18n:govoplan-access.instance_level_mail_server_profiles_and_policy_l.b807bda7",
|
||||
profileTitle: "i18n:govoplan-access.system_profiles.98adae54",
|
||||
policyTitle: "i18n:govoplan-access.system_mail_profile_policy.7edd7fcf"
|
||||
},
|
||||
tenant: {
|
||||
title: "Tenant mail profiles",
|
||||
description: "Tenant-level mail server profiles and policy limits for the active tenant.",
|
||||
profileTitle: "Tenant profiles",
|
||||
policyTitle: "Tenant mail profile policy"
|
||||
title: "i18n:govoplan-access.tenant_mail_profiles.5132a623",
|
||||
description: "i18n:govoplan-access.tenant_level_mail_server_profiles_and_policy_lim.d829507f",
|
||||
profileTitle: "i18n:govoplan-access.tenant_profiles.4d7281ce",
|
||||
policyTitle: "i18n:govoplan-access.tenant_mail_profile_policy.239298a1"
|
||||
},
|
||||
user: {
|
||||
title: "User mail profiles",
|
||||
description: "User-scoped profiles and policy limits for campaign owners in the active tenant.",
|
||||
targetLabel: "User",
|
||||
profileTitle: "User profiles",
|
||||
policyTitle: "User mail profile policy"
|
||||
title: "i18n:govoplan-access.user_mail_profiles.f54a845a",
|
||||
description: "i18n:govoplan-access.user_scoped_profiles_and_policy_limits_for_campa.bff6eccf",
|
||||
targetLabel: "i18n:govoplan-access.user.9f8a2389",
|
||||
profileTitle: "i18n:govoplan-access.user_profiles.57730285",
|
||||
policyTitle: "i18n:govoplan-access.user_mail_profile_policy.529e035b"
|
||||
},
|
||||
group: {
|
||||
title: "Group mail profiles",
|
||||
description: "Group-scoped profiles and policy limits for group-owned campaigns in the active tenant.",
|
||||
targetLabel: "Group",
|
||||
profileTitle: "Group profiles",
|
||||
policyTitle: "Group mail profile policy"
|
||||
title: "i18n:govoplan-access.group_mail_profiles.ebf1b5ba",
|
||||
description: "i18n:govoplan-access.group_scoped_profiles_and_policy_limits_for_grou.a314ba66",
|
||||
targetLabel: "i18n:govoplan-access.group.171a0606",
|
||||
profileTitle: "i18n:govoplan-access.group_profiles.74568838",
|
||||
policyTitle: "i18n:govoplan-access.group_mail_profile_policy.d98ef5a2"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,6 +47,9 @@ export default function MailProfilesPanel({ settings, scopeType, canWriteProfile
|
||||
const mailProfilesUi = usePlatformUiCapability<MailProfilesUiCapability>("mail.profiles");
|
||||
const MailProfileScopeManager = mailProfilesUi?.MailProfileScopeManager ?? null;
|
||||
const [targets, setTargets] = useState<MailProfileTargetOption[]>([]);
|
||||
const usersRef = useRef<UserAdminItem[]>([]);
|
||||
const groupsRef = useRef<GroupSummary[]>([]);
|
||||
const { getDeltaWatermark, setDeltaWatermark, resetDeltaWatermark } = useDeltaWatermarks();
|
||||
const [loadingTargets, setLoadingTargets] = useState(Boolean(MailProfileScopeManager) && (scopeType === "user" || scopeType === "group"));
|
||||
const [targetError, setTargetError] = useState("");
|
||||
|
||||
@@ -56,8 +60,11 @@ export default function MailProfilesPanel({ settings, scopeType, canWriteProfile
|
||||
setTargetError("");
|
||||
return;
|
||||
}
|
||||
usersRef.current = [];
|
||||
groupsRef.current = [];
|
||||
resetDeltaWatermark();
|
||||
void loadTargets();
|
||||
}, [settings.accessToken, settings.apiBaseUrl, settings.apiKey, scopeType, MailProfileScopeManager]);
|
||||
}, [settings.accessToken, settings.apiBaseUrl, settings.apiKey, scopeType, MailProfileScopeManager, resetDeltaWatermark]);
|
||||
|
||||
async function loadTargets() {
|
||||
if (scopeType !== "user" && scopeType !== "group") {
|
||||
@@ -70,14 +77,16 @@ export default function MailProfilesPanel({ settings, scopeType, canWriteProfile
|
||||
setTargetError("");
|
||||
try {
|
||||
if (scopeType === "user") {
|
||||
const users = await fetchUsers(settings);
|
||||
const users = await loadDeltaRows(usersRef.current, "access:mail-profile-users", getDeltaWatermark, setDeltaWatermark, (since) => fetchUsersDelta(settings, { since }), (response) => response.users, (user) => user.id, "access_user", sortUsers);
|
||||
usersRef.current = users;
|
||||
setTargets(users.map((user) => ({
|
||||
id: user.id,
|
||||
label: user.display_name || user.email,
|
||||
secondary: user.display_name ? user.email : null
|
||||
})));
|
||||
} else {
|
||||
const groups = await fetchGroups(settings);
|
||||
const groups = await loadDeltaRows(groupsRef.current, "access:mail-profile-groups", getDeltaWatermark, setDeltaWatermark, (since) => fetchGroupsDelta(settings, { since }), (response) => response.groups, (group) => group.id, "access_group", sortGroups);
|
||||
groupsRef.current = groups;
|
||||
setTargets(groups.map((group) => ({
|
||||
id: group.id,
|
||||
label: group.name,
|
||||
@@ -97,11 +106,11 @@ export default function MailProfilesPanel({ settings, scopeType, canWriteProfile
|
||||
if (!MailProfileScopeManager) {
|
||||
return (
|
||||
<AdminPageLayout title={labels.title} description={labels.description}>
|
||||
<Card title="Mail module unavailable">
|
||||
<p className="muted">Install and enable the Mail module to manage mail server profiles and profile policies.</p>
|
||||
<Card title="i18n:govoplan-access.mail_module_unavailable.b4e95104">
|
||||
<p className="muted">i18n:govoplan-access.install_and_enable_the_mail_module_to_manage_mai.a8ad5b3a</p>
|
||||
</Card>
|
||||
</AdminPageLayout>
|
||||
);
|
||||
</AdminPageLayout>);
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -115,8 +124,16 @@ export default function MailProfilesPanel({ settings, scopeType, canWriteProfile
|
||||
policyTitle={labels.policyTitle}
|
||||
canWriteProfiles={canWriteProfiles}
|
||||
canManageCredentials={canManageCredentials}
|
||||
canWritePolicy={canWritePolicy}
|
||||
/>
|
||||
</AdminPageLayout>
|
||||
);
|
||||
canWritePolicy={canWritePolicy} />
|
||||
|
||||
</AdminPageLayout>);
|
||||
|
||||
}
|
||||
|
||||
function sortUsers(left: UserAdminItem, right: UserAdminItem): number {
|
||||
return left.email.localeCompare(right.email);
|
||||
}
|
||||
|
||||
function sortGroups(left: GroupSummary, right: GroupSummary): number {
|
||||
return left.name.localeCompare(right.name) || left.slug.localeCompare(right.slug);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user