refactor(ui): [UI7-1] 为其余配置与边缘页面应用新版空壳布局
这个提交包含在:
@@ -15,6 +15,9 @@ import { Card } from "../components/ui/card";
|
||||
import { Input } from "../components/ui/input";
|
||||
import { Label } from "../components/ui/label";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../components/ui/table";
|
||||
import { toast } from "sonner";
|
||||
import { TableSkeleton } from "../components/common/TableSkeleton";
|
||||
import { ConfirmDialog } from "../components/common/ConfirmDialog";
|
||||
|
||||
export function DepartmentsPage() {
|
||||
const queryClient = useQueryClient();
|
||||
@@ -26,6 +29,7 @@ export function DepartmentsPage() {
|
||||
const [name, setName] = useState("");
|
||||
const [parentId, setParentId] = useState<string>("");
|
||||
const [error, setError] = useState("");
|
||||
const [confirmArchive, setConfirmArchive] = useState<{ id: string; name: string } | null>(null);
|
||||
|
||||
const listQuery = useQuery({
|
||||
queryKey: ["departments", includeArchived],
|
||||
@@ -53,13 +57,14 @@ export function DepartmentsPage() {
|
||||
setName("");
|
||||
setParentId("");
|
||||
setError("");
|
||||
toast.success("部门已创建");
|
||||
},
|
||||
onError: (err) => {
|
||||
if (isApiError(err)) {
|
||||
setError(`${err.code}: ${mapApiErrorMessage(err.code, err.details, err.message)}`);
|
||||
return;
|
||||
}
|
||||
setError(err instanceof Error ? err.message : "创建部门失败");
|
||||
const msg = isApiError(err)
|
||||
? `${err.code}: ${mapApiErrorMessage(err.code, err.details, err.message)}`
|
||||
: err instanceof Error ? err.message : "创建部门失败";
|
||||
setError(msg);
|
||||
toast.error(msg);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -68,13 +73,14 @@ export function DepartmentsPage() {
|
||||
onSuccess: async () => {
|
||||
await queryClient.invalidateQueries({ queryKey: ["departments"] });
|
||||
setError("");
|
||||
toast.success("已归档");
|
||||
},
|
||||
onError: (err) => {
|
||||
if (isApiError(err)) {
|
||||
setError(`${err.code}: ${mapApiErrorMessage(err.code, err.details, err.message)}`);
|
||||
return;
|
||||
}
|
||||
setError(err instanceof Error ? err.message : "归档部门失败");
|
||||
const msg = isApiError(err)
|
||||
? `${err.code}: ${mapApiErrorMessage(err.code, err.details, err.message)}`
|
||||
: err instanceof Error ? err.message : "归档部门失败";
|
||||
setError(msg);
|
||||
toast.error(msg);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -161,7 +167,7 @@ export function DepartmentsPage() {
|
||||
<Card className="space-y-4 p-6">
|
||||
<h3 className="text-base font-semibold text-slate-900">部门列表</h3>
|
||||
|
||||
{listQuery.isLoading ? <p className="text-sm text-slate-500">加载中...</p> : null}
|
||||
{listQuery.isLoading ? <TableSkeleton columns={4} rows={4} /> : null}
|
||||
|
||||
{listQuery.isError ? (
|
||||
<p className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600">
|
||||
@@ -208,12 +214,7 @@ export function DepartmentsPage() {
|
||||
variant="secondary"
|
||||
type="button"
|
||||
disabled={archiveMutation.isPending}
|
||||
onClick={() => {
|
||||
if (!window.confirm(`确认归档部门「${item.name}」?归档后不可用于新员工。`)) {
|
||||
return;
|
||||
}
|
||||
archiveMutation.mutate(item.id);
|
||||
}}
|
||||
onClick={() => setConfirmArchive({ id: item.id, name: item.name })}
|
||||
>
|
||||
归档
|
||||
</Button>
|
||||
@@ -236,6 +237,17 @@ export function DepartmentsPage() {
|
||||
</div>
|
||||
) : null}
|
||||
</Card>
|
||||
|
||||
<ConfirmDialog
|
||||
open={Boolean(confirmArchive)}
|
||||
title="确认归档"
|
||||
description={`确认归档部门「${confirmArchive?.name ?? ""}」?归档后不可用于新员工。`}
|
||||
variant="destructive"
|
||||
onConfirm={async () => {
|
||||
if (confirmArchive) archiveMutation.mutate(confirmArchive.id);
|
||||
}}
|
||||
onOpenChange={(open) => { if (!open) setConfirmArchive(null); }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户