refactor(ui): [UI8] 补齐全局异常卡片边距并统一剩余下拉表单样式
这个提交包含在:
@@ -8,7 +8,7 @@ type EmptyStateCardProps = {
|
|||||||
|
|
||||||
export function EmptyStateCard({ title, description, footer }: EmptyStateCardProps) {
|
export function EmptyStateCard({ title, description, footer }: EmptyStateCardProps) {
|
||||||
return (
|
return (
|
||||||
<section className="card-std">
|
<section className="card-std p-8">
|
||||||
<h3 className="card-title">{title}</h3>
|
<h3 className="card-title">{title}</h3>
|
||||||
<p className="card-desc">{description}</p>
|
<p className="card-desc">{description}</p>
|
||||||
{footer ? <div className="mt-4">{footer}</div> : null}
|
{footer ? <div className="mt-4">{footer}</div> : null}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||||||
<input
|
<input
|
||||||
type={type}
|
type={type}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-200 disabled:cursor-not-allowed disabled:opacity-50",
|
"flex select-std text-zinc-900 placeholder:text-zinc-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-200 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ export function ApprovalRulesPage() {
|
|||||||
<select
|
<select
|
||||||
id="level1Role"
|
id="level1Role"
|
||||||
data-testid="approval-rules-create-level1"
|
data-testid="approval-rules-create-level1"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={level1Role}
|
value={level1Role}
|
||||||
onChange={(event) => setLevel1Role(event.target.value as ApprovalRoleCode)}
|
onChange={(event) => setLevel1Role(event.target.value as ApprovalRoleCode)}
|
||||||
>
|
>
|
||||||
@@ -225,7 +225,7 @@ export function ApprovalRulesPage() {
|
|||||||
<select
|
<select
|
||||||
id="level2Role"
|
id="level2Role"
|
||||||
data-testid="approval-rules-create-level2"
|
data-testid="approval-rules-create-level2"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={level2Role}
|
value={level2Role}
|
||||||
onChange={(event) => setLevel2Role(event.target.value as ApprovalRoleCode)}
|
onChange={(event) => setLevel2Role(event.target.value as ApprovalRoleCode)}
|
||||||
>
|
>
|
||||||
@@ -243,7 +243,7 @@ export function ApprovalRulesPage() {
|
|||||||
<select
|
<select
|
||||||
id="level3Role"
|
id="level3Role"
|
||||||
data-testid="approval-rules-create-level3"
|
data-testid="approval-rules-create-level3"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={level3Role}
|
value={level3Role}
|
||||||
onChange={(event) => setLevel3Role(event.target.value as ApprovalRoleCode)}
|
onChange={(event) => setLevel3Role(event.target.value as ApprovalRoleCode)}
|
||||||
>
|
>
|
||||||
@@ -429,7 +429,7 @@ export function ApprovalRulesPage() {
|
|||||||
<select
|
<select
|
||||||
id="editRuleLevel1"
|
id="editRuleLevel1"
|
||||||
data-testid="approval-rule-edit-level1"
|
data-testid="approval-rule-edit-level1"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={level1Role}
|
value={level1Role}
|
||||||
onChange={(event) => setLevel1Role(event.target.value as ApprovalRoleCode)}
|
onChange={(event) => setLevel1Role(event.target.value as ApprovalRoleCode)}
|
||||||
>
|
>
|
||||||
@@ -446,7 +446,7 @@ export function ApprovalRulesPage() {
|
|||||||
<select
|
<select
|
||||||
id="editRuleLevel2"
|
id="editRuleLevel2"
|
||||||
data-testid="approval-rule-edit-level2"
|
data-testid="approval-rule-edit-level2"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={level2Role}
|
value={level2Role}
|
||||||
onChange={(event) => setLevel2Role(event.target.value as ApprovalRoleCode)}
|
onChange={(event) => setLevel2Role(event.target.value as ApprovalRoleCode)}
|
||||||
>
|
>
|
||||||
@@ -464,7 +464,7 @@ export function ApprovalRulesPage() {
|
|||||||
<select
|
<select
|
||||||
id="editRuleLevel3"
|
id="editRuleLevel3"
|
||||||
data-testid="approval-rule-edit-level3"
|
data-testid="approval-rule-edit-level3"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={level3Role}
|
value={level3Role}
|
||||||
onChange={(event) => setLevel3Role(event.target.value as ApprovalRoleCode)}
|
onChange={(event) => setLevel3Role(event.target.value as ApprovalRoleCode)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export function DepartmentsPage() {
|
|||||||
<select
|
<select
|
||||||
id="deptParent"
|
id="deptParent"
|
||||||
data-testid="departments-create-parent"
|
data-testid="departments-create-parent"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={parentId}
|
value={parentId}
|
||||||
onChange={(event) => setParentId(event.target.value)}
|
onChange={(event) => setParentId(event.target.value)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
|
|||||||
export function ForbiddenPage() {
|
export function ForbiddenPage() {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen items-center justify-center bg-background-light p-6">
|
<div className="flex min-h-screen items-center justify-center bg-background-light p-6">
|
||||||
<div className="card-std max-w-lg text-center">
|
<div className="card-std p-8 max-w-lg text-center">
|
||||||
<p className="text-sm font-semibold uppercase tracking-wide text-primary">403</p>
|
<p className="text-sm font-semibold uppercase tracking-wide text-primary">403</p>
|
||||||
<h1 className="mt-2 text-2xl font-bold text-zinc-900">无权限访问</h1>
|
<h1 className="mt-2 text-2xl font-bold text-zinc-900">无权限访问</h1>
|
||||||
<p className="mt-2 text-sm text-secondary">
|
<p className="mt-2 text-sm text-secondary">
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
|
|||||||
export function NotFoundPage() {
|
export function NotFoundPage() {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen items-center justify-center bg-background-light p-6">
|
<div className="flex min-h-screen items-center justify-center bg-background-light p-6">
|
||||||
<div className="card-std max-w-lg text-center">
|
<div className="card-std p-8 max-w-lg text-center">
|
||||||
<p className="text-sm font-semibold uppercase tracking-wide text-primary">404</p>
|
<p className="text-sm font-semibold uppercase tracking-wide text-primary">404</p>
|
||||||
<h1 className="mt-2 text-2xl font-bold text-zinc-900">页面不存在</h1>
|
<h1 className="mt-2 text-2xl font-bold text-zinc-900">页面不存在</h1>
|
||||||
<p className="mt-2 text-sm text-secondary">请检查地址,或返回工作台首页继续操作。</p>
|
<p className="mt-2 text-sm text-secondary">请检查地址,或返回工作台首页继续操作。</p>
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export function ReimbursementsPage() {
|
|||||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-center">
|
<div className="flex flex-col gap-2 sm:flex-row sm:items-center">
|
||||||
{showProxyOwnerSelector ? (
|
{showProxyOwnerSelector ? (
|
||||||
<select
|
<select
|
||||||
className="h-11 rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
data-testid="reimbursements-owner-select"
|
data-testid="reimbursements-owner-select"
|
||||||
onChange={(event) => setProxyOwnerEmployeeId(event.target.value)}
|
onChange={(event) => setProxyOwnerEmployeeId(event.target.value)}
|
||||||
value={proxyOwnerEmployeeId}
|
value={proxyOwnerEmployeeId}
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ export function UserManagementPage() {
|
|||||||
placeholder="搜索工号/姓名/手机号/邮箱"
|
placeholder="搜索工号/姓名/手机号/邮箱"
|
||||||
/>
|
/>
|
||||||
<select
|
<select
|
||||||
className="h-11 rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std w-auto"
|
||||||
data-testid="users-status-filter"
|
data-testid="users-status-filter"
|
||||||
value={status}
|
value={status}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
@@ -197,8 +197,8 @@ export function UserManagementPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value="">全部状态</option>
|
<option value="">全部状态</option>
|
||||||
<option value="active">active</option>
|
<option value="active">生效中</option>
|
||||||
<option value="archived">archived</option>
|
<option value="archived">已停用</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -207,10 +207,10 @@ export function UserManagementPage() {
|
|||||||
<p className="text-sm text-red-600">
|
<p className="text-sm text-red-600">
|
||||||
{isApiError(listQuery.error)
|
{isApiError(listQuery.error)
|
||||||
? `${listQuery.error.code}: ${mapApiErrorMessage(
|
? `${listQuery.error.code}: ${mapApiErrorMessage(
|
||||||
listQuery.error.code,
|
listQuery.error.code,
|
||||||
listQuery.error.details,
|
listQuery.error.details,
|
||||||
listQuery.error.message,
|
listQuery.error.message,
|
||||||
)}`
|
)}`
|
||||||
: "加载用户列表失败"}
|
: "加载用户列表失败"}
|
||||||
</p>
|
</p>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ export function WorkflowTaskDetailPage() {
|
|||||||
<div className="space-y-2 rounded-lg border border-zinc-200 p-4">
|
<div className="space-y-2 rounded-lg border border-zinc-200 p-4">
|
||||||
<p className="text-sm font-medium text-zinc-800">转审</p>
|
<p className="text-sm font-medium text-zinc-800">转审</p>
|
||||||
<select
|
<select
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
data-testid="workflow-task-transfer-to-approver"
|
data-testid="workflow-task-transfer-to-approver"
|
||||||
onChange={(event) => setSelectedApprover(event.target.value)}
|
onChange={(event) => setSelectedApprover(event.target.value)}
|
||||||
value={selectedApprover}
|
value={selectedApprover}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export function ReimbursementActions({
|
|||||||
value={paymentDate}
|
value={paymentDate}
|
||||||
/>
|
/>
|
||||||
<select
|
<select
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
data-testid="reimbursement-pay-channel"
|
data-testid="reimbursement-pay-channel"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setPaymentChannel(event.target.value as PaymentChannel)
|
setPaymentChannel(event.target.value as PaymentChannel)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export function ReimbursementItemEditor({
|
|||||||
费用类型
|
费用类型
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
data-testid="reimbursement-item-expense-type"
|
data-testid="reimbursement-item-expense-type"
|
||||||
disabled={expenseTypes.length === 0 || isPending}
|
disabled={expenseTypes.length === 0 || isPending}
|
||||||
id="expenseTypeId"
|
id="expenseTypeId"
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ export function CreateUserDialog({
|
|||||||
<select
|
<select
|
||||||
id="departmentId"
|
id="departmentId"
|
||||||
data-testid="users-create-department"
|
data-testid="users-create-department"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={departmentId}
|
value={departmentId}
|
||||||
onChange={(event) => setDepartmentId(event.target.value)}
|
onChange={(event) => setDepartmentId(event.target.value)}
|
||||||
>
|
>
|
||||||
@@ -187,7 +187,7 @@ export function CreateUserDialog({
|
|||||||
<select
|
<select
|
||||||
id="directManagerId"
|
id="directManagerId"
|
||||||
data-testid="users-create-direct-manager"
|
data-testid="users-create-direct-manager"
|
||||||
className="h-11 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm"
|
className="select-std"
|
||||||
value={directManagerId}
|
value={directManagerId}
|
||||||
onChange={(event) => setDirectManagerId(event.target.value)}
|
onChange={(event) => setDirectManagerId(event.target.value)}
|
||||||
>
|
>
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户