DG9 统一全站 UI 布局样板迁移
关联 Issue: DG9-0..DG9-12
这个提交包含在:
@@ -325,15 +325,15 @@ export function MobilePortalPage() {
|
||||
].filter((item): item is MobileAction => Boolean(item)).slice(0, 4);
|
||||
|
||||
return (
|
||||
<PageScaffold className="space-y-4">
|
||||
<PageScaffold className="mobile-page-stack">
|
||||
<PageHeader title="今天" />
|
||||
|
||||
{canAccessApprovals && pendingApprovalCount > 0 ? (
|
||||
<section className="mobile-card" data-testid="mobile-pending-summary">
|
||||
<div className="mb-3 flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<div className="text-base font-semibold text-zinc-900">待处理</div>
|
||||
<div className="mt-1 text-xs text-zinc-500">待我审批</div>
|
||||
<section className="mobile-card mobile-page-stack" data-testid="mobile-pending-summary">
|
||||
<div className="mobile-section-header">
|
||||
<div className="min-w-0">
|
||||
<div className="mobile-section-title">待处理</div>
|
||||
<div className="mobile-list-card__subtitle mt-1">待我审批</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-3xl font-semibold leading-none text-zinc-900" data-testid="mobile-pending-summary-count">
|
||||
@@ -345,7 +345,7 @@ export function MobilePortalPage() {
|
||||
</div>
|
||||
</div>
|
||||
{urgentPendingTask ? (
|
||||
<div className="space-y-2">
|
||||
<div className="mobile-page-stack">
|
||||
{(() => {
|
||||
const task = urgentPendingTask;
|
||||
const entityType = task.workflowInstance?.entityType;
|
||||
@@ -355,16 +355,16 @@ export function MobilePortalPage() {
|
||||
key={task.id}
|
||||
to={`/mobile/approvals/${encodeURIComponent(task.id)}`}
|
||||
state={{ from: currentMobileSource }}
|
||||
className="block rounded-lg border border-zinc-200 px-3 py-2 text-sm"
|
||||
className="mobile-list-card block text-sm"
|
||||
data-testid="mobile-pending-summary-primary"
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="min-w-0 truncate font-medium text-zinc-900">
|
||||
{reference ? `${businessEntityLabel(entityType, { noun: true })} ${reference}` : businessEntityLabel(entityType, { noun: true })}
|
||||
<div className="mobile-list-card__header">
|
||||
<div className="mobile-list-card__title">
|
||||
{reference ? `${businessEntityLabel(entityType, { noun: true })} ${reference}` : businessEntityLabel(entityType, { noun: true })}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-1 truncate text-xs text-zinc-500">
|
||||
{joinBusinessMeta([task.businessSummary?.applicantName ? `申请人:${task.businessSummary.applicantName}` : null, task.businessSummary?.amount ?? task.businessSummary?.duration, `节点:${task.stepName}`])}
|
||||
<div className="mobile-list-card__subtitle mt-1">
|
||||
{joinBusinessMeta([task.businessSummary?.applicantName ? `申请人:${task.businessSummary.applicantName}` : null, task.businessSummary?.amount ?? task.businessSummary?.duration, `节点:${task.stepName}`])}
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
@@ -378,9 +378,9 @@ export function MobilePortalPage() {
|
||||
) : null}
|
||||
|
||||
{canUseFinance ? (
|
||||
<section className="mobile-card" data-testid="mobile-finance-summary">
|
||||
<div className="mb-3 flex items-center justify-between gap-3">
|
||||
<div className="text-base font-semibold text-zinc-900">财务</div>
|
||||
<section className="mobile-card mobile-page-stack" data-testid="mobile-finance-summary">
|
||||
<div className="mobile-section-header">
|
||||
<div className="mobile-section-title">财务</div>
|
||||
<span className="badge-neutral">复核与付款</span>
|
||||
</div>
|
||||
{portalHomeQuery.isLoading ? <p className="text-sm text-zinc-500">读取中...</p> : null}
|
||||
@@ -408,9 +408,9 @@ export function MobilePortalPage() {
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
<section className="mobile-card" data-testid="mobile-today-focus">
|
||||
<div className="mb-3 flex items-center justify-between gap-3">
|
||||
<div className="text-base font-semibold text-zinc-900">常用</div>
|
||||
<section className="mobile-card mobile-page-stack" data-testid="mobile-today-focus">
|
||||
<div className="mobile-section-header">
|
||||
<div className="mobile-section-title">常用</div>
|
||||
</div>
|
||||
<div className="mobile-icon-grid" data-testid="mobile-action-grid">
|
||||
{actions.map((action) => (
|
||||
@@ -420,9 +420,9 @@ export function MobilePortalPage() {
|
||||
</section>
|
||||
|
||||
{!attendanceFeatureDisabled ? (
|
||||
<section className="mobile-card" data-testid="mobile-attendance-card">
|
||||
<div className="mb-3 flex items-center justify-between gap-3">
|
||||
<div className="text-base font-semibold text-zinc-900">打卡</div>
|
||||
<section className="mobile-card mobile-page-stack" data-testid="mobile-attendance-card">
|
||||
<div className="mobile-section-header">
|
||||
<div className="mobile-section-title">打卡</div>
|
||||
<span className="badge-neutral">{attendanceToday?.workDate ?? "今日"}</span>
|
||||
</div>
|
||||
|
||||
@@ -464,9 +464,9 @@ export function MobilePortalPage() {
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
<section className="mobile-card" data-testid="mobile-notifications">
|
||||
<div className="mb-3 flex items-center justify-between gap-3">
|
||||
<div className="text-base font-semibold text-zinc-900">通知</div>
|
||||
<section className="mobile-card mobile-page-stack" data-testid="mobile-notifications">
|
||||
<div className="mobile-section-header">
|
||||
<div className="mobile-section-title">通知</div>
|
||||
<Button asChild size="sm" type="button" variant="secondary">
|
||||
<Link to="/mobile/notifications">全部</Link>
|
||||
</Button>
|
||||
@@ -482,23 +482,23 @@ export function MobilePortalPage() {
|
||||
<p className="text-sm text-zinc-500">暂无通知。</p>
|
||||
) : null}
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="mobile-page-stack">
|
||||
{homeNotifications.map((item) => (
|
||||
<button
|
||||
key={item.id}
|
||||
type="button"
|
||||
className="block w-full rounded-lg border border-zinc-200 px-3 py-2 text-left text-sm"
|
||||
className="mobile-list-card w-full text-left text-sm"
|
||||
onClick={() => void openHomeNotification(item)}
|
||||
data-testid="mobile-home-notification-card"
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="mobile-list-card__header">
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs text-zinc-500">{notificationTypeLabel(item.type)}</div>
|
||||
<div className="mt-0.5 truncate font-medium text-zinc-900">{item.title}</div>
|
||||
<div className="text-xs font-medium text-primary">{notificationTypeLabel(item.type)}</div>
|
||||
<div className="mobile-list-card__title mt-0.5">{item.title}</div>
|
||||
</div>
|
||||
{!item.readAt ? <span className="badge-warning shrink-0">新</span> : null}
|
||||
{!item.readAt ? <span className="badge-warning mobile-status-slot">新</span> : null}
|
||||
</div>
|
||||
<div className="mt-1 text-xs text-zinc-500">{formatDateTime(item.createdAt)}</div>
|
||||
<div className="mobile-list-card__subtitle mt-1">{formatDateTime(item.createdAt)}</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
在新工单中引用
屏蔽一个用户