Browse Source

feat(dashboard-v6): 新增任务详情路由 /workspace/task/:taskId

- 新增 taskLoader 与任务详情页 show.tsx,复用现有 Task 组件
- 详情版心限宽 1000px 并居中
- 修正「在新标签页中打开任务」链接指向 /workspace/task/:taskId
visuddhinanda 1 week ago
parent
commit
1647a543d8

+ 16 - 0
dashboard-v6/src/api/task.ts

@@ -275,3 +275,19 @@ export async function projectLoader({ params }: LoaderFunctionArgs) {
 
   return res.data;
 }
+
+export async function taskLoader({ params }: LoaderFunctionArgs) {
+  const taskId = params.taskId;
+
+  if (!taskId) {
+    throw new Response("Missing taskId", { status: 400 });
+  }
+
+  const res = await get<ITaskResponse>(`/api/v2/task/${taskId}`);
+
+  if (!res.ok) {
+    throw new Response("Task not found", { status: 404 });
+  }
+
+  return res.data;
+}

+ 1 - 1
dashboard-v6/src/components/task/TaskEditDrawer.tsx

@@ -57,7 +57,7 @@ const TaskEditDrawer = ({
           <Button
             type="link"
             onClick={() => {
-              window.open(fullUrl(`/article/task/${taskId}`), "_blank");
+              window.open(fullUrl(`/workspace/task/${taskId}`), "_blank");
             }}
           >
             {intl.formatMessage(

+ 1 - 0
dashboard-v6/src/locales/en-US/pages.ts

@@ -9,6 +9,7 @@ const items = {
   "pages.workspace.home.title": "Welcome to WikiPali",
   "pages.team.title": "Team",
   "pages.task.project.title": "Project",
+  "pages.task.show.title": "Task",
   "pages.tipitaka.chapter.title": "Chapter",
   "pages.tipitaka.para.title": "Paragraph",
   "pages.tipitaka.cs-para.title": "CS Paragraph",

+ 1 - 0
dashboard-v6/src/locales/zh-Hans/pages.ts

@@ -9,6 +9,7 @@ const items = {
   "pages.workspace.home.title": "欢迎来到wikipali",
   "pages.team.title": "团队",
   "pages.task.project.title": "项目",
+  "pages.task.show.title": "任务",
   "pages.tipitaka.chapter.title": "章节",
   "pages.tipitaka.para.title": "段落",
   "pages.tipitaka.cs-para.title": "CS段落",

+ 27 - 0
dashboard-v6/src/pages/workspace/task/show.tsx

@@ -0,0 +1,27 @@
+// 任务详情页面
+import { useMatches, useParams } from "react-router";
+import { useIntl } from "react-intl";
+
+import Task from "../../../components/task/Task";
+
+const Widget = () => {
+  const { taskId } = useParams();
+  const intl = useIntl();
+  const matches = useMatches() as {
+    data?: { title?: string; name?: string; word?: string };
+  }[];
+  const data = [...matches].reverse().find((m) => m.data)?.data;
+  const name = data?.title ?? data?.name ?? data?.word;
+  const prefix = intl.formatMessage({ id: "pages.task.show.title" });
+
+  return (
+    <>
+      <title>{name ? `${prefix}-${name}` : prefix}</title>
+      <div style={{ maxWidth: 1000, margin: "0 auto" }}>
+        <Task taskId={taskId} />
+      </div>
+    </>
+  );
+};
+
+export default Widget;

+ 11 - 1
dashboard-v6/src/routes/taskRouters.ts

@@ -1,7 +1,7 @@
 // src/routes/taskRouters.ts
 import { lazy } from "react";
 import type { RouteObject } from "react-router";
-import { projectLoader } from "../api/task";
+import { projectLoader, taskLoader } from "../api/task";
 
 // 懒加载页面组件
 const hall = lazy(() => import("../pages/workspace/task/hall"));
@@ -11,6 +11,7 @@ const projects = lazy(() => import("../pages/workspace/task/projects"));
 const project = lazy(() => import("../pages/workspace/task/project"));
 const projectEdit = lazy(() => import("../pages/workspace/task/project-edit"));
 const workflows = lazy(() => import("../pages/workspace/task/workflow"));
+const show = lazy(() => import("../pages/workspace/task/show"));
 
 const taskRoutes: RouteObject[] = [
   {
@@ -32,6 +33,15 @@ const taskRoutes: RouteObject[] = [
         Component: list,
         handle: { id: "workspace.task.list", crumb: "list" },
       },
+      {
+        path: ":taskId",
+        Component: show,
+        loader: taskLoader,
+        handle: {
+          id: "workspace.task.show",
+          crumb: (match: { data: { title: string } }) => match.data.title,
+        },
+      },
       {
         path: "project",
         handle: { id: "workspace.task.project", crumb: "project" },