Commit f69316a2 authored by rocosen's avatar rocosen

Merge branch 'release' into feat-jobList

parents 710fd2a6 3d3954b0
...@@ -1437,17 +1437,48 @@ ...@@ -1437,17 +1437,48 @@
"integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ=="
}, },
"@emotion/react": { "@emotion/react": {
"version": "11.9.0", "version": "11.9.3",
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.9.0.tgz", "resolved": "https://registry.npmmirror.com/@emotion/react/-/react-11.9.3.tgz",
"integrity": "sha512-lBVSF5d0ceKtfKCDQJveNAtkC7ayxpVlgOohLgXqRwqWr9bOf4TZAFFyIcNngnV6xK6X4x2ZeXq7vliHkoVkxQ==", "integrity": "sha512-g9Q1GcTOlzOEjqwuLF/Zd9LC+4FljjPjDfxSM7KmEakm+hsHXk+bYZ2q+/hTJzr0OUNkujo72pXLQvXj6H+GJQ==",
"requires": { "requires": {
"@babel/runtime": "^7.13.10", "@babel/runtime": "^7.13.10",
"@emotion/babel-plugin": "^11.7.1", "@emotion/babel-plugin": "^11.7.1",
"@emotion/cache": "^11.7.1", "@emotion/cache": "^11.9.3",
"@emotion/serialize": "^1.0.3", "@emotion/serialize": "^1.0.4",
"@emotion/utils": "^1.1.0", "@emotion/utils": "^1.1.0",
"@emotion/weak-memoize": "^0.2.5", "@emotion/weak-memoize": "^0.2.5",
"hoist-non-react-statics": "^3.3.1" "hoist-non-react-statics": "^3.3.1"
},
"dependencies": {
"@emotion/cache": {
"version": "11.9.3",
"resolved": "https://registry.npmmirror.com/@emotion/cache/-/cache-11.9.3.tgz",
"integrity": "sha512-0dgkI/JKlCXa+lEXviaMtGBL0ynpx4osh7rjOXE71q9bIF8G+XhJgvi+wDu0B0IdCVx37BffiwXlN9I3UuzFvg==",
"requires": {
"@emotion/memoize": "^0.7.4",
"@emotion/sheet": "^1.1.1",
"@emotion/utils": "^1.0.0",
"@emotion/weak-memoize": "^0.2.5",
"stylis": "4.0.13"
}
},
"@emotion/serialize": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/@emotion/serialize/-/serialize-1.0.4.tgz",
"integrity": "sha512-1JHamSpH8PIfFwAMryO2bNka+y8+KA5yga5Ocf2d7ZEiJjb7xlLW7aknBGZqJLajuLOvJ+72vN+IBSwPlXD1Pg==",
"requires": {
"@emotion/hash": "^0.8.0",
"@emotion/memoize": "^0.7.4",
"@emotion/unitless": "^0.7.5",
"@emotion/utils": "^1.0.0",
"csstype": "^3.0.2"
}
},
"@emotion/sheet": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/@emotion/sheet/-/sheet-1.1.1.tgz",
"integrity": "sha512-J3YPccVRMiTZxYAY0IOq3kd+hUP8idY8Kz6B/Cyo+JuXq52Ek+zbPbSQUrVQp95aJ+lsAW7DPL1P2Z+U1jGkKA=="
}
} }
}, },
"@emotion/serialize": { "@emotion/serialize": {
...@@ -4126,6 +4157,11 @@ ...@@ -4126,6 +4157,11 @@
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
}, },
"classcat": {
"version": "5.0.3",
"resolved": "https://registry.npmmirror.com/classcat/-/classcat-5.0.3.tgz",
"integrity": "sha512-6dK2ke4VEJZOFx2ZfdDAl5OhEL8lvkl6EHF92IfRePfHxQTqir5NlcNVUv+2idjDqCX2NDc8m8YSAI5NI975ZQ=="
},
"classnames": { "classnames": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.1.tgz", "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.1.tgz",
...@@ -4679,6 +4715,72 @@ ...@@ -4679,6 +4715,72 @@
"resolved": "https://registry.npmmirror.com/custom-error-instance/-/custom-error-instance-2.1.1.tgz", "resolved": "https://registry.npmmirror.com/custom-error-instance/-/custom-error-instance-2.1.1.tgz",
"integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==" "integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg=="
}, },
"d3-color": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz",
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="
},
"d3-dispatch": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="
},
"d3-drag": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-drag/-/d3-drag-3.0.0.tgz",
"integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
"requires": {
"d3-dispatch": "1 - 3",
"d3-selection": "3"
}
},
"d3-ease": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-ease/-/d3-ease-3.0.1.tgz",
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="
},
"d3-interpolate": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
"requires": {
"d3-color": "1 - 3"
}
},
"d3-selection": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz",
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="
},
"d3-timer": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-timer/-/d3-timer-3.0.1.tgz",
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="
},
"d3-transition": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-transition/-/d3-transition-3.0.1.tgz",
"integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
"requires": {
"d3-color": "1 - 3",
"d3-dispatch": "1 - 3",
"d3-ease": "1 - 3",
"d3-interpolate": "1 - 3",
"d3-timer": "1 - 3"
}
},
"d3-zoom": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz",
"integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
"requires": {
"d3-dispatch": "1 - 3",
"d3-drag": "2 - 3",
"d3-interpolate": "1 - 3",
"d3-selection": "2 - 3",
"d3-transition": "2 - 3"
}
},
"damerau-levenshtein": { "damerau-levenshtein": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
...@@ -10242,6 +10344,29 @@ ...@@ -10242,6 +10344,29 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
}, },
"react-flow-renderer": {
"version": "10.3.7",
"resolved": "https://registry.npmmirror.com/react-flow-renderer/-/react-flow-renderer-10.3.7.tgz",
"integrity": "sha512-0WGyozT4SzMpim8MQRFBR8hqm11FGApXm+UD05BoAejhcUgohvmckBTRIQKxzGC2WQLR/6oXRzwzRYGQdrb4rw==",
"requires": {
"@babel/runtime": "^7.18.0",
"classcat": "^5.0.3",
"d3-drag": "^3.0.0",
"d3-selection": "^3.0.0",
"d3-zoom": "^3.0.0",
"zustand": "^3.7.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.18.3",
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.18.3.tgz",
"integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"react-is": { "react-is": {
"version": "17.0.2", "version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
...@@ -11478,6 +11603,16 @@ ...@@ -11478,6 +11603,16 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}, },
"tss-react": {
"version": "3.7.0",
"resolved": "https://registry.npmmirror.com/tss-react/-/tss-react-3.7.0.tgz",
"integrity": "sha512-thvJWR+sr3ZGMcV/Ryo1F5RzjXd1gMTzYV/ckfUEBhu701uTYE3KyL9DNxv827uRFPFSLYG7bKefuc7kmYMB9Q==",
"requires": {
"@emotion/cache": "*",
"@emotion/serialize": "*",
"@emotion/utils": "*"
}
},
"tsutils": { "tsutils": {
"version": "3.21.0", "version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
...@@ -11838,7 +11973,7 @@ ...@@ -11838,7 +11973,7 @@
}, },
"webpack-dev-server": { "webpack-dev-server": {
"version": "4.9.0", "version": "4.9.0",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.0.tgz", "resolved": "https://registry.npmmirror.com/webpack-dev-server/-/webpack-dev-server-4.9.0.tgz",
"integrity": "sha512-+Nlb39iQSOSsFv0lWUuUTim3jDQO8nhK3E68f//J2r5rIcp4lULHXz2oZ0UVdEeWXEh5lSzYUlzarZhDAeAVQw==", "integrity": "sha512-+Nlb39iQSOSsFv0lWUuUTim3jDQO8nhK3E68f//J2r5rIcp4lULHXz2oZ0UVdEeWXEh5lSzYUlzarZhDAeAVQw==",
"requires": { "requires": {
"@types/bonjour": "^3.5.9", "@types/bonjour": "^3.5.9",
...@@ -12398,6 +12533,11 @@ ...@@ -12398,6 +12533,11 @@
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
},
"zustand": {
"version": "3.7.2",
"resolved": "https://registry.npmmirror.com/zustand/-/zustand-3.7.2.tgz",
"integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA=="
} }
} }
} }
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
"react-dev-utils": "^12.0.1", "react-dev-utils": "^12.0.1",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"react-dropzone": "^14.2.1", "react-dropzone": "^14.2.1",
"react-flow-renderer": "^10.3.7",
"react-refresh": "^0.11.0", "react-refresh": "^0.11.0",
"react-router-dom": "^6.3.0", "react-router-dom": "^6.3.0",
"resolve": "^1.20.0", "resolve": "^1.20.0",
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-13 09:56:57 * @Date: 2022-06-13 09:56:57
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-13 09:59:29 * @LastEditTime: 2022-07-07 18:19:20
* @FilePath: /bkunyun/src/api/api_manager.ts * @FilePath: /bkunyun/src/api/api_manager.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
...@@ -29,17 +29,14 @@ const RESTAPI = { ...@@ -29,17 +29,14 @@ const RESTAPI = {
API_WORKBENCH_DELETE_TEMPLATE: `${BACKEND_API_URI_PREFIX}/cpp/workbench/project/workflowspec`, //项目管理员-删除工作流模板 API_WORKBENCH_DELETE_TEMPLATE: `${BACKEND_API_URI_PREFIX}/cpp/workbench/project/workflowspec`, //项目管理员-删除工作流模板
API_WORKBENCH_ADD_TEMPLATE_LIST: `${BACKEND_API_URI_PREFIX}/cpp/workbench/product/workflowspec`, //项目管理员-添加工作流模板-模板列表 API_WORKBENCH_ADD_TEMPLATE_LIST: `${BACKEND_API_URI_PREFIX}/cpp/workbench/product/workflowspec`, //项目管理员-添加工作流模板-模板列表
API_WORKBENCH_ADD_TEMPLATE: `${BACKEND_API_URI_PREFIX}/cpp/workbench/project/workflowspec`, //项目管理员-添加工作流模板-提交 API_WORKBENCH_ADD_TEMPLATE: `${BACKEND_API_URI_PREFIX}/cpp/workbench/project/workflowspec`, //项目管理员-添加工作流模板-提交
API_FETCH_TEMPLATE_INFO: `${BACKEND_API_URI_PREFIX}/cpp/workbench/workflowspec`, //点击使用模版查看模版详情
API_WORK_FLOW_JOB: `${BACKEND_API_URI_PREFIX}/cpp/workbench/workflowjob`, //点击任务列表查看任务详情
API_WORKBENCH_WORKFLOWJOB_LIST: `${BACKEND_API_URI_PREFIX}/cpp/workbench/project/workflowjob`, //查询工作流任务 API_WORKBENCH_WORKFLOWJOB_LIST: `${BACKEND_API_URI_PREFIX}/cpp/workbench/project/workflowjob`, //查询工作流任务
API_WORKBENCH_DEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/job/`, //删除工作流任务 API_WORKBENCH_DEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/job/`, //删除工作流任务
API_WORKBENCH_CANCEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/cancel`, //取消工作流 API_WORKBENCH_CANCEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/cancel`, //取消工作流
API_SUBMIT_WORKFLOW: `${BACKEND_API_URI_PREFIX}/cpp/workflow/submit`, //提交工作流
API_WORKBENCH_WORKFLOW_TASKINFO: `${BACKEND_API_URI_PREFIX}/cpp/workbench/workflowjob/task-info`, //查询任务某个算子详情
API_OPERATOR_LIST:`${BACKEND_API_URI_PREFIX}/cpp/workflow/actorspecs`, // 获取算子列表
}; };
export default RESTAPI; export default RESTAPI;
...@@ -176,7 +176,7 @@ export function useHttp(raw?: boolean) { ...@@ -176,7 +176,7 @@ export function useHttp(raw?: boolean) {
export default rawHttp; export default rawHttp;
export interface IResponse<T> { export interface IResponse<T> {
errorCode: number; errorCode?: number;
massage: string; massage?: string;
data: T; data: T;
} }
...@@ -21,7 +21,7 @@ type projectListParams = { ...@@ -21,7 +21,7 @@ type projectListParams = {
}; };
// 查询当前用户可以看到的项目列表 // 查询当前用户可以看到的项目列表
const product = (params: projectListParams) => { const getProjectList = (params: projectListParams) => {
return request({ return request({
url: Api.API_PROJECT_LIST, url: Api.API_PROJECT_LIST,
method: "get", method: "get",
...@@ -202,10 +202,51 @@ const getDataFileDelPackage = (params: getDataFileDelPackageParams) => { ...@@ -202,10 +202,51 @@ const getDataFileDelPackage = (params: getDataFileDelPackageParams) => {
}); });
}; };
// 点击使用模版,获取模版数据
const fetchTemplateConfigInfo = (params: { id: string }) => {
return request({
url: `${Api.API_FETCH_TEMPLATE_INFO}/${params.id}`,
method: "get",
});
};
// 点击工作列表,查看工作流详情
const fetchWorkFlowJob = (params: { id: string }) => {
return request({
url: `${Api.API_WORK_FLOW_JOB}/${params.id}`,
method: "get",
});
};
type submitWorkFlowParams = {
name: string;
projectId: string;
specId: string;
outputPath: string;
promotedParameters: any;
};
// 提交工作流
const submitWorkFlow = (params: submitWorkFlowParams) => {
return request({
url: Api.API_SUBMIT_WORKFLOW,
method: "post",
data: params,
});
};
// 查询任务某个算子详情
const getworkFlowTaskInfo = (params: { jobId: string; taskId: string }) => {
return request({
url: `${Api.API_WORKBENCH_WORKFLOW_TASKINFO}?jobId=${params.jobId}&taskId=${params.taskId}`,
method: "get",
});
};
export { export {
current, current,
menu, menu,
product, getProjectList,
hpczone, hpczone,
addProject, addProject,
getProject, getProject,
...@@ -218,4 +259,8 @@ export { ...@@ -218,4 +259,8 @@ export {
getDataFileMovePackage, getDataFileMovePackage,
getDataFileDel, getDataFileDel,
getDataFileDelPackage, getDataFileDelPackage,
fetchTemplateConfigInfo,
fetchWorkFlowJob,
submitWorkFlow,
getworkFlowTaskInfo,
}; };
export interface IGetOperatorList {
owner: string;
productId: string;
keyword?: string
}
\ No newline at end of file
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-07-05 14:00:37
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-07 18:24:16
* @FilePath: /bkunyun/src/api/workbench_api.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import request from "@/utils/axios/service"; import request from "@/utils/axios/service";
import Api from "./api_manager"; import Api from "./api_manager";
import { IGetOperatorList } from "./workbenchInterface";
function current() { function current() {
return request({ return request({
...@@ -119,6 +128,15 @@ const cancelWorkflowJob = (params: workflowJobCancelParams) => { ...@@ -119,6 +128,15 @@ const cancelWorkflowJob = (params: workflowJobCancelParams) => {
}); });
}; };
// 获取算子列表数据
const fetchOperatorList = (params: IGetOperatorList) => {
return request({
url: Api.API_OPERATOR_LIST,
method: "get",
params,
});
};
export { export {
current, current,
menu, menu,
...@@ -128,5 +146,6 @@ export { ...@@ -128,5 +146,6 @@ export {
addWorkbenchTemplate, addWorkbenchTemplate,
getWorkflowJobList, getWorkflowJobList,
deleteWorkflowJob, deleteWorkflowJob,
cancelWorkflowJob cancelWorkflowJob,
fetchOperatorList
}; };
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 6备份 5</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-25">
<rect id="矩形" x="0" y="0" width="20" height="20"></rect>
<g id="编组-32" transform="translate(0.533333, 3.452381)">
<path d="M8.36688938,0.416666667 L9.55313606,1.36249983 C9.81887602,1.6286558 10.1795465,1.77821568 10.5556538,1.77821568 L10.5556538,1.77821568 L14.8884238,1.77821568 L15.4717571,5.1407542 L8.77799689,5.3817735 L2.18238271,5.25717634 L2.18238271,1 L8.36688938,0.416666667 Z" id="路径-7" stroke="#8A9099" stroke-width="0.833333333" fill="#EBEDF0"></path>
<path d="M1.19361766,4.3897647 L17.7662846,4.3897647 C18.3185693,4.3897647 18.7662846,4.83747995 18.7662846,5.3897647 C18.7662846,5.43928252 18.7626065,5.48873196 18.7552809,5.53770491 L17.7437151,12.3001318 C17.6704625,12.7898332 17.2498687,13.1521916 16.7547187,13.1521916 L2.39674962,13.1521916 C1.91203684,13.1521916 1.49711429,12.804574 1.41221027,12.3273551 L0.209078316,5.56492826 C0.112338155,5.02118219 0.474708039,4.50196551 1.01845411,4.40522535 C1.07627469,4.39493825 1.1348891,4.3897647 1.19361766,4.3897647 Z" id="矩形" fill="#8A9099"></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>1.Base基础/Icon图标/全屏</title>
<defs>
<rect id="path-1" x="0" y="0" width="16" height="16"></rect>
<filter color-interpolation-filters="auto" id="filter-3">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0.337255 0 0 0 0 0.362353 0 0 0 0 0.400000 0 0 0 1.000000 0"></feColorMatrix>
</filter>
</defs>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="工作台(使用模版)" transform="translate(-1393.000000, -1979.000000)">
<g id="编组备份-2" transform="translate(1384.000000, 1970.000000)">
<g id="1.Base基础/Icon图标/全屏" transform="translate(8.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g filter="url(#filter-3)" id="编组">
<g mask="url(#mask-2)">
<g transform="translate(-1.000000, -1.000000)">
<g id="编组-63" transform="translate(12.706359, 5.236359) rotate(-315.000000) translate(-12.706359, -5.236359) translate(9.176029, 1.361359)">
<path d="M3.97654174,0.147051761 L4.06066017,0.219669914 L7.06066017,3.21966991 L6,4.28033009 L4.28,2.561 L4.28033009,7.75 L2.78033009,7.75 L2.78,2.561 L1.06066017,4.28033009 L6.61983662e-13,3.21966991 L3,0.219669914 C3.26626656,-0.0465966484 3.68293025,-0.0708026996 3.97654174,0.147051761 Z" id="形状结合" fill="#565C66" fill-rule="nonzero"></path>
</g>
<g id="编组-63备份" transform="translate(5.236359, 12.706359) scale(-1, -1) rotate(-315.000000) translate(-5.236359, -12.706359) translate(1.706029, 8.831359)">
<path d="M3.97654174,0.147051761 L4.06066017,0.219669914 L7.06066017,3.21966991 L6,4.28033009 L4.28,2.561 L4.28033009,7.75 L2.78033009,7.75 L2.78,2.561 L1.06066017,4.28033009 L2.55455517e-12,3.21966991 L3,0.219669914 C3.26626656,-0.0465966484 3.68293025,-0.0708026996 3.97654174,0.147051761 Z" id="形状结合" fill="#565C66" fill-rule="nonzero"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>information-outline</title>
<g id="云平台视觉规范" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Feedback-反馈" transform="translate(-375.000000, -1027.000000)" fill="#1370FF" fill-rule="nonzero">
<g id="编组-17" transform="translate(355.000000, 1007.000000)">
<g id="information-outline" transform="translate(20.000000, 20.000000)">
<path d="M7.2,5.6 L8.8,5.6 L8.8,4 L7.2,4 M8,14.4 C4.472,14.4 1.6,11.528 1.6,8 C1.6,4.472 4.472,1.6 8,1.6 C11.528,1.6 14.4,4.472 14.4,8 C14.4,11.528 11.528,14.4 8,14.4 M8,-3.55271368e-16 C3.581722,-3.55271368e-16 -3.55271368e-16,3.581722 -3.55271368e-16,8 C-3.55271368e-16,10.1217319 0.842854723,12.1565632 2.34314575,13.6568542 C3.84343678,15.1571453 5.87826808,16 8,16 C10.1217319,16 12.1565632,15.1571453 13.6568542,13.6568542 C15.1571453,12.1565632 16,10.1217319 16,8 C16,5.87826808 15.1571453,3.84343678 13.6568542,2.34314575 C12.1565632,0.842854723 10.1217319,-3.55271368e-16 8,-3.55271368e-16 M7.2,12 L8.8,12 L8.8,7.2 L7.2,7.2 L7.2,12 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>1.Base基础/Icon图标/全屏</title>
<defs>
<rect id="path-1" x="0" y="0" width="16" height="16"></rect>
<filter color-interpolation-filters="auto" id="filter-3">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0.337255 0 0 0 0 0.362353 0 0 0 0 0.400000 0 0 0 1.000000 0"></feColorMatrix>
</filter>
</defs>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="全屏" transform="translate(-1393.000000, -873.000000)">
<g id="编组备份" transform="translate(1384.000000, 864.000000)">
<g id="1.Base基础/Icon图标/全屏" transform="translate(8.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g filter="url(#filter-3)" id="编组">
<g mask="url(#mask-2)">
<g transform="translate(-1.000000, -1.000000)">
<g id="编组-63" transform="translate(12.706359, 5.236359) rotate(-315.000000) translate(-12.706359, -5.236359) translate(9.176029, 1.361359)">
<path d="M3.97654174,0.147051761 L4.06066017,0.219669914 L7.06066017,3.21966991 L6,4.28033009 L4.28,2.561 L4.28033009,7.75 L2.78033009,7.75 L2.78,2.561 L1.06066017,4.28033009 L-5.89740035e-13,3.21966991 L3,0.219669914 C3.26626656,-0.0465966484 3.68293025,-0.0708026996 3.97654174,0.147051761 Z" id="形状结合" fill="#565C66" fill-rule="nonzero" transform="translate(3.530330, 3.875000) rotate(-180.000000) translate(-3.530330, -3.875000) "></path>
</g>
<g id="编组-63备份" transform="translate(5.236359, 12.706359) scale(-1, -1) rotate(-135.000000) translate(-5.236359, -12.706359) translate(1.706029, 8.831359)">
<path d="M3.97654174,0.147051761 L4.06066017,0.219669914 L7.06066017,3.21966991 L6,4.28033009 L4.28,2.561 L4.28033009,7.75 L2.78033009,7.75 L2.78,2.561 L1.06066017,4.28033009 L2.55455517e-12,3.21966991 L3,0.219669914 C3.26626656,-0.0465966484 3.68293025,-0.0708026996 3.97654174,0.147051761 Z" id="形状结合" fill="#565C66" fill-rule="nonzero"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 26备份 2</title>
<defs>
<filter color-interpolation-filters="auto" id="filter-1">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0.540000 0 0 0 0 0.564000 0 0 0 0 0.600000 0 0 0 1.000000 0"></feColorMatrix>
</filter>
<filter color-interpolation-filters="auto" id="filter-2">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0.540000 0 0 0 0 0.564000 0 0 0 0 0.600000 0 0 0 1.000000 0"></feColorMatrix>
</filter>
</defs>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g filter="url(#filter-1)" id="编组-26备份-2">
<g>
<g id="编组-24备份">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g filter="url(#filter-2)" id="提示图标">
<g>
<circle id="椭圆形" stroke="#979797" stroke-width="1.5" cx="8" cy="8" r="7.25"></circle>
</g>
</g>
</g>
<g id="编组" transform="translate(5.000000, 3.500000)" fill="#8A9099" fill-rule="nonzero">
<path d="M2.30709006,9 L3.69095124,9 L3.69095124,7.65034906 L2.30709006,7.65034906 L2.30709006,9 Z M4.42953435,4.770966 C3.73711269,5.22116893 3.41447366,5.76045459 3.41447364,6.3457184 L3.41447364,6.75042212 L2.30659899,6.75042212 L2.30659899,6.25567783 C2.26043754,5.44579147 2.67589055,4.7259457 3.41398257,4.18570217 C4.24390642,3.60139623 4.65935941,3.0161324 4.56703652,2.47588887 C4.47471362,1.66648145 4.01359027,1.21627851 3.13701391,1.17125823 C2.12195322,1.12623793 1.47618407,1.71150176 1.24586792,2.92609181 L0,2.61094976 C0.369291561,0.811574815 1.52234551,-0.0433318336 3.36782113,0.0016884633 C4.98248953,0.0917290571 5.81290444,0.856595112 5.99705913,2.34130693 C6.04371164,3.24123387 5.53593576,4.05112022 4.42904326,4.770966 L4.42953435,4.770966 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 24</title>
<defs>
<filter color-interpolation-filters="auto" id="filter-1">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0.540000 0 0 0 0 0.564000 0 0 0 0 0.600000 0 0 0 1.000000 0"></feColorMatrix>
</filter>
<filter color-interpolation-filters="auto" id="filter-2">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0.540000 0 0 0 0 0.564000 0 0 0 0 0.600000 0 0 0 1.000000 0"></feColorMatrix>
</filter>
</defs>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g filter="url(#filter-1)" id="编组-24">
<g>
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g filter="url(#filter-2)" id="提示图标">
<g>
<line x1="8" y1="7.1" x2="8" y2="11.9" id="路径-7" stroke="#979797" stroke-width="1.6"></line>
<rect id="矩形" stroke="#979797" fill="#D8D8D8" x="7.75" y="4.6" width="1" height="1"></rect>
<circle id="椭圆形" stroke="#8A9099" stroke-width="1.5" cx="8" cy="8" r="7.25"></circle>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
.RadiosBox {
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid #e6e8eb;
border-radius: 4px;
background-color: #e6e8eb;
cursor: pointer;
height: 32px;
box-sizing: border-box;
padding: 2px;
}
.radio {
height: 28px;
box-sizing: border-box;
font-size: 14px;
color: #565c66;
border-radius: 4px;
line-height: 20px;
padding: 3px 18px;
background-color: #e6e8eb;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
white-space: nowrap;
}
.radioActive {
color: #1370ff;
background-color: #fff;
border: 1px solid #e6e8eb;
}
// 按钮样式的单选组
import classnames from "classnames";
import style from "./index.module.css";
type radioOption = {
value: string;
label: string;
};
type IRadioGroupOfButtonStyleProps = {
radioOptions: Array<radioOption>;
value: string;
handleRadio: any;
RadiosBoxStyle?: object;
radioStyle?: object;
};
const RadioGroupOfButtonStyle = (props: IRadioGroupOfButtonStyleProps) => {
const { radioOptions, value, handleRadio, RadiosBoxStyle, radioStyle } =
props;
return (
<div className={style.RadiosBox} style={RadiosBoxStyle}>
{radioOptions.map((options) => {
return (
<div
key={options.value}
className={classnames({
[style.radio]: true,
[style.radioActive]: value === options.value,
})}
onClick={() => handleRadio(options.value)}
style={radioStyle}
>
{options.label}
</div>
);
})}
</div>
);
};
export default RadioGroupOfButtonStyle;
.rootTitle {
border-radius: 4px 4px 0 0;
background-color: rgba(25, 118, 210, 0.08);
/* background-color: rgba(25, 118, 210, 0.5); */
line-height: 44px;
color: rgba(30, 38, 51, 1);
font-size: 14px;
font-weight: 600;
display: flex;
justify-content: flex-start;
align-items: center;
}
.rootTitleActive {
background-color: rgba(25, 118, 210, 0.2);
}
.bigFolderIcon {
margin: 0 9px;
}
.treeLabel {
display: flex;
justify-content: flex-start;
align-items: center;
}
.treeLabelText {
line-height: 44px;
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
white-space: nowrap;
width: 320px;
}
.labelFolderIcon {
margin-right: 9px;
}
import MyDialog from "../mui/Dialog";
import { useStores } from "@/store";
import { observer } from "mobx-react-lite";
import { toJS } from "mobx";
import { useEffect, useState } from "react";
import CloudEController from "@/api/fileserver/CloudEController";
import MyTreeView from "@/components/mui/MyTreeView";
import classNames from "classnames";
import bigFolderIcon from "@/assets/project/bigFolderIcon.svg";
import folderIcon from "@/assets/project/folderIcon.svg";
import dataSetIcon from "@/assets/project/dataSetIcon.svg";
import fileIcon from "@/assets/project/fileIcon.svg";
import useMyRequest from "@/hooks/useMyRequest";
import { getDataFind } from "@/api/project_api";
import style from "./index.module.css";
import _ from "lodash";
type FileSelectProps = {
open: boolean;
onConfirm: any;
onClose: any;
type?: "file" | "dataset" | "path";
};
const FileSelect = observer((props: FileSelectProps) => {
const { onConfirm, type = "path" } = props;
// const { onConfirm, type = "dataset" } = props;
const { currentProjectStore } = useStores();
const projectId = toJS(currentProjectStore.currentProjectInfo.id);
const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken);
const [treeData, setTreeData] = useState<Array<any>>([]);
const [rootActive, setRootActive] = useState(true);
const [newPath, setNewPath] = useState("/");
// 获取某路径下的数据集
const { run: getDataFindRun } = useMyRequest(getDataFind, {
onSuccess: (res: any) => {
const dataSetList = res.data.map((item: any) => {
return {
...item,
type: "dataset",
dir: `/${item.path}`,
subdirs: "",
};
});
let treeDataArr = _.cloneDeep(treeData);
if (newPath === "/") {
treeDataArr = _.uniqWith([...treeDataArr, ...dataSetList], _.isEqual);
setTreeData(treeDataArr);
} else {
let pathArr: Array<any> = newPath.split("/");
pathArr.shift();
let reduceResult = pathArr.reduce((result, path) => {
if (Array.isArray(result)) {
result.forEach((item: any, index: number) => {
if (item.name === path) {
result = result[index];
}
});
} else if (Array.isArray(result.subdirs)) {
result.subdirs.forEach((item: any, index: number) => {
if (item.name === path) {
result = result.subdirs[index];
}
});
} else {
result = result.subdirs;
}
return result;
}, treeDataArr);
if (Array.isArray(reduceResult.subdirs)) {
reduceResult.subdirs = _.uniqWith(
[...reduceResult.subdirs, ...dataSetList],
_.isEqual
);
} else {
reduceResult.subdirs = dataSetList;
}
treeDataArr = _.uniqWith(treeDataArr, _.isEqual);
setTreeData(treeDataArr);
}
},
});
useEffect(() => {
if (type === "dataset") {
getDataFindRun({
projectId: projectId as string,
path: newPath === "/" ? "/" : `${newPath}/`,
});
}
}, [newPath, getDataFindRun, projectId, type]);
useEffect(() => {
if (fileToken && projectId) {
CloudEController.JobOutFileDirtree(
"/",
fileToken,
projectId,
false
)?.then((res: any) => {
if (Array.isArray(res.data)) {
setTreeData(res.data);
} else {
setTreeData([]);
}
if (type === "dataset") {
getDataFindRun({
projectId: projectId as string,
path: "/",
// path: path === "/" ? "/" : `${path}/`,
});
}
});
}
}, [projectId, fileToken, type, getDataFindRun]);
// const renderLabel = (labelNmae: string) => {
const renderLabel = (node: any) => {
return (
<span className={style.treeLabel}>
{node.type === "directory" && (
<img className={style.labelFolderIcon} src={folderIcon} alt="" />
)}
{node.type === "dataset" && (
<img className={style.labelFolderIcon} src={dataSetIcon} alt="" />
)}
{node.type !== "directory" && node.type !== "dataset" && (
<img className={style.labelFolderIcon} src={fileIcon} alt="" />
)}
<span className={style.treeLabelText}>{node.name}</span>
</span>
);
};
const handleRoot = () => {
setNewPath("/");
setRootActive(true);
};
const onNodeSelect = (a: any, b: any) => {
setNewPath(b);
setRootActive(false);
};
// 给路径去掉第一个'/'然后结尾加上文件名 方便后面直接使用
const idFunc = (item: any) => {
return `${item.dir.substr(1)}${item.name}`;
};
const fileSelectOnConfirm = () => {
onConfirm(newPath);
};
return (
<MyDialog
open={props.open}
onClose={props.onClose}
onConfirm={fileSelectOnConfirm}
title={type}
>
<div
className={classNames({
[style.rootTitle]: true,
[style.rootTitleActive]: rootActive,
})}
onClick={handleRoot}
>
<img className={style.bigFolderIcon} src={bigFolderIcon} alt="" />
ProjectData
</div>
<MyTreeView
treeData={treeData}
renderLabel={renderLabel}
onNodeSelect={onNodeSelect}
idFunc={idFunc}
treeViewSx={{
width: 400,
overflow: "hidden",
}}
></MyTreeView>
</MyDialog>
);
});
export default FileSelect;
import { useStores } from "@/store/index"; import { useStores } from "@/store/index";
import { elements } from "@/router"; import { elements } from "@/router";
import { current } from "@/api/demo_api"; import { current } from "@/api/demo_api";
import { product } from "@/api/project_api";
import localStorageKey from "@/utils/localStorageKey"; import localStorageKey from "@/utils/localStorageKey";
import NotFound from "@/views/404"; import NotFound from "@/views/404";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import { useEffect } from "react"; import { useEffect } from "react";
import { menu } from "@/api/routes_api"; import { menu } from "@/api/routes_api";
import {
setFileServerEndPointLocalStorage,
getFiletokenAccordingToId,
} from "@/views/Project/project";
const useMyRouter = () => { const useMyRouter = () => {
const { permissionStore, menuStore, currentProjectStore } = useStores(); const { permissionStore, menuStore } = useStores();
const userInfo = useMyRequest(current); const userInfo = useMyRequest(current);
const menuInfo = useMyRequest(menu); const menuInfo = useMyRequest(menu);
const productInfo = useMyRequest(product);
useEffect(() => { useEffect(() => {
userInfo.run(); userInfo.run();
menuInfo.run(); menuInfo.run();
productInfo.run({
product: "CADD",
});
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
...@@ -47,24 +38,8 @@ const useMyRouter = () => { ...@@ -47,24 +38,8 @@ const useMyRouter = () => {
permissionStore.initAllRoutes(); permissionStore.initAllRoutes();
} }
if (productInfo.res) {
let list = productInfo.data?.data;
if (list.length === 0) {
currentProjectStore.setProjectList([]);
currentProjectStore.changeProject({});
} else {
currentProjectStore.setProjectList(list);
currentProjectStore.changeProject(list[0]);
setFileServerEndPointLocalStorage(list[0].zoneId);
getFiletokenAccordingToId(list[0].id).then((res) => {
list[0].filetoken = res;
currentProjectStore.changeProject(list[0]);
});
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [userInfo.data, menuInfo.data, productInfo.data]); }, [userInfo.data, menuInfo.data]);
return permissionStore.allRoutes; return permissionStore.allRoutes;
}; };
......
...@@ -42,7 +42,7 @@ const getTransitionComponent = (transition: "grow" | "fade") => { ...@@ -42,7 +42,7 @@ const getTransitionComponent = (transition: "grow" | "fade") => {
const MySnackbarProvider = ({ const MySnackbarProvider = ({
vertical = "top", vertical = "top",
horizontal = "center", horizontal = "center",
autoHideDuration = 2000, autoHideDuration = 5000,
snackerClasses, snackerClasses,
ClickAwayListenerProps, ClickAwayListenerProps,
ContentProps, ContentProps,
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-07-05 14:00:37
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-06 13:52:48
* @FilePath: /bkunyun/src/components/mui/MyCheckBox.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import * as React from "react";
import FormGroup, { FormGroupProps } from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Checkbox from "@mui/material/Checkbox";
import FormControl from "@mui/material/FormControl";
import FormHelperText from '@mui/material/FormHelperText';
import _ from "lodash";
interface IMyCheckBoxProps extends FormGroupProps{
value: Array<any>;
options: Array<ICheckBoxOption>;
onChange: any; // 直接返回选中项的数组
variant?: "standard" | "outlined" | "filled";
error?: boolean;
helperText?: string;
};
type ICheckBoxOption = {
value: any;
label?: string;
disabled?: boolean;
};
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<ICheckBoxOption> => {
return arr.map((item: any) => {
return {
value: item[valueKey],
label: item[labelKey],
disabled: item[disabledKey] || false,
};
});
};
export default function MyCheckBox(props: IMyCheckBoxProps) {
const { value, options, onChange, error = false, helperText, variant } = props;
const getCheckedStatus = (
checkBoxItemValue: any,
valueArr: Array<any>
): boolean => {
const result = valueArr.indexOf(checkBoxItemValue);
return result === -1 ? false : true;
};
const handleMyCheckBoxOnChange = (e: any) => {
const resultArr = _.cloneDeep(value);
const clickValue = e.target.name;
const clickValueIndex = value.indexOf(clickValue);
if (clickValueIndex === -1) {
resultArr.push(clickValue);
onChange && onChange(resultArr);
} else {
resultArr.splice(clickValueIndex, 1);
onChange && onChange(resultArr);
}
};
return (
<FormControl fullWidth variant={variant} error={error}>
<FormGroup {...props} row>
{options.map((option) => {
return (
<FormControlLabel
key={option.value}
control={
<Checkbox
checked={getCheckedStatus(option.value, value)}
value={option.value}
/>
}
label={option.label}
name={option.value}
onChange={handleMyCheckBoxOnChange}
/>
);
})}
</FormGroup>
{helperText && error && <FormHelperText>{helperText}</FormHelperText>}
</FormControl>
);
}
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-07-05 14:00:37
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-06 11:45:10
* @FilePath: /bkunyun/src/components/mui/MyInput.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import TextField, { TextFieldProps } from "@mui/material/TextField";
interface MyInputProps extends Omit<TextFieldProps, "value"> {
value: any;
inputSx?: any;
onChange?: any;
onFocus?: any;
label?: string;
variant?: "standard" | "filled" | "outlined";
id?: string;
size?: "small" | "medium";
placeholder?: string;
fullWidth?: boolean; // 宽度是否和容器一致
InputProps?: any; // input加前后icon可以用这个
error?: boolean;
helperText?: string;
};
const MyInput = (props: MyInputProps) => {
const {
inputSx = {},
value,
onChange,
onFocus,
label,
id,
variant,
size = "small",
placeholder = "请输入",
fullWidth = true,
InputProps,
error = false,
helperText,
} = props;
return (
<TextField
{...props}
error={error}
helperText={helperText}
sx={{ ...inputSx }}
id={id}
label={label}
variant={variant}
onChange={onChange}
onFocus={onFocus}
size={size}
placeholder={placeholder}
fullWidth={fullWidth}
InputProps={{
...InputProps,
}}
value={value}
/>
);
};
export default MyInput;
import * as React from "react";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import CheckIcon from "@mui/icons-material/Check";
import { ThemeProvider, createTheme } from "@mui/material/styles";
type IOption = {
label: string;
value: string;
};
type IMyMenuProps = {
children: React.ReactNode;
options: Array<IOption>;
value: string;
setValue?: any;
};
const theme = createTheme({
components: {
MuiMenu: {
styleOverrides: {
root: {
maxHeight: "260px",
overflowY: "scroll",
},
},
},
MuiMenuItem: {
styleOverrides: {
root: {
fontSize: "14px",
lineHeight: "36px",
display: "flex",
justifyContent: "space-between",
":hover": {
color: "rgba(19, 112, 255, 1)",
},
"&.Mui-selected": {
backgroundColor: "#fff",
color: "rgba(19, 112, 255, 1)",
},
},
},
},
MuiSvgIcon: {
styleOverrides: {
root: {
width: "16px",
height: "16px",
},
},
},
},
});
const MyMenu = (props: IMyMenuProps) => {
const { children, options, value, setValue } = props;
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = (value: string) => {
setAnchorEl(null);
setValue && setValue(value);
};
return (
<ThemeProvider theme={theme}>
<div>
<div onClick={handleClick}>{children}</div>
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "basic-button",
}}
>
{options.map((option, index) => {
return (
<MenuItem
onClick={() => handleClose(option.value)}
selected={value === option.value}
key={index}
>
<span>{option.label}</span>
{value === option.value && <CheckIcon />}
</MenuItem>
);
})}
</Menu>
</div>
</ThemeProvider>
);
};
export default MyMenu;
import * as React from "react";
import { ReactNode, useEffect } from "react";
import Box from "@mui/material/Box";
import ButtonComponent from "./Button";
import tipsIcon from "@/assets/project/information-outline.svg";
import Popper from "@mui/material/Popper";
type IMyPopconfirmProps = {
title: string | ReactNode;
cancelText?: string;
okText?: string;
showCancel?: boolean;
onCancel?: any;
onConfirm?: any;
children: ReactNode;
};
const MyPopconfirm = (props: IMyPopconfirmProps) => {
const {
title,
cancelText = "取消",
okText = "确认",
showCancel = true,
onCancel,
onConfirm,
} = props;
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
event.nativeEvent.stopImmediatePropagation();
setAnchorEl(anchorEl ? null : event.currentTarget);
};
const open = Boolean(anchorEl);
const id = open ? "simple-popper" : undefined;
const handleCancel = () => {
setAnchorEl(null);
onCancel && onCancel();
};
const handleOk = () => {
setAnchorEl(null);
onConfirm && onConfirm();
};
useEffect(() => {
document.addEventListener("click", (e) => {
setAnchorEl(null);
});
}, []);
return (
<div>
<div aria-describedby={id} onClick={handleClick}>
{props.children && props.children}
</div>
<Popper
id={id}
open={open}
anchorEl={anchorEl}
sx={{
zIndex: 2000,
bgcolor: "#fff",
minWidth: "200px",
borderRadius: "2px",
padding: "20px 16px",
boxShadow: "0px 3px 10px 0px rgba(0, 24, 57, 0.14)",
}}
>
{/* "0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d", */}
<Box sx={{ marginBottom: "16px" }}>
<img
style={{ marginRight: "12px", position: "relative", top: "3px" }}
src={tipsIcon}
alt=""
/>
{title}
</Box>
<Box sx={{ display: "flex", justifyContent: "flex-end" }}>
{showCancel && (
<ButtonComponent
text={cancelText}
// variant="text"
size="small"
color="inherit"
click={handleCancel}
style={{ marginRight: "12px" }}
></ButtonComponent>
)}
<ButtonComponent
text={okText}
// variant="text"
size="small"
click={handleOk}
></ButtonComponent>
</Box>
</Popper>
</div>
);
};
export default MyPopconfirm;
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-07-05 14:00:37
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-06 13:49:25
* @FilePath: /bkunyun/src/components/mui/MyRadio.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import * as React from "react";
import Radio from "@mui/material/Radio";
import RadioGroup, { RadioGroupProps } from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormHelperText from '@mui/material/FormHelperText';
interface IMyRadioProps extends RadioGroupProps {
value: any;
options: Array<ICheckBoxOption>;
onChange: any;
variant?: "standard" | "outlined" | "filled";
error?: boolean;
helperText?: string;
};
type ICheckBoxOption = {
value: any;
label?: string;
disabled?: boolean;
};
// 如果后端给的options不是 value-label的字段可以用下面的方法转换
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<ICheckBoxOption> => {
return arr.map((item: any) => {
return {
value: item[valueKey],
label: item[labelKey],
disabled: item[disabledKey] || false,
};
});
};
export default function MyRadio(props: IMyRadioProps) {
const { value, options, onChange , error = false, helperText, variant} = props;
return (
<FormControl fullWidth variant={variant} error={error}>
<RadioGroup
{...props}
row
aria-labelledby="demo-row-radio-buttons-group-label"
name="row-radio-buttons-group"
value={value}
onChange={onChange}
>
{options.map((option) => {
return (
<FormControlLabel
key={option.value}
value={option.value}
control={<Radio />}
label={option.label}
/>
);
})}
</RadioGroup>
{helperText && error && <FormHelperText>{helperText}</FormHelperText>}
</FormControl>
);
}
...@@ -18,6 +18,22 @@ export interface IOption { ...@@ -18,6 +18,22 @@ export interface IOption {
value: string; value: string;
disabled?: boolean; disabled?: boolean;
} }
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<IOption> => {
return arr.map((item: any) => {
return {
label: item[labelKey],
value: item[valueKey],
disabled: item[disabledKey],
};
});
};
interface IProps interface IProps
extends Omit<SelectProps, "value" | "options" | "onChange" | "title"> { extends Omit<SelectProps, "value" | "options" | "onChange" | "title"> {
value?: IOption; value?: IOption;
......
...@@ -15,7 +15,7 @@ type MyTreeViewProps = { ...@@ -15,7 +15,7 @@ type MyTreeViewProps = {
onNodeFocus?: (event: object, value: string) => void; // 点击某一项的回调 onNodeFocus?: (event: object, value: string) => void; // 点击某一项的回调
onNodeSelect?: (event: object, value: Array<any> | string) => void; // 点击某一项的回调 onNodeSelect?: (event: object, value: Array<any> | string) => void; // 点击某一项的回调
onNodeToggle?: (event: object, nodeIds: Array<any>) => void; // 点击某一项的回调 onNodeToggle?: (event: object, nodeIds: Array<any>) => void; // 点击某一项的回调
renderLabel?: (labelNmae: string) => React.ReactNode; renderLabel?: (node: any) => React.ReactNode;
treeViewSx?: any; treeViewSx?: any;
defaultExpanded?: Array<string>; defaultExpanded?: Array<string>;
idKey?: string; idKey?: string;
...@@ -48,7 +48,7 @@ const MyTreeView = (props: MyTreeViewProps) => { ...@@ -48,7 +48,7 @@ const MyTreeView = (props: MyTreeViewProps) => {
nodeId={String( nodeId={String(
idFunc ? idFunc(nodes) : nodes.id || `${nodes.name}${index}` idFunc ? idFunc(nodes) : nodes.id || `${nodes.name}${index}`
)} )}
label={renderLabel === undefined ? nodes.name : renderLabel(nodes.name)} label={renderLabel === undefined ? nodes.name : renderLabel(nodes)}
disabled={nodes?.disabled ? true : false} disabled={nodes?.disabled ? true : false}
> >
{Array.isArray(nodes.subdirs) {Array.isArray(nodes.subdirs)
......
...@@ -2,92 +2,104 @@ ...@@ -2,92 +2,104 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13 * @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-07 20:31:40 * @LastEditTime: 2022-07-04 20:18:17
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx * @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
import { memo } from "react"; import { memo } from "react";
import { isEqual } from "lodash"; import { isEqual } from "lodash";
import { useState, useMemo, useEffect } from "react"; import { useState } from "react";
import { Box } from "@mui/system"; import { Box } from "@mui/system";
import Tab from "@mui/material/Tab"; import Tab from "@mui/material/Tab";
import { TabContext, TabList, TabPanel } from "@mui/lab"; import { TabContext, TabList, TabPanel } from "@mui/lab";
import { Typography } from '@mui/material'; import { Typography } from "@mui/material";
interface ITabList { interface ITabList {
label: string; label: string;
value: string; value: string;
component: JSX.Element; component: JSX.Element;
icon?: string; icon?: string;
iconed?: string; iconed?: string;
hide?: boolean hide?: boolean;
} }
interface IProps { interface IProps {
tabList: ITabList[]; tabList: ITabList[];
defaultValue?: string;
} }
const Tabs = (props: IProps) => { const Tabs = (props: IProps) => {
const { tabList } = props; const { tabList, defaultValue } = props;
const [value, setValue] = useState(tabList.filter(e => !e.hide)[0].value); const [value, setValue] = useState(
defaultValue || tabList.filter((e) => !e.hide)[0].value
);
const onChange = (val: string) => { const onChange = (val: string) => {
setValue(val); setValue(val);
}; };
const labelRender = (item: ITabList, key: number) => { const labelRender = (item: ITabList, key: number) => {
return ( return (
<Box style={{ display: "flex", alignItems: "center" }}> <Box style={{ display: "flex", alignItems: "center" }}>
{ {item.icon ? (
item.icon ? <img style={{ width: "14px", marginRight: "10px" }} src={value === item.value ? item.iconed : item.icon} alt="" /> <img
: "" style={{ width: "14px", marginRight: "10px" }}
} src={value === item.value ? item.iconed : item.icon}
<Typography sx={{ fontSize: "14px", fontWeight: '400' }} >{item.label}</Typography> alt=""
</Box> />
) ) : (
} ""
)}
<Typography sx={{ fontSize: "14px", fontWeight: "400" }}>
{item.label}
</Typography>
</Box>
);
};
return ( return (
<TabContext value={value}> <TabContext value={value}>
<Box sx={{ borderBottom: 1, borderColor: "#F0F2F5" }}> <Box sx={{ borderBottom: 1, borderColor: "#F0F2F5" }}>
<TabList <TabList
onChange={(e: any, val: string) => { onChange={(e: any, val: string) => {
onChange(val); onChange(val);
}} }}
aria-label="lab API tabs example" >
> {tabList
{tabList?.map((item, key) => { ?.filter((item) => !item.hide)
if (item.hide) return "" .map((item, key) => {
return ( return (
<Tab <Tab
key={key} key={key}
label={labelRender(item, key)} label={labelRender(item, key)}
value={item.value} value={item.value}
id={item.value} id={item.value}
/> />
); );
})} })}
</TabList> </TabList>
</Box> </Box>
{tabList?.map((item) => { {tabList
return ( ?.filter((item) => !item.hide)
<TabPanel .map((item) => {
sx={{ padding: "20px 0 0 0" }} return (
value={item.value} <TabPanel
key={item.value} sx={{ padding: "20px 0 0 0" }}
> value={item.value}
{item.component} key={item.value}
</TabPanel> >
); {item.component}
})} </TabPanel>
</TabContext> );
); })}
</TabContext>
);
}; };
const handleEqual = (prvProps: IProps, nextProps: IProps) => { const handleEqual = (prvProps: IProps, nextProps: IProps) => {
if (isEqual(prvProps, nextProps)) { if (isEqual(prvProps, nextProps)) {
return true; return true;
} }
return false; return false;
}; };
export default memo(Tabs, handleEqual); export default memo(Tabs, handleEqual);
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:17:23 * @Date: 2022-05-31 10:17:23
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-14 10:28:43 * @LastEditTime: 2022-07-07 22:03:00
* @FilePath: /bkunyun/src/react-app-env.d.ts * @FilePath: /bkunyun/src/react-app-env.d.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
...@@ -80,7 +80,9 @@ declare module "*.module.sass" { ...@@ -80,7 +80,9 @@ declare module "*.module.sass" {
declare module "@mui/lab"; declare module "@mui/lab";
declare module "lodash"; declare module "lodash";
declare module 'lodash/cloneDeep'
declare module "@mui/material/Tab"; declare module "@mui/material/Tab";
declare module "tus-js-client"; declare module "tus-js-client";
declare module "uuid"; declare module "uuid";
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13 * @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-05-31 15:15:59 * @LastEditTime: 2022-06-24 14:32:32
* @FilePath: /bkunyun/src/router/index.ts * @FilePath: /bkunyun/src/router/index.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
import { AnyMap } from "immer/dist/internal"; import { AnyMap } from "immer/dist/internal";
...@@ -16,7 +16,8 @@ import Demo from "@/views/demo"; ...@@ -16,7 +16,8 @@ import Demo from "@/views/demo";
import ProjectSetting from "@/views/Project/ProjectSetting"; import ProjectSetting from "@/views/Project/ProjectSetting";
import ProjectData from "@/views/Project/ProjectData"; import ProjectData from "@/views/Project/ProjectData";
import ProjectWorkbench from "@/views/Project/ProjectWorkbench"; import ProjectWorkbench from "@/views/Project/ProjectWorkbench";
import ProjectSubmitWork from "@/views/Project/ProjectSubmitWork";
import ProjectJobDetail from "@/views/Project/ProjectJobDetail";
export type route = { export type route = {
id?: string; id?: string;
...@@ -51,7 +52,9 @@ export const elements: { ...@@ -51,7 +52,9 @@ export const elements: {
Demo: Demo, Demo: Demo,
ProjectSetting: ProjectSetting, ProjectSetting: ProjectSetting,
ProjectData: ProjectData, ProjectData: ProjectData,
ProjectWorkbench:ProjectWorkbench ProjectWorkbench: ProjectWorkbench,
ProjectSubmitWork: ProjectSubmitWork,
ProjectJobDetail: ProjectJobDetail
}; };
export const routes: Array<route | navigate> = [ export const routes: Array<route | navigate> = [
......
...@@ -11,22 +11,39 @@ type productInfo = { ...@@ -11,22 +11,39 @@ type productInfo = {
id?: string; id?: string;
name?: string; name?: string;
}; };
const sessionStorageCurrentProjectInfo = JSON.parse(
sessionStorage.getItem("currentProjectInfo") || "{}"
);
const sessionStorageCurrentProductInfo = JSON.parse(
sessionStorage.getItem("currentProductInfo") || "{}"
);
const sessionStorageProjectList = JSON.parse(
sessionStorage.getItem("projectList") || "[]"
);
class currentProject { class currentProject {
constructor() { constructor() {
makeAutoObservable(this); makeAutoObservable(this);
} }
// 选中的项目 // 选中的项目
currentProjectInfo: projectInfo = {}; currentProjectInfo: projectInfo = sessionStorageCurrentProjectInfo;
// 选中的产品下的项目列表 // 选中的产品下的项目列表
projectList: Array<projectInfo> = []; projectList: Array<projectInfo> = sessionStorageProjectList;
// 选中的产品 // 选中的产品
currentProductInfo: productInfo = {}; currentProductInfo: productInfo = sessionStorageCurrentProductInfo;
setProjectList = (list: Array<projectInfo>) => { setProjectList = (list: Array<projectInfo>) => {
this.projectList = list; this.projectList = list;
sessionStorage.setItem("projectList", JSON.stringify(list));
}; };
changeProject = (project: projectInfo) => { changeProject = (project: projectInfo) => {
this.currentProjectInfo = project; this.currentProjectInfo = project;
sessionStorage.setItem("currentProjectInfo", JSON.stringify(project));
};
changeProductInfo = (productInfo: productInfo) => {
this.currentProductInfo = productInfo;
sessionStorage.setItem("currentProductInfo", JSON.stringify(productInfo));
}; };
} }
......
...@@ -17,11 +17,13 @@ class Menus { ...@@ -17,11 +17,13 @@ class Menus {
productList: Array<{ productList: Array<{
name: string; name: string;
path: string; path: string;
id: string;
}> = []; }> = [];
utilityList: Array<{ utilityList: Array<{
name: string; name: string;
path: string; path: string;
id: string;
}> = []; }> = [];
initMenu = (list: projectList) => { initMenu = (list: projectList) => {
...@@ -32,11 +34,13 @@ class Menus { ...@@ -32,11 +34,13 @@ class Menus {
this.productList.push({ this.productList.push({
name: item.name, name: item.name,
path: item.routes[0].path, path: item.routes[0].path,
id: item.id,
}); });
} else if (item.type === "utility") { } else if (item.type === "utility") {
this.utilityList.push({ this.utilityList.push({
name: item.name, name: item.name,
path: item.routes[0].path, path: item.routes[0].path,
id: item.id,
}); });
} }
} }
......
...@@ -140,11 +140,10 @@ const FileItem = observer((props: IProps) => { ...@@ -140,11 +140,10 @@ const FileItem = observer((props: IProps) => {
<div className={styles.speedBox}> <div className={styles.speedBox}>
<span className={styles.span}>{`${storageUnitFromB( <span className={styles.span}>{`${storageUnitFromB(
itemInfo?.bytesUploaded || 0 itemInfo?.bytesUploaded || 0
)}/${storageUnitFromB(itemInfo?.bytesTotal || 0)}`}</span>{" "} )}/${storageUnitFromB(itemInfo?.bytesTotal || 0)}`}</span>
: {statusMsg !== '上传失败' ? <span className={styles.span}>{`${storageUnitFromB(
<span className={styles.span}>{`${storageUnitFromB(
speed speed
)}/s`}</span> )}/s`}</span> : null}
</div> </div>
)} )}
</div> </div>
......
import React, { useEffect } from "react"; import React, { useEffect, useState } from "react";
import { Outlet, useLocation, useNavigate } from "react-router-dom"; import { Outlet, useLocation, useNavigate } from "react-router-dom";
import cx from "classnames"; import cx from "classnames";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
...@@ -14,163 +14,202 @@ import Button from "@/components/mui/Button"; ...@@ -14,163 +14,202 @@ import Button from "@/components/mui/Button";
import logo from "@/assets/img/logo.svg"; import logo from "@/assets/img/logo.svg";
import MyPopover from "@/components/mui/MyPopover"; import MyPopover from "@/components/mui/MyPopover";
import TranSferList from "./components/TransferList"; import TranSferList from "./components/TransferList";
import { getProjectList } from "@/api/project_api";
import useMyRequest from "@/hooks/useMyRequest";
import {
setFileServerEndPointLocalStorage,
getFiletokenAccordingToId,
} from "@/views/Project/project";
import style from "./index.module.css"; import style from "./index.module.css";
const ConsoleLayout = observer(() => { const ConsoleLayout = observer(() => {
const { const {
productAnchorEl, productAnchorEl,
utilityAnchorEl, utilityAnchorEl,
productOpen, productOpen,
utilityOpen, utilityOpen,
handleProductClick, handleProductClick,
handleUtilityClick, handleUtilityClick,
handleClose, handleClose,
} = useIndex(); } = useIndex();
const [currentProduct, setCurrentProduct] = useState<{
path: string;
name: string;
}>();
const { currentProjectStore } = useStores();
const { run: runGetProjectList } = useMyRequest(getProjectList, {
onSuccess: (res) => {
let list = res.data;
if (list.length === 0) {
currentProjectStore.setProjectList([]);
currentProjectStore.changeProject({});
navigate(currentProduct?.path as string);
} else {
currentProjectStore.setProjectList(list);
currentProjectStore.changeProject(list[0]);
setFileServerEndPointLocalStorage(list[0].zoneId);
getFiletokenAccordingToId(list[0].id).then((res) => {
list[0].filetoken = res;
currentProjectStore.changeProject(list[0]);
});
navigate(currentProduct?.path as string);
}
},
});
// 切换产品
const getProduct = (item: any) => {
currentProjectStore.changeProductInfo({ id: item.id, name: item.name });
setCurrentProduct(item);
runGetProjectList({
product: item.name,
});
};
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
const { permissionStore, menuStore } = useStores(); const { permissionStore, menuStore } = useStores();
useEffect(() => { useEffect(() => {
permissionStore.setSidebarRouters(location.pathname); permissionStore.setSidebarRouters(location.pathname);
}, [location, permissionStore]); }, [location, permissionStore]);
return ( return (
<Box> <Box>
<Box className={style.topApp}> <Box className={style.topApp}>
<Box className={style.topLeftBox}> <Box className={style.topLeftBox}>
<img src={logo} alt="" className={style.logo} /> <img src={logo} alt="" className={style.logo} />
<Button <Button
text={globalText.console} text={globalText.console}
variant={"text"} variant={"text"}
style={{ color: "#565C66" }} style={{ color: "#565C66" }}
click={() => navigate("/home")} click={() => navigate("/home")}
/> />
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Button <Button
text={globalText.product} text={globalText.product}
variant={"text"} variant={"text"}
style={{ color: "#565C66" }} style={{ color: "#565C66" }}
click={handleProductClick} click={handleProductClick}
dropValue={productOpen} dropValue={productOpen}
drop={true} drop={true}
/> />
{/* <ArrowDropDownIcon classes={{ {/* <ArrowDropDownIcon classes={{
root: cx({ root: cx({
[style.ArrowDropDownIconRoot]: true, [style.ArrowDropDownIconRoot]: true,
[style.ArrowDropDownIconRootOpen]: Boolean(productOpen) [style.ArrowDropDownIconRootOpen]: Boolean(productOpen)
}) })
}} /> */} }} /> */}
<Menu <Menu
id="product-menu" id="product-menu"
anchorEl={productAnchorEl} anchorEl={productAnchorEl}
open={productOpen} open={productOpen}
onClose={handleClose} onClose={handleClose}
classes={{ classes={{
paper: style.menuPaper, paper: style.menuPaper,
}} }}
MenuListProps={{ MenuListProps={{
"aria-labelledby": "product-button", "aria-labelledby": "product-button",
}} }}
> >
{menuStore.productList.map((item) => { {menuStore.productList.map((item) => {
return ( return (
<MenuItem <MenuItem
key={item.path} key={item.path}
classes={{ classes={{
root: style.menuItemRoot, root: style.menuItemRoot,
}} }}
onClick={() => { onClick={() => {
navigate(item.path); getProduct(item);
handleClose(); handleClose();
}} }}
> >
{item.name} {item.name}
</MenuItem> </MenuItem>
); );
})} })}
</Menu> </Menu>
</Box> </Box>
</Box> </Box>
<Box className={style.topRightBox}> <Box className={style.topRightBox}>
<MyPopover <MyPopover
content={<TranSferList />} content={<TranSferList />}
transformOrigin={{ transformOrigin={{
vertical: "top", vertical: "top",
horizontal: "right", horizontal: "right",
}} }}
> >
<Box className={style.topRightItem}> <img
<img className={style.topRightItem}
src={uploadIcon} src={uploadIcon}
alt="" alt=""
style={{ verticalAlign: "middle" }} style={{ verticalAlign: "middle" }}
/> />
</Box> </MyPopover>
</MyPopover> <Box className={style.topRightItem}>
<Box className={style.topRightItem}> <Box
<Box sx={{ display: "flex", alignItems: "center" }}
sx={{ display: "flex", alignItems: "center" }} onClick={handleUtilityClick}
onClick={handleUtilityClick} >
> <Avatar
<Avatar sx={{
sx={{ bgcolor: "#1370FF",
bgcolor: "#1370FF", width: 28,
width: 28, height: 28,
height: 28, fontSize: "14px",
fontSize: "14px", cursor: "pointer",
cursor: "pointer", }}
}} >
> H
H </Avatar>
</Avatar> <ArrowDropDownIcon
<ArrowDropDownIcon classes={{
classes={{ root: cx({
root: cx({ [style.ArrowDropDownIconRoot]: true,
[style.ArrowDropDownIconRoot]: true, [style.ArrowDropDownIconRootOpen]: Boolean(utilityOpen),
[style.ArrowDropDownIconRootOpen]: Boolean(utilityOpen), }),
}), }}
}} />
/> </Box>
</Box>
<Menu <Menu
id="utility-menu" id="utility-menu"
anchorEl={utilityAnchorEl} anchorEl={utilityAnchorEl}
open={utilityOpen} open={utilityOpen}
onClose={handleClose} onClose={handleClose}
MenuListProps={{ MenuListProps={{
"aria-labelledby": "utility-button", "aria-labelledby": "utility-button",
}} }}
> >
{menuStore.utilityList.map((item) => { {menuStore.utilityList.map((item) => {
return ( return (
<MenuItem <MenuItem
key={item.path} key={item.path}
onClick={() => { onClick={() => {
navigate(item.path); navigate(item.path);
handleClose(); handleClose();
}} }}
> >
{item.name} {item.name}
</MenuItem> </MenuItem>
); );
})} })}
</Menu> </Menu>
</Box> </Box>
</Box> </Box>
</Box> </Box>
<Box> <Box>
<Outlet></Outlet> <Outlet></Outlet>
</Box> </Box>
</Box> </Box>
); );
}); });
export default ConsoleLayout; export default ConsoleLayout;
...@@ -13,8 +13,7 @@ ...@@ -13,8 +13,7 @@
.content { .content {
flex: 1; flex: 1;
height: calc(100vh - 57px); height: calc(100vh - 57px);
overflow: hidden; overflow: scroll;
/* ??????????? */
} }
.list { .list {
/* background-color: red; */ /* background-color: red; */
......
...@@ -6,31 +6,42 @@ import style from "./index.module.css"; ...@@ -6,31 +6,42 @@ import style from "./index.module.css";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { useStores } from "@/store/index"; import { useStores } from "@/store/index";
import classnames from "classnames"; import classnames from "classnames";
import { toJS } from "mobx";
const MenuLayout = observer(() => { const MenuLayout = observer(() => {
const { permissionStore } = useStores(); const { permissionStore, currentProjectStore } = useStores();
let pathname = new URL(window.location.href).pathname; let pathname = new URL(window.location.href).pathname;
const navigate = useNavigate(); const navigate = useNavigate();
const productInfo = toJS(currentProjectStore.currentProductInfo);
// 未选择产品时 直接跳转home页面
if (!productInfo.name) {
navigate("/home");
}
return ( return (
<Box className={style.container}> <Box className={style.container}>
<Box className={style.aside}> <Box className={style.aside}>
<CurrentProject /> <CurrentProject />
<List className={style.list}> <List className={style.list}>
{permissionStore.sidebarRouters.map((item, index) => { {permissionStore.sidebarRouters.map((item, index) => {
return ( if (item.show) {
<li return (
key={"sidebar" + index} <li
className={classnames({ key={"sidebar" + index}
[style.listItem]: true, className={classnames({
[style.active]: item.path === pathname, [style.listItem]: true,
})} [style.active]: item.path === pathname,
onClick={() => item.type === "page" && navigate(item.path)} })}
> onClick={() => item.type === "page" && navigate(item.path)}
{item.name} >
</li> {item.name}
); </li>
);
}
return null;
})} })}
</List> </List>
</Box> </Box>
......
...@@ -34,7 +34,9 @@ const MoveFile = (props: any) => { ...@@ -34,7 +34,9 @@ const MoveFile = (props: any) => {
const [moveFileSubmitloading, setMoveFileSubmitloading] = useState(false); const [moveFileSubmitloading, setMoveFileSubmitloading] = useState(false);
const [treeData, setTreeData] = useState<any>([]); const [treeData, setTreeData] = useState<any>([]);
const [renderTreeData, setRenderTreeData] = useState<any>([]); const [renderTreeData, setRenderTreeData] = useState<any>([]);
let moveFileDialogRef: any = React.createRef(); const [moveFileDialogRef, setMoveFileDialogRef] = useState<any>(
React.createRef()
);
// 要移动的文件夹 之后用来隐藏文件夹树中同路径的文件夹 // 要移动的文件夹 之后用来隐藏文件夹树中同路径的文件夹
const [moveFolderPathArr, setMoveFolderPathArr] = useState<Array<string>>([]); const [moveFolderPathArr, setMoveFolderPathArr] = useState<Array<string>>([]);
...@@ -301,11 +303,11 @@ const MoveFile = (props: any) => { ...@@ -301,11 +303,11 @@ const MoveFile = (props: any) => {
}); });
}; };
const renderLabel = (labelNmae: string) => { const renderLabel = (node: any) => {
return ( return (
<span className={style.treeLabel}> <span className={style.treeLabel}>
<img className={style.labelFolderIcon} src={folderIcon} alt="" /> <img className={style.labelFolderIcon} src={folderIcon} alt="" />
<span className={style.treeLabelText}>{labelNmae}</span> <span className={style.treeLabelText}>{node.name}</span>
</span> </span>
); );
}; };
......
...@@ -453,7 +453,10 @@ const ProjectData = observer(() => { ...@@ -453,7 +453,10 @@ const ProjectData = observer(() => {
// 下载文件 // 下载文件
const hanleDownloadFile = (item: any) => { const hanleDownloadFile = (item: any) => {
const downloadPath = path === "/" ? "/" : `${path}/${item.name}`; console.log(item);
const downloadPath =
path === "/" ? `/${item.name}` : `${path}/${item.name}`;
console.log(downloadPath);
CloudEController.JobFileDownload( CloudEController.JobFileDownload(
downloadPath, downloadPath,
fileToken as string, fileToken as string,
......
.swBox {
position: fixed;
z-index: 1000;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: RGBA(247, 248, 250, 1);
overflow-y: scroll;
}
.swHeader {
z-index: 1001;
position: sticky;
top: 0;
height: 56px;
background-color: #fff;
box-shadow: 0px 3px 10px 0px rgba(0, 24, 57, 0.04);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
}
.swHeaderLeft {
display: flex;
justify-content: flex-start;
align-items: center;
}
.swTemplateTitle {
margin: 0 19px 0 8px;
line-height: 22px;
font-size: 14px;
color: rgba(30, 38, 51, 1);
font-weight: 600;
}
.swContent {
display: flex;
height: calc(100vh - 56px);
}
.swFormBox {
background-color: #fff;
border-right: 1xp solid rgba(235, 237, 240, 1);
width: 360px;
overflow-y: scroll;
box-sizing: border-box;
padding: 24px;
}
.swFlowBox {
flex: 1;
height: calc(100vh - 56px);
}
.title {
color: rgba(30, 38, 51, 1);
font-size: 16px;
line-height: 24px;
font-weight: 600;
margin-bottom: 16px;
}
.taskResults {
padding: 24px;
background-color: rgba(247, 248, 250, 1);
margin-bottom: 24px;
}
.outputLi {
display: flex;
justify-content: space-between;
align-items: center;
margin: 6px 0;
}
.outputLiLeft {
display: flex;
align-items: center;
color: rgba(19, 112, 255, 1);
font-size: 14px;
}
.outputLiLeftImg {
margin-right: 15px;
}
.outputLiRight {
color: rgba(138, 144, 153, 1);
font-size: 12px;
}
.notResults {
background-color: rgba(247, 248, 250, 1);
padding: 54px 0;
text-align: center;
color: rgba(138, 144, 153, 1);
font-size: 14px;
line-height: 22px;
margin-bottom: 24px;
}
.taskInfoLi {
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.taskInfoParams {
color: rgba(138, 144, 153, 1);
font-size: 14px;
line-height: 22px;
width: 72px;
margin-right: 44px;
}
.taskInfoValue {
color: rgba(30, 38, 51, 1);
font-size: 14px;
line-height: 22px;
display: flex;
position: relative;
align-items: center;
text-align: left;
word-break: break-all;
flex: 1;
justify-content: flex-end;
}
.taskInfoValueClick {
cursor: pointer;
color: rgba(19, 112, 255, 1);
}
.taskInfoDownload {
color: rgba(19, 112, 255, 1);
cursor: pointer;
}
.taskInfoValueShowAll {
white-space: normal;
}
.taskInfoValueIcon {
margin-right: 9px;
}
.tabs {
display: flex;
justify-content: flex-start;
border-bottom: 1px solid rgba(240, 242, 245, 1);
}
.tabLi {
cursor: pointer;
font-size: 14px;
line-height: 22px;
padding-bottom: 8px;
color: rgba(138, 144, 153, 1);
margin-right: 32px;
position: relative;
}
.tabLiAcitve {
color: rgba(19, 112, 255, 1);
border-bottom: 2px solid rgba(19, 112, 255, 1);
}
.overview {
padding-top: 19px;
}
.params {
padding-top: 19px;
}
.options {
position: absolute;
top: 33px;
max-height: 230px;
overflow-y: scroll;
padding: 8px 0px;
background: #ffffff;
box-shadow: 0px 3px 10px 0px rgba(0, 24, 57, 0.14);
border-radius: 4px;
z-index: 1002;
}
.option {
padding: 7px 16px;
font-size: 14px;
color: rgba(30, 38, 51, 1);
line-height: 22px;
cursor: pointer;
}
.option:hover {
color: rgba(19, 112, 255, 1);
}
.optionActive {
color: rgba(19, 112, 255, 1);
}
.fullScreenBox {
position: absolute;
background-color: #fff;
cursor: pointer;
z-index: 1000;
right: 24px;
bottom: 24px;
padding: 8px;
}
.fullScreenBox:hover {
opacity: 0.6;
}
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13 * @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-16 20:49:14 * @LastEditTime: 2022-07-07 18:08:33
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx * @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
...@@ -28,168 +28,176 @@ import { isProjectOwner } from "@/utils/util"; ...@@ -28,168 +28,176 @@ import { isProjectOwner } from "@/utils/util";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
const ProjectMembers = observer(() => { const ProjectMembers = observer(() => {
const http = useHttp(); const http = useHttp();
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
/** 删除成员 */ /** 删除成员 */
const [removeDialog, setRemoveDialog] = useState<IDialogInfo>({ const [removeDialog, setRemoveDialog] = useState<IDialogInfo>({
isShow: false, isShow: false,
username: "", username: "",
}); });
/** 更改权限 */ /** 更改权限 */
const [permissionDialog, setPermissionDialog] = useState<IDialogInfo>({ const [permissionDialog, setPermissionDialog] = useState<IDialogInfo>({
isShow: false, isShow: false,
username: "", username: "",
}); });
/** 添加成员 */ /** 添加成员 */
const [addMemberDialog, setAddMemberDialog] = useState<boolean>(false); const [addMemberDialog, setAddMemberDialog] = useState<boolean>(false);
/** 表格数据 */ /** 表格数据 */
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
/** 项目名称 */ /** 当前项目用户权限 */
const [projectName, setProjectMember] = useState(""); const [projectRole, setProjectRole] = useState<string>("");
/** 过滤后数据 */ /** 项目名称 */
const [filterTableData, setFilterTableData] = useState([]); const [projectName, setProjectMember] = useState("");
/** 过滤后数据 */
const [filterTableData, setFilterTableData] = useState([]);
const columns = useMemo(() => { const columns = useMemo(() => {
const val: any = [ const val: any = [
{ id: "username", label: "成员名称" }, { id: "username", label: "成员名称" },
{ id: "projectRoleDesc", label: "项目权限" }, { id: "projectRoleDesc", label: "项目权限" },
{ id: "phone", label: "联系方式" }, { id: "phone", label: "联系方式" },
{ ...(projectRole !== "OWNER"
id: "operation", ? []
label: "操作", : [
width: 160, {
render: (item: any, row: any) => { id: "operation",
return row?.projectRole === "OWNER" ? null : ( label: "操作",
<> width: 160,
<span render: (item: any, row: any) => {
style={{ color: "#1370FF", cursor: "pointer" }} return row?.projectRole === "OWNER" ? null : (
onClick={() => { <>
onPermissionBtn(row); <span
}} style={{ color: "#1370FF", cursor: "pointer" }}
> onClick={() => {
更改权限 onPermissionBtn(row);
</span> }}
<span >
className={styles.removeItemBox} 更改权限
onClick={() => { </span>
onRemoveItemBtn(row.username); <span
}} className={styles.removeItemBox}
> onClick={() => {
移出项目 onRemoveItemBtn(row.username);
</span> }}
</> >
); 移出项目
}, </span>
}, </>
]; );
return val; },
}, []); },
]),
];
return val;
}, [projectRole]);
/** 获取表格数据 */ /** 获取表格数据 */
const getTableList = useCallback(() => { const getTableList = useCallback(() => {
const projectInfo = toJS(currentProjectStore?.currentProjectInfo); const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
if (!projectInfo?.id) return; if (!projectInfo?.id) return;
http http
.get<IResponse<any>>("/cpp/project/get", { .get<IResponse<any>>("/cpp/project/get", {
params: { id: projectInfo?.id || "" }, params: { id: projectInfo?.id || "" },
}) })
.then((res) => { .then((res) => {
const { data = {} } = res; const { data = {} } = res;
setTableData(data?.members || []); setTableData(data?.members || []);
}); console.log(data?.projectRole, data?.projectRole);
}, [currentProjectStore?.currentProjectInfo, http]); setProjectRole(data?.projectRole || "");
});
}, [currentProjectStore?.currentProjectInfo, http]);
useEffect(() => { useEffect(() => {
getTableList(); getTableList();
}, [getTableList]); }, [getTableList]);
useEffect(() => { useEffect(() => {
if (!!projectName) { if (!!projectName) {
const newVal = const newVal =
tableData.filter((item: any) => { tableData.filter((item: any) => {
return item?.username?.includes(projectName); return item?.username?.includes(projectName);
}) || []; }) || [];
setFilterTableData(newVal || []); setFilterTableData(newVal || []);
} else { } else {
setFilterTableData(tableData); setFilterTableData(tableData);
} }
}, [projectName, tableData]); }, [projectName, tableData]);
/** 点击添加成员 */ /** 点击添加成员 */
const onAddMember = () => { const onAddMember = () => {
setAddMemberDialog(true); setAddMemberDialog(true);
}; };
/** 点击删除成员 */ /** 点击删除成员 */
const onRemoveItemBtn = (userName: string) => { const onRemoveItemBtn = (userName: string) => {
setRemoveDialog({ isShow: true, username: userName }); setRemoveDialog({ isShow: true, username: userName });
}; };
/** 点击更改权限 */ /** 点击更改权限 */
const onPermissionBtn = (row: any) => { const onPermissionBtn = (row: any) => {
setPermissionDialog({ setPermissionDialog({
isShow: true, isShow: true,
username: row?.username || "", username: row?.username || "",
projectRole: row?.projectRole || "", projectRole: row?.projectRole || "",
}); });
}; };
return ( return (
<> <>
<Box className={styles.headerBox}> <Box className={styles.headerBox}>
<OutlinedInput <OutlinedInput
onChange={(e: any) => { onChange={(e: any) => {
_.debounce(() => { _.debounce(() => {
setProjectMember(e.target.value); setProjectMember(e.target.value);
}, 200)(); }, 200)();
}} }}
placeholder="搜索项目成员" placeholder="搜索项目成员"
size="small" size="small"
sx={{ width: 340, height: 32 }} sx={{ width: 340, height: 32 }}
endAdornment={<SearchIcon style={{ color: "#8A9099" }} />} endAdornment={<SearchIcon style={{ color: "#8A9099" }} />}
/> />
{currentProjectStore?.currentProjectInfo?.projectRole === "OWNER" ? ( {currentProjectStore?.currentProjectInfo?.projectRole === "OWNER" ? (
<Button <Button
style={{ backgroundColor: "#1370FF " }} style={{ backgroundColor: "#1370FF " }}
variant="contained" variant="contained"
onClick={onAddMember} onClick={onAddMember}
startIcon={<Add />} startIcon={<Add />}
size="small" size="small"
> >
添加成员 添加成员
</Button> </Button>
) : null} ) : null}
</Box> </Box>
<Table <Table
rowHover={true} rowHover={true}
stickyheader={true} stickyheader={true}
rows={filterTableData} rows={filterTableData}
rowsPerPage={"99"} rowsPerPage={"99"}
headCells={columns} headCells={columns}
nopadding={true} nopadding={true}
footer={false} footer={false}
tableStyle={{ minWidth: "auto" }} tableStyle={{ minWidth: "auto" }}
borderBottom={"none"} borderBottom={"none"}
/> />
<RemoveItem <RemoveItem
removeDialog={removeDialog} removeDialog={removeDialog}
setRemoveDialog={setRemoveDialog} setRemoveDialog={setRemoveDialog}
getTableList={getTableList} getTableList={getTableList}
/> />
<ChangePermission <ChangePermission
permissionDialog={permissionDialog} permissionDialog={permissionDialog}
getTableList={getTableList} getTableList={getTableList}
setPermissionDialog={setPermissionDialog} setPermissionDialog={setPermissionDialog}
/> />
<AddMember <AddMember
addMemberDialog={addMemberDialog} addMemberDialog={addMemberDialog}
setAddMemberDialog={setAddMemberDialog} setAddMemberDialog={setAddMemberDialog}
getTableList={getTableList} getTableList={getTableList}
/> />
</> </>
); );
}); });
export default memo(ProjectMembers); export default memo(ProjectMembers);
.formBox {
position: relative;
}
.templateDescBox {
margin-bottom: 40px;
}
.templateDescTitle {
font-size: 16px;
line-height: 24px;
color: rgba(30, 38, 51, 1);
font-weight: 600;
margin-bottom: 12px;
}
.templateDesc {
font-size: 12px;
line-height: 20px;
color: #565c66;
}
.backgroundTitle {
background-color: rgba(245, 246, 247, 1);
height: 48px;
display: flex;
justify-content: flex-start;
align-items: center;
padding: 12px 16px;
box-sizing: border-box;
position: relative;
}
.backgroundTitleTextIcon {
visibility: hidden;
}
.backgroundTitleTextIconShow {
visibility: visible;
}
.backgroundTitleText {
font-size: 16px;
font-weight: 600;
line-height: 24px;
color: rgba(30, 38, 51, 1);
margin-left: 12px;
}
.taskDescIcon {
margin-left: 8px;
}
.flowDescIcon {
margin-left: 8px;
}
.formItems {
padding: 20px 44px 40px 44px;
}
.formItem {
margin-bottom: 20px;
}
.fileSelectImg {
cursor: pointer;
}
.formItemLable {
margin-bottom: 12px;
font-size: 14px;
color: rgba(30, 38, 51, 1);
line-height: 22px;
font-weight: 600;
}
.required::after {
content: "*";
color: red;
margin-left: 3px;
}
.taskConfigBox {
padding: 24px 44px 40px 44px;
}
.flowTitle {
line-height: 16px;
margin: 3px 0 27px;
color: rgba(30, 38, 51, 1);
font-size: 14px;
font-weight: 600;
border-left: 3px solid rgba(19, 112, 255, 1);
padding-left: 3px;
display: flex;
align-items: center;
}
.parameter {
margin-bottom: 20px;
position: relative;
}
.parameterTitle {
color: rgba(30, 38, 51, 1);
font-size: 14px;
font-weight: 600;
line-height: 22px;
margin-bottom: 12px;
}
.parameterContent {
position: relative;
}
.parameterDesc {
position: absolute;
top: 12px;
right: -22px;
}
.parameterDataType {
color: rgba(138, 144, 153, 1);
margin-left: 16px;
}
This diff is collapsed.
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-21 15:25:25
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-06 11:55:41
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/WorkFlow/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import Flow from "../../components/Flow";
import { ITemplateConfig } from "../interface";
interface IProps {
templateConfigInfo?: ITemplateConfig;
setSelectedNodeId?: (val:string) => void;
selectedNodeId?: string;
}
const WorkFlow = (props: IProps) => {
const { templateConfigInfo,setSelectedNodeId, selectedNodeId } = props;
return <Flow tasks={templateConfigInfo?.tasks} setSelectedNodeId={setSelectedNodeId} selectedNodeId={selectedNodeId}/>;
};
export default WorkFlow;
import React from "react";
// import { MarkerType } from "react-flow-renderer";
export const nodes = [
{
id: "1",
type: "input",
data: {
label: (
<>
Welcome to <strong>React Flow!</strong>
</>
),
},
position: { x: 250, y: 0 },
},
{
id: "2",
data: {
label: (
<>
This is a <strong>default node</strong>
</>
),
},
position: { x: 100, y: 100 },
},
{
id: "3",
data: {
label: (
<>
This one has a <strong>custom style</strong>
</>
),
},
position: { x: 400, y: 100 },
style: {
background: "#D6D5E6",
color: "#333",
border: "1px solid #222138",
width: 180,
},
},
{
id: "4",
position: { x: 250, y: 200 },
data: {
label: "Another default node",
},
},
{
id: "5",
data: {
label: "Node id: 5",
},
position: { x: 250, y: 325 },
},
{
id: "6",
type: "output",
data: {
label: (
<>
An <strong>output node</strong>
</>
),
},
position: { x: 100, y: 480 },
},
{
id: "7",
type: "output",
data: { label: "Another output node" },
position: { x: 400, y: 450 },
},
];
export const edges = [
{ id: "e1-2", source: "1", target: "2", label: "this is an edge label" },
{ id: "e1-3", source: "1", target: "3" },
{
id: "e3-4",
source: "3",
target: "4",
animated: true,
label: "animated edge",
},
{
id: "e4-5",
source: "4",
target: "5",
label: "edge with arrow head",
},
{
id: "e5-6",
source: "5",
target: "6",
type: "smoothstep",
label: "smooth step edge",
},
{
id: "e5-7",
source: "5",
target: "7",
type: "step",
style: { stroke: "#f6ab6c" },
label: "a step edge",
animated: true,
labelStyle: { fill: "#f6ab6c", fontWeight: 700 },
},
];
import * as React from "react";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import FormHelperText from "@mui/material/FormHelperText";
import Select, { SelectProps } from "@mui/material/Select";
export interface IOption {
label: string;
value: string;
disabled?: boolean;
}
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<IOption> => {
return arr.map((item: any) => {
return {
label: item[labelKey],
value: item[valueKey],
disabled: item[disabledKey],
};
});
};
interface IProps
extends Omit<SelectProps, "value" | "options" | "onChange" | "title"> {
value?: any;
options: IOption[];
onChange?: any;
/** 类型变种 */
variant?: "standard" | "outlined" | "filled";
/** title */
title?: string;
/** 是否显示title */
isTitle?: boolean;
size?: "small" | "medium";
multiple?: boolean; // 多选
error?: boolean;
helpertext?: string;
}
export default function MySelect(props: IProps) {
const {
value,
options,
onChange,
title,
isTitle = false,
variant,
size = "small",
multiple = false,
error = false,
helpertext,
} = props;
return (
<FormControl fullWidth variant={variant} error={error}>
{isTitle ? (
<InputLabel id="demo-simple-select-label">
{title || "请选择"}
</InputLabel>
) : null}
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
label={title || ""}
size={size}
{...props}
value={value}
onChange={onChange}
multiple={multiple}
>
{options.length
? options?.map((item: IOption) => {
return (
<MenuItem
key={item.value}
value={item.value}
disabled={item?.disabled}
>
{item.label}
</MenuItem>
);
})
: null}
</Select>
{helpertext && error && <FormHelperText>{helpertext}</FormHelperText>}
</FormControl>
);
}
.swBox {
position: fixed;
z-index: 1000;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: RGBA(247, 248, 250, 1);
overflow-y: scroll;
}
.swHeader {
z-index: 1001;
position: sticky;
top: 0;
height: 56px;
background-color: #fff;
box-shadow: 0px 3px 10px 0px rgba(0, 24, 57, 0.04);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
}
.swHeaderLeft {
display: flex;
justify-content: flex-start;
align-items: center;
}
.swTemplateTitle {
margin: 0 19px 0 8px;
line-height: 22px;
font-size: 14px;
color: rgba(30, 38, 51, 1);
font-weight: 600;
padding-right: 20px;
border-right: 1px solid rgba(235, 237, 240, 1);
}
.swHeaderLable {
color: rgba(138, 144, 153, 1);
font-size: 12px;
}
.swHeaderValue {
color: rgba(30, 38, 51, 1);
font-size: 12px;
margin-right: 24px;
}
.swContent {
display: flex;
height: calc(100vh - 56px);
}
.swFormBox {
background-color: #fff;
border-right: 1xp solid rgba(235, 237, 240, 1);
width: 608px;
overflow-y: scroll;
box-sizing: border-box;
padding: 36px;
}
.swFlowBox {
flex: 1;
height: calc(100vh - 56px);
}
.fullScreenBox {
position: absolute;
background-color: #fff;
cursor: pointer;
z-index: 1000;
right: 24px;
bottom: 24px;
padding: 8px;
}
.fullScreenBox:hover {
opacity: 0.6;
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
import { IParameter } from "./interface";
export const getCheckResult = (
parameter: IParameter,
value: string
): {
error: boolean;
helperText: string;
} => {
let error = false;
let helperText = "";
// 表单校验
if (parameter.required) {
if (Array.isArray(value)) {
if (value.length === 0) {
error = true;
helperText = "该选项是必填项";
}
} else if (value === "" || value === null || value === undefined) {
error = true;
helperText = "该选项是必填项";
}
}
if (parameter.validators.length > 0) {
parameter.validators.forEach((validator) => {
const reg = new RegExp(validator.regex);
if (!reg.test(value)) {
error = true;
helperText = validator.message;
}
});
}
return {
error,
helperText,
};
};
...@@ -2,24 +2,25 @@ ...@@ -2,24 +2,25 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13 * @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-07 21:39:30 * @LastEditTime: 2022-06-28 11:30:27
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx * @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
import { memo, useEffect, useState } from "react"; import { memo, useCallback, useEffect, useState } from "react";
import _ from "lodash"; import _ from "lodash";
import { useStores } from "@/store"; import { useNavigate } from "react-router-dom";
import styles from "./index.module.css";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import OutlinedInput from "@mui/material/OutlinedInput"; import OutlinedInput from "@mui/material/OutlinedInput";
import SearchIcon from "@mui/icons-material/Search"; import SearchIcon from "@mui/icons-material/Search";
import useMyRequest from "@/hooks/useMyRequest";
import LinearProgress, { linearProgressClasses } from '@mui/material/LinearProgress'; import LinearProgress, { linearProgressClasses } from '@mui/material/LinearProgress';
import { TablePagination } from '@mui/material'; import { TablePagination } from '@mui/material';
import ActionsComponent from "../../../../components/Material.Ui/Table/ActionsComponent"
import TextField from '@mui/material/TextField'; import TextField from '@mui/material/TextField';
import MenuItem from '@mui/material/MenuItem'; import MenuItem from '@mui/material/MenuItem';
import SimpleDialog from "./components/simpleDialog" import SimpleDialog from "./components/simpleDialog"
import { useStores } from "@/store";
import useMyRequest from "@/hooks/useMyRequest";
import ActionsComponent from "../../../../components/Material.Ui/Table/ActionsComponent"
import runTime from '../../../../assets/project/runTime.svg' import runTime from '../../../../assets/project/runTime.svg'
import jobCost from '../../../../assets/project/jobCost.svg' import jobCost from '../../../../assets/project/jobCost.svg'
import jobSue from '../../../../assets/project/jobSue.svg' import jobSue from '../../../../assets/project/jobSue.svg'
...@@ -39,6 +40,9 @@ import { toJS } from "mobx"; ...@@ -39,6 +40,9 @@ import { toJS } from "mobx";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import usePass from "@/hooks/usePass"; import usePass from "@/hooks/usePass";
import styles from "./index.module.css";
const currencies = [ const currencies = [
{ {
value: 'ALL', value: 'ALL',
...@@ -93,6 +97,7 @@ const ProjectMembers = observer(() => { ...@@ -93,6 +97,7 @@ const ProjectMembers = observer(() => {
}, 60000); }, 60000);
}, },
}); });
const navigate = useNavigate()
// 删除作业 // 删除作业
const { run: delWorkflowJob } = useMyRequest(deleteWorkflowJob, { const { run: delWorkflowJob } = useMyRequest(deleteWorkflowJob, {
...@@ -238,6 +243,16 @@ const ProjectMembers = observer(() => { ...@@ -238,6 +243,16 @@ const ProjectMembers = observer(() => {
} }
} }
/** 点击每一行 */
const rowClick = useCallback(
(id: string) => {
navigate(`/product/cadd/projectJobDetail`, {
state: { taskId: id },
});
},
[navigate],
);
return ( return (
<Box className={styles.headerBox}> <Box className={styles.headerBox}>
...@@ -312,7 +327,7 @@ const ProjectMembers = observer(() => { ...@@ -312,7 +327,7 @@ const ProjectMembers = observer(() => {
{ {
jobList.length > 0 && jobList.map((item: any, key) => { jobList.length > 0 && jobList.map((item: any, key) => {
return ( return (
<Box className={styles.tabBox}> <Box className={styles.tabBox} onClick={()=>rowClick(item.id)}>
<Box className={styles.tabBoxInfo}> <Box className={styles.tabBoxInfo}>
<div className={styles.tabBoxTitle}>{item.name}</div> <div className={styles.tabBoxTitle}>{item.name}</div>
<Box className={styles.tabBoxDescInfo}> <Box className={styles.tabBoxDescInfo}>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment