feat(workspace): 在工作台接入今日日报列
This commit is contained in:
@@ -10,9 +10,11 @@ import { useDevTaskStore } from '@/stores/useDevTaskStore';
|
|||||||
import { useTestCaseStore } from '@/stores/useTestCaseStore';
|
import { useTestCaseStore } from '@/stores/useTestCaseStore';
|
||||||
import { useBugStore } from '@/stores/useBugStore';
|
import { useBugStore } from '@/stores/useBugStore';
|
||||||
import { useAuthStore } from '@/stores/useAuthStore';
|
import { useAuthStore } from '@/stores/useAuthStore';
|
||||||
|
import { useTaskWorklogStore } from '@/stores/useTaskWorklogStore';
|
||||||
import { flattenVersions } from '@/lib/derive';
|
import { flattenVersions } from '@/lib/derive';
|
||||||
import { aggregateWorkItems, WORK_ITEM_TYPE_LABEL } from '@/lib/workspace-engine';
|
import { aggregateWorkItems, WORK_ITEM_TYPE_LABEL } from '@/lib/workspace-engine';
|
||||||
import type { WorkItem, WorkItemType } from '@/lib/workspace-engine';
|
import type { WorkItem, WorkItemType } from '@/lib/workspace-engine';
|
||||||
|
import { DailyReportPanel } from '@/components/workspace/DailyReportPanel';
|
||||||
import { PlanDetailDrawer } from '@/components/version/PlanDetailDrawer';
|
import { PlanDetailDrawer } from '@/components/version/PlanDetailDrawer';
|
||||||
import { DevTaskDetailDrawer } from '@/components/dev-task/DevTaskDetailDrawer';
|
import { DevTaskDetailDrawer } from '@/components/dev-task/DevTaskDetailDrawer';
|
||||||
import { TestCaseDetailDrawer } from '@/components/test-case/TestCaseDetailDrawer';
|
import { TestCaseDetailDrawer } from '@/components/test-case/TestCaseDetailDrawer';
|
||||||
@@ -23,6 +25,7 @@ import { formatDateTime } from '@/lib/format';
|
|||||||
import { formatShortTime, formatWorkHours } from '@/lib/work-hours';
|
import { formatShortTime, formatWorkHours } from '@/lib/work-hours';
|
||||||
import { TEST_CASE_STATUS_LABEL, TEST_CASE_STATUS_COLOR } from '@/lib/test-case';
|
import { TEST_CASE_STATUS_LABEL, TEST_CASE_STATUS_COLOR } from '@/lib/test-case';
|
||||||
import { BUG_STATUS_LABEL, BUG_STATUS_COLOR, BUG_SEVERITY_LABEL, BUG_SEVERITY_COLOR } from '@/lib/bug';
|
import { BUG_STATUS_LABEL, BUG_STATUS_COLOR, BUG_SEVERITY_LABEL, BUG_SEVERITY_COLOR } from '@/lib/bug';
|
||||||
|
import { getWorkspaceDailyReport } from '@/lib/workspace-daily-report';
|
||||||
|
|
||||||
type TabKey = 'all' | 'plan_research' | 'plan_product' | 'plan_ui' | 'devTask' | 'testCase' | 'bug';
|
type TabKey = 'all' | 'plan_research' | 'plan_product' | 'plan_ui' | 'devTask' | 'testCase' | 'bug';
|
||||||
|
|
||||||
@@ -51,6 +54,7 @@ export default function WorkspacePage() {
|
|||||||
const { tasks: devTasks, fetchTasks } = useDevTaskStore();
|
const { tasks: devTasks, fetchTasks } = useDevTaskStore();
|
||||||
const { testCases, fetchTestCases } = useTestCaseStore();
|
const { testCases, fetchTestCases } = useTestCaseStore();
|
||||||
const { bugs, fetchBugs } = useBugStore();
|
const { bugs, fetchBugs } = useBugStore();
|
||||||
|
const { worklogs, fetchWorklogs } = useTaskWorklogStore();
|
||||||
const user = useAuthStore((s) => s.user);
|
const user = useAuthStore((s) => s.user);
|
||||||
const [activeTab, setActiveTab] = useState<TabKey>('all');
|
const [activeTab, setActiveTab] = useState<TabKey>('all');
|
||||||
const [showCompleted, setShowCompleted] = useState(true);
|
const [showCompleted, setShowCompleted] = useState(true);
|
||||||
@@ -64,6 +68,7 @@ export default function WorkspacePage() {
|
|||||||
useEffect(() => { fetchTasks(); }, [fetchTasks]);
|
useEffect(() => { fetchTasks(); }, [fetchTasks]);
|
||||||
useEffect(() => { fetchTestCases(); }, [fetchTestCases]);
|
useEffect(() => { fetchTestCases(); }, [fetchTestCases]);
|
||||||
useEffect(() => { fetchBugs(); }, [fetchBugs]);
|
useEffect(() => { fetchBugs(); }, [fetchBugs]);
|
||||||
|
useEffect(() => { fetchWorklogs(); }, [fetchWorklogs]);
|
||||||
|
|
||||||
const userName = user?.name ?? '';
|
const userName = user?.name ?? '';
|
||||||
const allVersions = useMemo(() => flattenVersions(overview), [overview]);
|
const allVersions = useMemo(() => flattenVersions(overview), [overview]);
|
||||||
@@ -113,6 +118,18 @@ export default function WorkspacePage() {
|
|||||||
return items.sort((a, b) => (a.completed !== b.completed ? (a.completed ? 1 : -1) : 0));
|
return items.sort((a, b) => (a.completed !== b.completed ? (a.completed ? 1 : -1) : 0));
|
||||||
}, [workItems, activeTab, showCompleted, selectedVersionId]);
|
}, [workItems, activeTab, showCompleted, selectedVersionId]);
|
||||||
|
|
||||||
|
const today = useMemo(() => new Date().toISOString().slice(0, 10), []);
|
||||||
|
|
||||||
|
const dailyReport = useMemo(() =>
|
||||||
|
getWorkspaceDailyReport({
|
||||||
|
worklogs,
|
||||||
|
workItems,
|
||||||
|
userId: userName,
|
||||||
|
date: today,
|
||||||
|
}),
|
||||||
|
[worklogs, workItems, userName, today]
|
||||||
|
);
|
||||||
|
|
||||||
// 待办数量按 tab 分(受 version filter 影响)
|
// 待办数量按 tab 分(受 version filter 影响)
|
||||||
const pendingByTab = useMemo(() => {
|
const pendingByTab = useMemo(() => {
|
||||||
const base = selectedVersionId ? workItems.filter((i) => i.versionId === selectedVersionId) : workItems;
|
const base = selectedVersionId ? workItems.filter((i) => i.versionId === selectedVersionId) : workItems;
|
||||||
@@ -191,7 +208,7 @@ export default function WorkspacePage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 右侧:任务列表 */}
|
{/* 右侧:任务列表 */}
|
||||||
<div className="flex-1 flex flex-col overflow-hidden">
|
<div className="min-w-0 flex-1 flex flex-col overflow-hidden">
|
||||||
<header className="flex h-14 shrink-0 items-center border-b border-[var(--line)] bg-[var(--bg-card)] px-5">
|
<header className="flex h-14 shrink-0 items-center border-b border-[var(--line)] bg-[var(--bg-card)] px-5">
|
||||||
<h2 className="text-[14px] font-semibold text-[var(--ink)]">{TABS.find((t) => t.key === activeTab)?.label}</h2>
|
<h2 className="text-[14px] font-semibold text-[var(--ink)]">{TABS.find((t) => t.key === activeTab)?.label}</h2>
|
||||||
<span className="ml-2 text-[12px] text-[var(--ink-muted)]">{filteredItems.length} 项</span>
|
<span className="ml-2 text-[12px] text-[var(--ink-muted)]">{filteredItems.length} 项</span>
|
||||||
@@ -222,6 +239,8 @@ export default function WorkspacePage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<DailyReportPanel report={dailyReport} />
|
||||||
|
|
||||||
{/* Detail Drawers */}
|
{/* Detail Drawers */}
|
||||||
{drawerItem && (drawerItem.type === 'plan_research' || drawerItem.type === 'plan_product' || drawerItem.type === 'plan_ui') && (
|
{drawerItem && (drawerItem.type === 'plan_research' || drawerItem.type === 'plan_product' || drawerItem.type === 'plan_ui') && (
|
||||||
<PlanDetailDrawer planId={drawerItem.id} onClose={() => setDrawerItem(null)} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
|
<PlanDetailDrawer planId={drawerItem.id} onClose={() => setDrawerItem(null)} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
|
||||||
|
|||||||
Reference in New Issue
Block a user