fix: require explicit business form choices
This commit is contained in:
@@ -36,7 +36,6 @@ export function OrganizationInviteDialog({
|
||||
() => roles.filter((role) => role.scope === "organization" && role.organizationId === organization.id && role.isEnabled),
|
||||
[organization.id, roles],
|
||||
);
|
||||
const defaultRoleId = organizationRoles.find((role) => role.key === "caregiver")?.id ?? organizationRoles[0]?.id ?? "";
|
||||
|
||||
function closeDialog(): void {
|
||||
if (isPending) {
|
||||
@@ -52,14 +51,20 @@ export function OrganizationInviteDialog({
|
||||
event.preventDefault();
|
||||
setMessage("");
|
||||
setLastInviteHref("");
|
||||
setIsPending(true);
|
||||
const formData = new FormData(event.currentTarget);
|
||||
const roleId = String(formData.get("roleId") ?? "");
|
||||
if (!roleId) {
|
||||
setMessage("请选择邀请角色");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsPending(true);
|
||||
const response = await fetch(`/api/organizations/${organization.id}/invitations`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
email: String(formData.get("email") ?? ""),
|
||||
roleId: String(formData.get("roleId") ?? ""),
|
||||
roleId,
|
||||
}),
|
||||
});
|
||||
const result = (await response.json()) as ApiResult<{ invitation: OrganizationInvitation }>;
|
||||
@@ -94,11 +99,14 @@ export function OrganizationInviteDialog({
|
||||
<span className="font-medium">角色</span>
|
||||
<Select
|
||||
aria-label="邀请角色"
|
||||
defaultValue={defaultRoleId}
|
||||
defaultValue=""
|
||||
disabled={organizationRoles.length === 0}
|
||||
key={organization.id}
|
||||
name="roleId"
|
||||
options={organizationRoles.map((role) => ({ value: role.id, label: role.label }))}
|
||||
options={[
|
||||
{ value: "", label: "选择邀请角色", disabled: true },
|
||||
...organizationRoles.map((role) => ({ value: role.id, label: role.label })),
|
||||
]}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
@@ -125,7 +133,7 @@ export function OrganizationInviteDialog({
|
||||
<Button disabled={isPending} onClick={closeDialog} type="button" variant="outline">
|
||||
取消
|
||||
</Button>
|
||||
<Button disabled={isPending || !defaultRoleId} type="submit">
|
||||
<Button disabled={isPending || organizationRoles.length === 0} type="submit">
|
||||
<Send className="size-4" aria-hidden="true" />
|
||||
生成邀请
|
||||
</Button>
|
||||
|
||||
@@ -24,10 +24,6 @@ function getOrganizationRoles(roles: RoleDefinition[], organizationId: string):
|
||||
return roles.filter((role) => role.scope === "organization" && role.organizationId === organizationId && role.isEnabled);
|
||||
}
|
||||
|
||||
function getDefaultOrganizationId(organizations: Organization[]): string {
|
||||
return organizations[0]?.id ?? "";
|
||||
}
|
||||
|
||||
export function UserManagementClient({
|
||||
canManageAccounts = false,
|
||||
organizations,
|
||||
@@ -36,7 +32,7 @@ export function UserManagementClient({
|
||||
}: UserManagementClientProps): React.ReactElement {
|
||||
const router = useRouter();
|
||||
const [isCreateOpen, setIsCreateOpen] = useState(false);
|
||||
const [selectedOrganizationId, setSelectedOrganizationId] = useState(() => getDefaultOrganizationId(organizations));
|
||||
const [selectedOrganizationId, setSelectedOrganizationId] = useState("");
|
||||
const [reviewRoleByRequestId, setReviewRoleByRequestId] = useState<Record<string, string>>({});
|
||||
const [message, setMessage] = useState("");
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
@@ -68,15 +64,22 @@ export function UserManagementClient({
|
||||
}
|
||||
|
||||
setMessage("");
|
||||
setIsPending(true);
|
||||
|
||||
const formData = new FormData(event.currentTarget);
|
||||
const organizationId = String(formData.get("organizationId") ?? "");
|
||||
const roleId = String(formData.get("roleId") ?? "");
|
||||
if (!organizationId || !roleId) {
|
||||
setMessage("请选择机构和角色");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsPending(true);
|
||||
const response = await fetch("/api/settings/accounts", {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
organizationId: String(formData.get("organizationId") ?? ""),
|
||||
roleId: String(formData.get("roleId") ?? ""),
|
||||
organizationId,
|
||||
roleId,
|
||||
name: String(formData.get("name") ?? ""),
|
||||
email: String(formData.get("email") ?? ""),
|
||||
avatarUrl: String(formData.get("avatarUrl") ?? ""),
|
||||
@@ -170,8 +173,7 @@ export function UserManagementClient({
|
||||
<CardContent className="space-y-3">
|
||||
{pendingJoinRequests.map((request) => {
|
||||
const requestRoles = getOrganizationRoles(roles, request.organizationId);
|
||||
const defaultRoleId = requestRoles.find((role) => role.key === "caregiver")?.id ?? requestRoles[0]?.id ?? "";
|
||||
const selectedRoleId = reviewRoleByRequestId[request.id] ?? defaultRoleId;
|
||||
const selectedRoleId = reviewRoleByRequestId[request.id] ?? "";
|
||||
|
||||
return (
|
||||
<div key={request.id} className="rounded-md border p-3">
|
||||
@@ -190,7 +192,10 @@ export function UserManagementClient({
|
||||
onValueChange={(roleId) =>
|
||||
setReviewRoleByRequestId((current) => ({ ...current, [request.id]: roleId }))
|
||||
}
|
||||
options={requestRoles.map((role) => ({ value: role.id, label: role.label }))}
|
||||
options={[
|
||||
{ value: "", label: "选择审批角色", disabled: true },
|
||||
...requestRoles.map((role) => ({ value: role.id, label: role.label })),
|
||||
]}
|
||||
value={selectedRoleId}
|
||||
/>
|
||||
<Button
|
||||
@@ -233,7 +238,11 @@ export function UserManagementClient({
|
||||
aria-label="机构"
|
||||
name="organizationId"
|
||||
onValueChange={setSelectedOrganizationId}
|
||||
options={organizations.map((organization) => ({ value: organization.id, label: organization.name }))}
|
||||
options={[
|
||||
{ value: "", label: "选择机构", disabled: true },
|
||||
...organizations.map((organization) => ({ value: organization.id, label: organization.name })),
|
||||
]}
|
||||
required
|
||||
value={selectedOrganizationId}
|
||||
/>
|
||||
</label>
|
||||
@@ -242,11 +251,14 @@ export function UserManagementClient({
|
||||
<span className="font-medium">角色</span>
|
||||
<Select
|
||||
aria-label="角色"
|
||||
defaultValue={organizationRoles[0]?.id ?? ""}
|
||||
defaultValue=""
|
||||
disabled={organizationRoles.length === 0}
|
||||
key={selectedOrganizationId}
|
||||
name="roleId"
|
||||
options={organizationRoles.map((role) => ({ value: role.id, label: role.label }))}
|
||||
options={[
|
||||
{ value: "", label: selectedOrganizationId ? "选择角色" : "先选择机构", disabled: true },
|
||||
...organizationRoles.map((role) => ({ value: role.id, label: role.label })),
|
||||
]}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
@@ -303,17 +315,14 @@ export function UserAccountActions({
|
||||
}: UserAccountActionsProps): React.ReactElement {
|
||||
const router = useRouter();
|
||||
const [isEditOpen, setIsEditOpen] = useState(false);
|
||||
const [selectedOrganizationId, setSelectedOrganizationId] = useState(
|
||||
() => account.organizationId ?? getDefaultOrganizationId(organizations),
|
||||
);
|
||||
const [selectedOrganizationId, setSelectedOrganizationId] = useState(() => account.organizationId ?? "");
|
||||
const [message, setMessage] = useState("");
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
const organizationRoles = useMemo(
|
||||
() => getOrganizationRoles(roles, selectedOrganizationId),
|
||||
[roles, selectedOrganizationId],
|
||||
);
|
||||
const defaultRoleId =
|
||||
organizationRoles.find((role) => role.key === account.role || role.id === account.role)?.id ?? organizationRoles[0]?.id ?? "";
|
||||
const defaultRoleId = organizationRoles.find((role) => role.key === account.role || role.id === account.role)?.id ?? "";
|
||||
const isCurrentAccount = account.id === currentAccountId;
|
||||
|
||||
async function updateAccount(payload: Record<string, string>): Promise<void> {
|
||||
@@ -430,7 +439,10 @@ export function UserAccountActions({
|
||||
aria-label="账号机构"
|
||||
name="organizationId"
|
||||
onValueChange={setSelectedOrganizationId}
|
||||
options={organizations.map((organization) => ({ value: organization.id, label: organization.name }))}
|
||||
options={[
|
||||
{ value: "", label: "选择机构", disabled: true },
|
||||
...organizations.map((organization) => ({ value: organization.id, label: organization.name })),
|
||||
]}
|
||||
value={selectedOrganizationId}
|
||||
/>
|
||||
</label>
|
||||
@@ -442,7 +454,10 @@ export function UserAccountActions({
|
||||
disabled={organizationRoles.length === 0}
|
||||
key={selectedOrganizationId}
|
||||
name="roleId"
|
||||
options={organizationRoles.map((role) => ({ value: role.id, label: role.label }))}
|
||||
options={[
|
||||
{ value: "", label: selectedOrganizationId ? "选择角色" : "先选择机构", disabled: true },
|
||||
...organizationRoles.map((role) => ({ value: role.id, label: role.label })),
|
||||
]}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user