From 4fe1f1838aa8a92d9d131b799ec5d5cf1e0a444d Mon Sep 17 00:00:00 2001 From: wulibaibao <13366578180@163.com> Date: Thu, 14 Apr 2022 16:06:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B5=8B=E8=AF=95=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=B0=E5=A2=9E=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Loading.tsx | 1 + src/components/Public/StateTag.tsx | 74 ++++--- src/components/RichTextEditor/index.tsx | 1 + src/pages/Plan/CreatePage.tsx | 123 ++++++++++++ .../components/ContentTable/Suite.table.tsx | 69 +++++-- .../components/ContentTable/Task.table.tsx | 46 ++++- src/pages/Plan/components/LeftList/index.tsx | 67 ++++--- .../components/RightContent/EditContent.tsx | 47 ----- .../Plan/components/RightContent/index.tsx | 186 ++++++++++++++---- .../components/SelectModal/Suite.selet.tsx | 22 ++- .../components/SelectModal/Task.select.tsx | 10 +- src/pages/Plan/index.tsx | 125 ++++-------- src/pages/Plan/services.ts | 8 + 13 files changed, 509 insertions(+), 270 deletions(-) create mode 100644 src/pages/Plan/CreatePage.tsx delete mode 100644 src/pages/Plan/components/RightContent/EditContent.tsx diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx index ddb61fa..22f9ab0 100644 --- a/src/components/Loading.tsx +++ b/src/components/Loading.tsx @@ -9,6 +9,7 @@ const LoadingWrapper = styled(Row)` bottom: 0; top: 0; background: #fff; + z-index: 100; padding-top: 300px; ` const Loading: React.FC = () => ( diff --git a/src/components/Public/StateTag.tsx b/src/components/Public/StateTag.tsx index 61010df..9798ca1 100644 --- a/src/components/Public/StateTag.tsx +++ b/src/components/Public/StateTag.tsx @@ -2,43 +2,69 @@ import React from "react" import { Tag } from "antd" type IProps = { - state: string + status: string } -const stateWordsMap = new Map([ - ["success", "新建"], - ["success1", "分析中"], - ["success2", "评审中"], - ["success3", "已评审"], - ["success4", "运行中"], - ["success5", "已完成"], -]) +export const stateWordsMap = new Map([ + ["analysing", "分析中"], + ["reviewing", "评审中"], + ["accepted", "已接受"], + ["refused", "已拒绝"], + + ["init", "初始化"], + ["waiting", "等待中"], + ["starting", "开始中"], + ["running", "运行中"], + ["stopping", "停止中"], + ["pedding", "待定中"], + + ["finish", "已完成"], + ["stopped", "已停止"], + ["pause", "暂停"], + ["skip", "跳过"], + ["cancel", "取消"], -const stateColorMap = new Map([ - ["success", "#1890FF"], - ["success1", "#FAAD15"], - ["success2", "#FAAD15"], - ["success3", "#22BC3D"], - ["success4", "#22BC3D"], - ["success5", "rgba(0,0,0,.3)"], + ["success", "成功"], + ["fail", "失败"], + ["error", "错误"], + ["ignore", "忽略"], + + ["online", "在线"], + ["offline", "下线"], + ["uninstalling", "卸载中"], + ["installing", "下载中"], ]) -const StateTag: React.FC = (props) => { - const { state } = props +export const planStatusMap = (state: any) => new Map([ + ["running", { "color": "rgba(24,144,255,1)", "background": "rgba(24,144,255,.1)" }], + ["reviewing", { "color": "rgba(24,144,255,1)", "background": "rgba(24,144,255,.1)" }], + + ["finish", { "color": "rgba(34,188,61,1)", "background": "rgba(34,188,61,.1)" }], + ["accepted", { "color": "rgba(34,188,61,1)", "background": "rgba(34,188,61,.1)" }], + ["success", { "color": "rgba(34,188,61,1)", "background": "rgba(34,188,61,.1)" }], + + ["analysing", { "color": "rgba(250,173,21,1)", "background": "rgba(250,173,21,.1)" }], + ["pedding", { "color": "rgba(250,173,21,1)", "background": "rgba(250,173,21,.1)" }], + + ["refused", { "color": "rgba(255,77,79,1)", "background": "rgba(255,77,79,.1)" }], + ["fail", { "color": "rgba(255,77,79,1)", "background": "rgba(255,77,79,.1)" }], + ["error", { "color": "rgba(255,77,79,1)", "background": "rgba(255,77,79,.1)" }], +]).get(state) || { "color": "rgba(0,0,0,0.45)", "background": "rgba(0,0,0,0.03)" } + +export const StateTag: React.FC = (props) => { + const { status } = props return ( - {stateWordsMap.get(state)} + {stateWordsMap.get(status)} ) -} - -export default StateTag \ No newline at end of file +} \ No newline at end of file diff --git a/src/components/RichTextEditor/index.tsx b/src/components/RichTextEditor/index.tsx index e70aadc..ed995e5 100644 --- a/src/components/RichTextEditor/index.tsx +++ b/src/components/RichTextEditor/index.tsx @@ -30,6 +30,7 @@ const RichTextEditor: React.FC = (props) => { ...config, placeholder: "请输入内容", MENU_CONF: { + }, onCreated(vm) { const tb = createToolbar({ diff --git a/src/pages/Plan/CreatePage.tsx b/src/pages/Plan/CreatePage.tsx new file mode 100644 index 0000000..747431a --- /dev/null +++ b/src/pages/Plan/CreatePage.tsx @@ -0,0 +1,123 @@ +import React from "react" +import { Table, Space, Typography, Row, Button, Col, Spin, Form, message, Input, Select } from "antd" +import { createTestPlan, queryTestPlanList, updateTestPlanDetail } from "./services" +import Loading from "@/components/Loading" +import { history, request, useParams, useRequest } from "umi" +import RichTextEditor from "@/components/RichTextEditor" + +import SuiteTable from "@/pages/Plan/components/ContentTable/Suite.table" +import TaskTable from "@/pages/Plan/components/ContentTable/Task.table" +import { CustomForm } from "@/components/CustomStyled" +import { usePlanProvider } from "./hooks" +/** + * + * 测试方案 + * + */ + +type IProps = { + [k: string]: any; +} + +const TestPlan: React.FC = (props) => { + const { refresh } = usePlanProvider() + const { plan_id } = useParams() as any + const { source, onOk } = props + const [form] = Form.useForm() + console.log(props, plan_id) + + React.useEffect(() => { + if (source && JSON.stringify(source) !== "{}") { + const { req_id, title } = source + form.setFieldsValue({ req_id, title }) + } + }, [source]) + + const [baseData, setBaseData] = React.useState({}) + + const { data: requirement, run } = useRequest(() => request(`/api/requirement`), { initialData: [], manual: true }) + + React.useEffect(() => { + run() + }, []) + + const handleSave = () => { + form.validateFields() + .then(async (values) => { + const params = { ...baseData, ...values, reviewers: "xxxx" } + const isEditPage = plan_id && source + const { data, code, msg } = isEditPage ? + await updateTestPlanDetail(plan_id, params) : + await createTestPlan(params) + if (code !== 200) { + message.error(msg) + return + } + if (isEditPage) { + onOk() + refresh() + message.success("操作成功") + } + else + history.push(`/plan/${data.id}`) + }) + } + + return ( +
+ + + 新建方案 + + + 基础信息 + + + + + + - - - - - - - - - - - - - 描述 -
- -
-
-
-
- ) -} - -export default PlanRighttEditContent \ No newline at end of file diff --git a/src/pages/Plan/components/RightContent/index.tsx b/src/pages/Plan/components/RightContent/index.tsx index d8e60f8..895a405 100644 --- a/src/pages/Plan/components/RightContent/index.tsx +++ b/src/pages/Plan/components/RightContent/index.tsx @@ -1,54 +1,156 @@ -import React from "react"; -import { Space, Row, Typography, Button, Form, Input, Select, Card } from "antd" +import React, { useState } from "react"; +import { Space, Row, Typography, Button, Empty, Menu, Dropdown, Avatar, Divider, Col, message } from "antd" import RichTextEditor from "@/components/RichTextEditor"; +import { history, useParams, useRequest } from "umi"; +import { deleteTestPlan, queryTestPlanDetail } from "../../services"; +import Loading from "@/components/Loading"; +import { createEditor } from "@wangeditor/editor" +import SuiteTable from "@/pages/Plan/components/ContentTable/Suite.table" +import TaskTable from "@/pages/Plan/components/ContentTable/Task.table" +import styled from "styled-components" +import Logo from "@/assets/logo.png" +import { ReactComponent as Priority } from "@/assets/case/priority.svg" +import { stateWordsMap } from "@/components/Public/StateTag" +import { MoreOutlined } from "@ant-design/icons" +import CreatePage from "@/pages/Plan/CreatePage" type IProps = { [k: string]: any; } +const PriorityAvatar = styled.div` + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + overflow: hidden; +` + const PlanRightContent: React.FC = () => { + const { plan_id } = useParams() as any + + const [edit, setEdit] = useState(false) + const { data, run, refresh } = useRequest(queryTestPlanDetail, { manual: true, initialData: null }) + + React.useEffect(() => { + if (plan_id) + run(plan_id) + }, [plan_id]) + + const handleMenuClick = (e: any) => { + switch (e.key) { + case "delete": return handleDelete() + } + return + } + + const handleDelete = async () => { + const { code, msg } = await deleteTestPlan(plan_id) + if (code !== 200) return message.error(msg) + history.push(`/plan`) + message.success("操作成功!") + } + + const handleEditOk = () => { + setEdit(false) + refresh() + } + + if (edit) + return + + if (plan_id && !data) return + + if (!plan_id) return ( + + + + ) - const [form] = Form.useForm() return ( - - - - - 基础信息 - - -
- - - - - - - -
-
- - - - 描述 - -
- -
-
- - 选择用例}> - - - - 选择任务}> - - -
+ + + + + 创建于 + {data.gmt_created} + + + 更新于 + {data.gmt_modified} + + + + + + + 删除 + + + } + > + + + + + + + + + {data.title} + + + + + + + + {data?.owner} + 负责人 + + + + + + + + + + {stateWordsMap.get(data?.status)} + 状态 + + + + + + + + + 基础信息 + + + + 测试需求 + {data.req_id} + + + + + + 描述 + +
+ + + ) } diff --git a/src/pages/Plan/components/SelectModal/Suite.selet.tsx b/src/pages/Plan/components/SelectModal/Suite.selet.tsx index 67814ca..1a045d1 100644 --- a/src/pages/Plan/components/SelectModal/Suite.selet.tsx +++ b/src/pages/Plan/components/SelectModal/Suite.selet.tsx @@ -29,13 +29,12 @@ const ReactComponent: React.ForwardRefRenderFunction = (props, re const [visible, setVisible] = React.useState(false) const [loading, setLoading] = React.useState(false) - const [source, setSource] = React.useState(undefined) React.useImperativeHandle(ref, () => ({ show(_: any) { - setSource(_) + setSelectedKeys(_) + setCheckAll(_.length === cases.length) setVisible(true) - form.setFieldsValue(_) } })) @@ -57,12 +56,9 @@ const ReactComponent: React.ForwardRefRenderFunction = (props, re setCheckAll(list.length === allCaseId.length); } - const [form] = Form.useForm() - const handleCancel = () => { setVisible(false) setLoading(false) - setSource(undefined) setSelectedKeys([]) setIndeterminate(false) setCheckAll(false) @@ -81,15 +77,19 @@ const ReactComponent: React.ForwardRefRenderFunction = (props, re setSelectedKeys([]) } + const handleKeyup = (e: any) => { + + } + return ( - {`共${allCaseId.length}条 已选中${selectedKeys.length}条`} + {`共${allCaseId.length}条`} @@ -100,7 +100,11 @@ const ReactComponent: React.ForwardRefRenderFunction = (props, re onCancel={handleCancel} > - +
= (props, re const [visible, setVisible] = React.useState(false) const [loading, setLoading] = React.useState(false) - const [source, setSource] = React.useState(undefined) const [selectedKeys, setSelectedKeys] = React.useState([]) const { data: taskList, loading: taskLoading } = useRequest(queryTaskList, { initialData: [] }) React.useImperativeHandle(ref, () => ({ show(_: any) { - setSource(_) + setSelectedKeys(_) setVisible(true) - form.setFieldsValue(_) } })) - const [form] = Form.useForm() - const handleCancel = () => { setVisible(false) setLoading(false) - setSource(undefined) + setSelectedKeys([]) } const handleOk = async () => { if (loading) return setLoading(true) - onOk([]) + onOk(taskList.filter((i: any) => selectedKeys.includes(i.id))) handleCancel() } diff --git a/src/pages/Plan/index.tsx b/src/pages/Plan/index.tsx index 1e48876..8698c9d 100644 --- a/src/pages/Plan/index.tsx +++ b/src/pages/Plan/index.tsx @@ -1,20 +1,16 @@ import React from "react" -import { Table, Space, Typography, Row, Button, Col, Spin, Form, message, Input, Select } from "antd" -import { createTestPlan, queryTestPlanList } from "./services" -import { useRequest } from "umi" -import AddModal from "./components/AddModal" +import { Row, Spin, } from "antd" +import { queryTestPlanList } from "./services" import LeftList from "./components/LeftList" -import RightContent from "./components/RightContent" -import EditContent from "./components/RightContent/EditContent" +// import EditContent from "./components/RightContent/EditContent" import { Provider as PlanPageProvider } from "./hooks" import Loading from "@/components/Loading" -import { history, request, useParams } from "umi" -import RichTextEditor from "@/components/RichTextEditor" +import { history, useParams, useRequest } from "umi" + +const CreatePage = React.lazy(() => import("@/pages/Plan/CreatePage")) +const RightContent = React.lazy(() => import("@/pages/Plan/components/RightContent")) -import SuiteTable from "@/pages/Plan/components/ContentTable/Suite.table" -import TaskTable from "@/pages/Plan/components/ContentTable/Task.table" -import { CustomForm } from "@/components/CustomStyled" /** * * 测试方案 @@ -26,94 +22,41 @@ type IProps = { } const TestPlan: React.FC = (props) => { - const [form] = Form.useForm() - const { data: requirement } = useRequest(() => request(`/api/requirement`), { initialData: [] }) - - const handleSave = () => { - form.validateFields() - .then(async (values) => { - const { code, msg } = await createTestPlan(values) - if (code !== 200) { - message.error(msg) - return - } - }) - } - - const requirementList = React.useMemo(() => { - if (requirement) - return requirement.map((i: any) => ({ label: i.title, value: i.id })) - return [] - }, [requirement]) - - return ( -
- - - 新建方案 - - - 基础信息 - - - - - -