Commit 3829e562 authored by wuyongsheng's avatar wuyongsheng

Merge branch 'feat-20220620-taskSubmission' into 'release'

Feat 20220620 task submission

See merge request !67
parents a76e2c1e 16d0cb96
......@@ -1437,17 +1437,48 @@
"integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ=="
},
"@emotion/react": {
"version": "11.9.0",
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.9.0.tgz",
"integrity": "sha512-lBVSF5d0ceKtfKCDQJveNAtkC7ayxpVlgOohLgXqRwqWr9bOf4TZAFFyIcNngnV6xK6X4x2ZeXq7vliHkoVkxQ==",
"version": "11.9.3",
"resolved": "https://registry.npmmirror.com/@emotion/react/-/react-11.9.3.tgz",
"integrity": "sha512-g9Q1GcTOlzOEjqwuLF/Zd9LC+4FljjPjDfxSM7KmEakm+hsHXk+bYZ2q+/hTJzr0OUNkujo72pXLQvXj6H+GJQ==",
"requires": {
"@babel/runtime": "^7.13.10",
"@emotion/babel-plugin": "^11.7.1",
"@emotion/cache": "^11.7.1",
"@emotion/serialize": "^1.0.3",
"@emotion/cache": "^11.9.3",
"@emotion/serialize": "^1.0.4",
"@emotion/utils": "^1.1.0",
"@emotion/weak-memoize": "^0.2.5",
"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": {
......@@ -4126,6 +4157,11 @@
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
"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": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.1.tgz",
......@@ -4679,6 +4715,72 @@
"resolved": "https://registry.npmmirror.com/custom-error-instance/-/custom-error-instance-2.1.1.tgz",
"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": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
......@@ -10242,6 +10344,29 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
"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": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
......@@ -11478,6 +11603,16 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"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": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
......@@ -11838,7 +11973,7 @@
},
"webpack-dev-server": {
"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==",
"requires": {
"@types/bonjour": "^3.5.9",
......@@ -12398,6 +12533,11 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"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 @@
"react-dev-utils": "^12.0.1",
"react-dom": "^18.1.0",
"react-dropzone": "^14.2.1",
"react-flow-renderer": "^10.3.7",
"react-refresh": "^0.11.0",
"react-router-dom": "^6.3.0",
"resolve": "^1.20.0",
......
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-13 09:56:57
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-13 09:59:29
* @LastEditTime: 2022-06-24 16:32:31
* @FilePath: /bkunyun/src/api/api_manager.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -29,17 +29,13 @@ const RESTAPI = {
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: `${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_DEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/job/`, //删除工作流任务
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`, //查询任务某个算子详情
};
export default RESTAPI;
......@@ -176,7 +176,7 @@ export function useHttp(raw?: boolean) {
export default rawHttp;
export interface IResponse<T> {
errorCode: number;
massage: string;
errorCode?: number;
massage?: string;
data: T;
}
......@@ -202,6 +202,47 @@ 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 {
current,
menu,
......@@ -218,4 +259,8 @@ export {
getDataFileMovePackage,
getDataFileDel,
getDataFileDelPackage,
fetchTemplateConfigInfo,
fetchWorkFlowJob,
submitWorkFlow,
getworkFlowTaskInfo,
};
<?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
.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 style from "./index.module.css";
type FileSelectProps = {
open: boolean;
onConfirm: any;
onClose: any;
};
const FileSelect = observer((props: FileSelectProps) => {
const { onConfirm } = 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("/");
useEffect(() => {
if (fileToken && projectId) {
CloudEController.JobOutFileDirtree(
"/",
fileToken,
projectId,
false
)?.then((res: any) => {
if (Array.isArray(res.data)) {
setTreeData(res.data);
} else {
setTreeData([]);
}
});
}
}, [projectId, fileToken]);
const renderLabel = (labelNmae: string) => {
return (
<span className={style.treeLabel}>
<img className={style.labelFolderIcon} src={folderIcon} alt="" />
<span className={style.treeLabelText}>{labelNmae}</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}
>
<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;
......@@ -42,7 +42,7 @@ const getTransitionComponent = (transition: "grow" | "fade") => {
const MySnackbarProvider = ({
vertical = "top",
horizontal = "center",
autoHideDuration = 2000,
autoHideDuration = 5000,
snackerClasses,
ClickAwayListenerProps,
ContentProps,
......
import * as React from "react";
import FormGroup 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";
type IMyCheckBoxProps = {
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 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>
);
}
import TextField from "@mui/material/TextField";
type MyInputProps = {
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
error={error}
helperText={helperText}
value={value}
sx={{ ...inputSx }}
id={id}
label={label}
variant={variant}
onChange={onChange}
onFocus={onFocus}
size={size}
placeholder={placeholder}
fullWidth={fullWidth}
InputProps={{
...InputProps,
}}
/>
);
};
export default MyInput;
import * as React from "react";
import { ReactNode } 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>) => {
console.log(123);
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();
};
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;
import * as React from "react";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormHelperText from '@mui/material/FormHelperText';
type IMyRadioProps = {
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
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 {
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?: IOption;
......
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @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
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
import { AnyMap } from "immer/dist/internal";
......@@ -16,7 +16,8 @@ import Demo from "@/views/demo";
import ProjectSetting from "@/views/Project/ProjectSetting";
import ProjectData from "@/views/Project/ProjectData";
import ProjectWorkbench from "@/views/Project/ProjectWorkbench";
import ProjectSubmitWork from "@/views/Project/ProjectSubmitWork";
import ProjectJobDetail from "@/views/Project/ProjectJobDetail";
export type route = {
id?: string;
......@@ -51,7 +52,9 @@ export const elements: {
Demo: Demo,
ProjectSetting: ProjectSetting,
ProjectData: ProjectData,
ProjectWorkbench:ProjectWorkbench
ProjectWorkbench: ProjectWorkbench,
ProjectSubmitWork: ProjectSubmitWork,
ProjectJobDetail: ProjectJobDetail
};
export const routes: Array<route | navigate> = [
......
......@@ -140,11 +140,10 @@ const FileItem = observer((props: IProps) => {
<div className={styles.speedBox}>
<span className={styles.span}>{`${storageUnitFromB(
itemInfo?.bytesUploaded || 0
)}/${storageUnitFromB(itemInfo?.bytesTotal || 0)}`}</span>{" "}
:
<span className={styles.span}>{`${storageUnitFromB(
)}/${storageUnitFromB(itemInfo?.bytesTotal || 0)}`}</span>
{statusMsg !== '上传失败' ? <span className={styles.span}>{`${storageUnitFromB(
speed
)}/s`}</span>
)}/s`}</span> : null}
</div>
)}
</div>
......
......@@ -106,13 +106,12 @@ const ConsoleLayout = observer(() => {
horizontal: "right",
}}
>
<Box className={style.topRightItem}>
<img
className={style.topRightItem}
src={uploadIcon}
alt=""
style={{ verticalAlign: "middle" }}
/>
</Box>
</MyPopover>
<Box className={style.topRightItem}>
<Box
......
......@@ -19,6 +19,7 @@ const MenuLayout = observer(() => {
<CurrentProject />
<List className={style.list}>
{permissionStore.sidebarRouters.map((item, index) => {
if (item.show) {
return (
<li
key={"sidebar" + index}
......@@ -31,6 +32,8 @@ const MenuLayout = observer(() => {
{item.name}
</li>
);
}
return null;
})}
</List>
</Box>
......
.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;
}
.taskInfoValue {
color: rgba(30, 38, 51, 1);
font-size: 14px;
line-height: 22px;
max-width: 210px;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
overflow: hidden;
position: relative;
align-items: center;
}
.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;
}
.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;
}
\ No newline at end of file
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-21 20:03:56
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-29 17:07:49
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { useEffect, useState, useMemo, useCallback } from "react";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
import classNames from "classnames";
import { useLocation, useNavigate } from "react-router-dom";
import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
import IconButton from "@mui/material/IconButton";
import ButtonComponent from "@/components/mui/Button";
import useMyRequest from "@/hooks/useMyRequest";
import { fetchWorkFlowJob, getworkFlowTaskInfo } from "@/api/project_api";
import { IResponse } from "@/api/http";
import jobSue from "@/assets/project/jobSue.svg";
import jobStop from "@/assets/project/jobStop.svg";
import jobRun from "@/assets/project/jobRun.svg";
import fullScreen from "@/assets/project/fullScreen.svg";
import partialScreen from "@/assets/project/partialScreen.svg";
import CloudEController from "@/api/fileserver/CloudEController";
import jobFail from "@/assets/project/jobFail.svg";
import fileIcon from "@/assets/project/fileIcon.svg";
import dataSetIcon from "@/assets/project/dataSetIcon.svg";
import { useStores } from "@/store";
import { getDataFind } from "@/api/project_api";
import { ITaskInfo } from "../ProjectSubmitWork/interface";
import Flow from "../components/Flow";
import { cancelWorkflowJob, deleteWorkflowJob } from "@/api/workbench_api";
import { useMessage } from "@/components/MySnackbar";
import MyPopconfirm from "@/components/mui/MyPopconfirm";
import styles from "./index.module.css";
const stateMap = {
RUNNING: "正在运行",
ABORTED: "运行终止",
FAILED: "运行失败",
SUCCEEDED: "运行成功",
};
const statusMap = {
Done: "运行完成",
Running: "正在运行",
Failed: "运行失败",
Pending: "等待运行",
};
type IStatus = "Done" | "Running" | "Failed" | "Pending";
let randerOutputs: Array<any> = [];
const ProjectSubmitWork = observer(() => {
const { currentProjectStore } = useStores();
const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken);
const projectId = toJS(currentProjectStore.currentProjectInfo.id);
const [workFlowJobInfo, setWorkFlowJobInfo] = useState<ITaskInfo>();
const [patchInfo, setPatchInfo] = useState<any>();
const [activePatchId, setActivePatchId] = useState<string>("");
const [overviewActive, setOverviewActive] = useState(true);
const [activeFlowIndex, setActiveFlowIndex] = useState<number>(0);
const [showOptions, setShowOptions] = useState<boolean>(false);
const [randerOutputs1, setRanderOutputs] = useState<Array<any>>([]);
const location: any = useLocation();
const navigate = useNavigate();
const message = useMessage();
const [fullScreenShow, setFullScreenShow] = useState<boolean>(false);
const { name, state } = workFlowJobInfo || {};
/** 获取模版数据 */
const { run } = useMyRequest(fetchWorkFlowJob, {
onSuccess: (res: IResponse<ITaskInfo>) => {
getOutouts(res.data.outputs);
setWorkFlowJobInfo(res.data);
},
});
useEffect(() => {
const locationInfo: any = location?.state;
run({
id: locationInfo.taskId,
});
}, [location?.state, run]);
const { run: getworkFlowTaskInfoRun } = useMyRequest(getworkFlowTaskInfo, {
onSuccess: (res) => {
setPatchInfo(res.data);
},
});
const goToProjectData = (path: string) => {
path = path.slice(13);
if (path) {
navigate(`/product/cadd/projectData`, {
state: { pathName: "path" },
});
}
};
const getOutouts = (outputs: any) => {
if (outputs) {
let result = Object.keys(outputs);
let arr = result.map((item) => {
let type = "file";
if (outputs[item].indexOf("dataset") !== -1) {
type = "dataset";
}
return {
name: item,
type,
path: outputs[item],
size: 0,
};
});
arr.forEach(async (item, index) => {
if (item.type === "dataset") {
await getDataSetSize(item, index);
} else {
await getFileSize(item, index);
}
});
randerOutputs = arr;
setRanderOutputs([...randerOutputs]);
} else {
randerOutputs = [];
setRanderOutputs([]);
}
};
const getDataSetSize = async (item: any, index: number) => {
let path = item.path.slice(13);
const lastIndex = path.lastIndexOf("/");
if (lastIndex === -1) {
path = "/";
} else {
path = path.slice(0, lastIndex + 1);
}
const res = await getDataFind({
projectId: projectId as string,
path: path,
});
res.data.forEach((item1: any) => {
if (item1.name === item.path.slice(item.path.lastIndexOf("/") + 1)) {
randerOutputs[index].size = `${item1.size}条`;
setRanderOutputs([...randerOutputs]);
}
});
};
const getFileSize = (item: any, index: number) => {
let path = item.path.slice(13);
const lastIndex = path.lastIndexOf("/");
if (lastIndex === -1) {
path = "/";
} else {
path = path.slice(0, lastIndex + 1);
}
CloudEController.JobOutFileList(
path,
fileToken as string,
projectId as string,
false
)?.then((res) => {
if (Array.isArray(res.data)) {
res.data.forEach((item1) => {
if (item1.name === item.path.slice(item.path.lastIndexOf("/") + 1)) {
randerOutputs[index].size = item1.size;
setRanderOutputs([...randerOutputs]);
}
});
}
});
};
// 取消作业
const { run: cancelWorkJob } = useMyRequest(cancelWorkflowJob, {
onSuccess: (res: IResponse<boolean>) => {
const { errorCode } = res;
if (errorCode === 0) {
message.success("操作成功!");
}
navigate(-1);
},
});
// 取消作业
const { run: deleteWorkJob } = useMyRequest(deleteWorkflowJob, {
onSuccess: (res: IResponse<boolean>) => {
const { errorCode } = res;
if (errorCode === 0) {
message.success("操作成功!");
}
navigate(-1);
},
});
const handleBatch = (id: string) => {
setActivePatchId(id);
if (id) {
setActiveFlowIndex(0);
getworkFlowTaskInfoRun({
jobId: workFlowJobInfo?.id as string,
taskId: id,
});
}
};
const randerParameters = useMemo(() => {
if (patchInfo?.children) {
if (patchInfo.children.length > 0) {
return patchInfo.children[activeFlowIndex].parameters;
} else {
return patchInfo?.parameters;
}
} else {
return patchInfo?.parameters;
}
}, [activeFlowIndex, patchInfo]);
const handleParams = () => {
setOverviewActive(false);
setShowOptions(!showOptions);
};
const handleDownLoad = (path: string) => {
if (path.indexOf("/home/cloudam") !== -1) {
path = path.slice(13);
}
CloudEController.JobFileDownload(
path,
fileToken as string,
projectId as string
);
};
/** 终止任务 */
const onStopJob = useCallback(() => {
cancelWorkJob({
jobid: workFlowJobInfo?.id || "",
});
}, [cancelWorkJob, workFlowJobInfo?.id]);
/** 删除任务 */
const onDeleteJob = useCallback(() => {
deleteWorkJob({
id: workFlowJobInfo?.id || "",
});
}, [deleteWorkJob, workFlowJobInfo?.id]);
return (
<div className={styles.swBox}>
{fullScreenShow ? null : (
<div className={styles.swHeader}>
<div className={styles.swHeaderLeft}>
<IconButton
color="primary"
onClick={() => navigate(-1)}
aria-label="upload picture"
component="span"
size="small"
>
<ArrowBackIosNewIcon
sx={{
color: "rgba(194, 198, 204, 1)",
width: "12px",
height: "12px",
}}
/>
</IconButton>
<div className={styles.swTemplateTitle}>{name}</div>
</div>
<div className={styles.swHeaderRight}>
<MyPopconfirm
title={
state === "RUNNING"
? "正在运行的任务终止后将无法重新运行,确认继续吗?"
: "任务被删除后将无法恢复,确认继续吗?"
}
onConfirm={() => {
state === "RUNNING" ? onStopJob() : onDeleteJob();
}}
>
<ButtonComponent
text={state === "RUNNING" ? "终止" : "删除"}
variant="outlined"
color="secondary"
// click={onStopJob}
></ButtonComponent>
</MyPopconfirm>
</div>
</div>
)}
<div className={styles.swContent}>
{fullScreenShow ? null : (
<div className={styles.swFormBox}>
{!activePatchId && (
<div className={styles.taskInfo}>
<div className={styles.title}>任务结果</div>
{workFlowJobInfo?.outputs && (
<div className={styles.taskResults}>
{randerOutputs1.map((item, index) => {
return (
<div key={index} className={styles.outputLi}>
<MyPopconfirm
title="即将跳转至项目数据内该任务的结果目录,确认继续吗?"
onConfirm={() => goToProjectData(item.path)}
>
<div className={styles.outputLiLeft}>
<img
className={styles.outputLiLeftImg}
src={
item.type === "file" ? fileIcon : dataSetIcon
}
alt=""
/>
{item.name}
</div>
</MyPopconfirm>
<span className={styles.outputLiRight}>
{item.size}
</span>
</div>
);
})}
</div>
)}
{!workFlowJobInfo?.outputs && (
<div className={styles.notResults}>暂无结果文件</div>
)}
<div className={styles.title}>任务信息</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务名称</div>
<div className={styles.taskInfoValue} title={name}>
{name || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务ID</div>
<div
className={styles.taskInfoValue}
title={workFlowJobInfo?.id}
>
{workFlowJobInfo?.id || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>输出路径</div>
<div
className={styles.taskInfoValue}
onClick={() =>
goToProjectData(workFlowJobInfo?.outputPath as string)
}
>
{workFlowJobInfo?.outputPath || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行状态</div>
<div className={styles.taskInfoValue}>
{state === "SUCCEEDED" && (
<img
className={styles.taskInfoValueIcon}
src={jobSue}
alt=""
/>
)}
{state === "RUNNING" && (
<img
className={styles.taskInfoValueIcon}
src={jobRun}
alt=""
/>
)}
{state === "ABORTED" && (
<img
className={styles.taskInfoValueIcon}
src={jobStop}
alt=""
/>
)}
{state === "FAILED" && (
<img
className={styles.taskInfoValueIcon}
src={jobFail}
alt=""
/>
)}
{state ? stateMap[state] : "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specTitle || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板版本</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specVersion || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>花费(元)</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.jobCost || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建人</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.creator || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.createTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.costTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>日志文件</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.logPath && (
<span
className={styles.taskInfoDownload}
onClick={() => handleDownLoad(workFlowJobInfo?.logPath)}
>
下载
</span>
)}
{!workFlowJobInfo?.logPath && "-"}
</div>
</div>
</div>
)}
{activePatchId && (
<div className={styles.suanziInfo}>
<div className={styles.title}>{patchInfo?.title}</div>
<div className={styles.tabs}>
<div
className={classNames({
[styles.tabLi]: true,
[styles.tabLiAcitve]: overviewActive,
})}
onClick={() => setOverviewActive(true)}
>
概览
</div>
<div
className={classNames({
[styles.tabLi]: true,
[styles.tabLiAcitve]: !overviewActive,
})}
// onClick={() => setOverviewActive(false)}
onClick={() => handleParams()}
>
{patchInfo?.children.length > 0
? patchInfo?.children[activeFlowIndex].title
: patchInfo?.title}
{showOptions && patchInfo?.children.length > 0 && (
<div className={styles.options}>
{patchInfo?.children.map((item: any, index: number) => {
return (
<div
key={index}
className={styles.option}
onClick={() => setActiveFlowIndex(index)}
>
{item.title}
</div>
);
})}
</div>
)}
</div>
</div>
{overviewActive && (
<div className={styles.overview}>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>描述</div>
<div
className={classNames({
[styles.taskInfoValue]: true,
[styles.taskInfoValueShowAll]: true,
})}
>
{patchInfo?.description}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>算子版本</div>
<div className={styles.taskInfoValue}>
{patchInfo?.creator || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>算子状态</div>
<div className={styles.taskInfoValue}>
{patchInfo?.status === "Done" && (
<img
className={styles.taskInfoValueIcon}
src={jobSue}
alt=""
/>
)}
{patchInfo?.status === "Running" && (
<img
className={styles.taskInfoValueIcon}
src={jobRun}
alt=""
/>
)}
{patchInfo?.status === "Failed" && (
<img
className={styles.taskInfoValueIcon}
src={jobFail}
alt=""
/>
)}
{statusMap[patchInfo?.status as IStatus]}
</div>
</div>
</div>
)}
{!overviewActive && (
<div className={styles.params}>
{randerParameters.map((parameter: any) => {
return (
<div className={styles.taskInfoLi} key={parameter.name}>
<div className={styles.taskInfoParams}>
{parameter.name}
</div>
<div className={styles.taskInfoValue}>
{parameter.value || "-"}
</div>
</div>
);
})}
</div>
)}
</div>
)}
</div>
)}
<div
className={styles.swFlowBox}
style={fullScreenShow ? { height: "100vh" } : undefined}
>
<Flow tasks={workFlowJobInfo?.tasks} onBatchClick={handleBatch} />
</div>
</div>
<img
className={styles.fullScreenBox}
src={fullScreenShow ? partialScreen : fullScreen}
onClick={() => setFullScreenShow(!fullScreenShow)}
alt="全屏"
/>
</div>
);
});
export default ProjectSubmitWork;
.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;
}
import { ITemplateConfig, IRenderTasks, IRenderTask } from "../interface";
import styles from "./index.module.css";
import MyInput from "@/components/mui/MyInput";
import Tooltip from "@mui/material/Tooltip";
import classnames from "classnames";
import { useState, useMemo, useImperativeHandle, useCallback } from "react";
import FileSelect from "@/components/FileSelect";
import moment from "moment";
import MySelect, { optionsTransform } from "../components/MySelect";
import MyCheckBox from "@/components/mui/MyCheckBox";
import MyRadio from "@/components/mui/MyRadio";
import _ from "lodash";
import { getCheckResult } from "../util";
import fileSelectIcon from "@/assets/project/fileSelect.svg";
import questionMark from "@/assets/project/questionMark.svg";
import tipsIcon from "@/assets/project/tipsIcon.svg";
import jobSueIcon from "@/assets/project/jobSue.svg";
import { IParameter } from "../interface";
type ConfigFormProps = {
templateConfigInfo?: ITemplateConfig;
setParameter: any;
onRef?: React.Ref<any>;
};
const ConfigForm = (props: ConfigFormProps) => {
const { templateConfigInfo, setParameter } = props;
const [name, setName] = useState<string>(""); // 任务名称
const [nameHelp, setNameHelp] = useState({
error: false,
helperText: "",
});
const [outputPath, setOutputPath] = useState<string>("ProjectData"); // 输出路径
const [outputPathHelp, setOutputPathHelp] = useState({
error: false,
helperText: "",
});
const getNameAndPath = () => {
return {
name,
outputPath,
nameAndOutputPathCheck: !(checkName(name) || checkOutputPath(outputPath)), // 任务名称、输出路径是否通过校验
};
};
const setInitName = (name: string) => {
setName(`${name}_${moment(new Date()).format("YYYY_MM_DD_HH_mm")}`);
};
useImperativeHandle(props.onRef, () => {
return {
getNameAndPath: getNameAndPath,
setInitName: setInitName,
};
});
const [fileSelectOpen, setFileSelectOpen] = useState(false); // 选择输出路径的弹窗显示控制
const [fileSelectObject, setFileSelectObject] = useState({
taskId: "",
parameterName: "",
});
const onFileSelectConfirm = (path: string) => {
setFileSelectOpen(false);
if (fileSelectObject.taskId) {
setParameter(
`ProjectData${path === "/" ? "" : path}`,
fileSelectObject.taskId,
fileSelectObject.parameterName
);
} else {
setOutputPath(`ProjectData${path === "/" ? "" : path}`);
checkOutputPath(`ProjectData${path === "/" ? "" : path}`);
}
};
const handleFileSelectOnClose = () => {
setFileSelectOpen(false);
};
const handleOpenFileSelect = (
taskId: string = "",
parameterName: string = ""
) => {
setFileSelectObject({
taskId,
parameterName,
});
setFileSelectOpen(true);
};
const handleNameChange = (e: any) => {
setName(e.target.value);
checkName(e.target.value);
};
const checkName = (name: string = "") => {
const reg = new RegExp(/^[a-zA-Z0-9\u4e00-\u9fa5-_]{3,30}$/);
if (reg.test(name)) {
setNameHelp({
error: false,
helperText: "",
});
return false;
} else {
setNameHelp({
error: true,
helperText:
"请输入正确任务名称(3~30字符,可包含大小写字母、数字、中文、特殊符号“-”、“_”)",
});
return true;
}
};
const checkOutputPath = (outputPath: string = "") => {
if (outputPath) {
setOutputPathHelp({
error: false,
helperText: "",
});
return false;
} else {
setOutputPathHelp({
error: true,
helperText: "请选择输出路径",
});
return true;
}
};
const renderTasks: IRenderTasks = useMemo(() => {
const result: IRenderTasks = [];
templateConfigInfo?.tasks.forEach((task, taskIndex) => {
if (task.type === "BATCH") {
result.push({ ...task, flows: [], isCheck: true });
} else {
result[result.length - 1]?.flows.push({ ...task });
}
});
result.forEach((task) => {
let isCheck = true;
if (task.parameters.length > 0) {
task.parameters.forEach((parameter) => {
const { error } = getCheckResult(parameter, parameter.value);
if (error) {
isCheck = false;
return;
}
});
}
if (task.flows.length > 0) {
task.flows.forEach((flow) => {
if (flow.parameters.length > 0) {
flow.parameters.forEach((parameter) => {
const { error } = getCheckResult(parameter, parameter.value);
if (error) {
isCheck = false;
return;
}
});
}
});
}
task.isCheck = isCheck;
});
return result;
}, [templateConfigInfo]);
const handleParameterChange = (
e: any,
taskId: string,
parameterName: string
) => {
setParameter(e.target.value, taskId, parameterName);
};
const randerParameters = (parameters: Array<IParameter>, taskId: string) => {
return parameters
.filter((parameter) => parameter.hidden === false)
.map((parameter, parameterIndex) => {
return (
<div
className={styles.parameter}
key={parameter.id || "" + parameterIndex}
>
<div
className={classnames({
[styles.parameterTitle]: true,
[styles.required]: parameter.required,
})}
>
{parameter.name}
<span className={styles.parameterDataType}>
{parameter.classTypeName}
</span>
</div>
<div className={styles.parameterContent}>
{parameter.domType.toLowerCase() === "file" && (
<MyInput
value={parameter.value || ""}
InputProps={{
endAdornment: (
<img
onClick={() =>
handleOpenFileSelect(taskId, parameter.name)
}
src={fileSelectIcon}
alt=""
className={styles.fileSelectImg}
/>
),
}}
placeholder="请选择"
error={parameter.error || false}
helperText={parameter.helperText}
></MyInput>
)}
{parameter.domType.toLowerCase() === "path" && (
<MyInput
value={parameter.value || ""}
InputProps={{
endAdornment: (
<img
onClick={() =>
handleOpenFileSelect(taskId, parameter.name)
}
src={fileSelectIcon}
alt=""
className={styles.fileSelectImg}
/>
),
}}
placeholder="请选择"
error={parameter.error || false}
helperText={parameter.helperText}
></MyInput>
)}
{parameter.domType.toLowerCase() === "dataset" && (
<MyInput
value={parameter.value || ""}
InputProps={{
endAdornment: (
<img
onClick={() =>
handleOpenFileSelect(taskId, parameter.name)
}
src={fileSelectIcon}
alt=""
className={styles.fileSelectImg}
/>
),
}}
placeholder="请选择"
error={parameter.error || false}
helperText={parameter.helperText}
></MyInput>
)}
{parameter.domType.toLowerCase() === "input" && (
<MyInput
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "")
}
placeholder="请输入"
error={parameter.error || false}
helperText={parameter.helperText}
></MyInput>
)}
{parameter.domType.toLowerCase() === "select" && (
<MySelect
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "")
}
error={parameter.error || false}
helpertext={parameter.helperText}
options={optionsTransform(parameter.choices, "label")}
></MySelect>
)}
{parameter.domType.toLowerCase() === "multipleselect" && (
<MySelect
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "")
}
multiple={true}
error={parameter.error || false}
helpertext={parameter.helperText}
options={optionsTransform(parameter.choices, "label")}
></MySelect>
)}
{parameter.domType.toLowerCase() === "radio" && (
<MyRadio
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "")
}
options={optionsTransform(parameter.choices, "label")}
error={parameter.error || false}
helperText={parameter.helperText}
></MyRadio>
)}
{parameter.domType.toLowerCase() === "checkbox" && (
<MyCheckBox
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(
{
target: {
value: e,
},
},
taskId,
parameter.name || ""
)
}
options={optionsTransform(parameter.choices, "label")}
error={parameter.error || false}
helperText={parameter.helperText}
></MyCheckBox>
)}
{parameter.description && (
<Tooltip title={parameter.description} placement="top">
<img
className={styles.parameterDesc}
src={questionMark}
alt=""
/>
</Tooltip>
)}
</div>
</div>
);
});
};
return (
<div className={styles.formBox}>
<div className={styles.templateDescBox}>
<div className={styles.templateDescTitle}>模板描述</div>
<div className={styles.templateDesc}>
{templateConfigInfo?.description || ""}
</div>
</div>
<div
className={classnames({
[styles.backgroundTitle]: true,
[styles.backgroundTitlePass]: true,
})}
>
<img src="" alt="" />
<span className={styles.backgroundTitleText}>基础信息</span>
</div>
<div className={styles.formItems}>
<div className={styles.formItem}>
<div
className={classnames({
[styles.formItemLable]: true,
[styles.required]: true,
})}
>
任务名称
</div>
<div className={styles.formItem}>
<MyInput
value={name}
onChange={handleNameChange}
placeholder="请输入任务名称"
error={nameHelp.error}
helperText={nameHelp.helperText}
></MyInput>
</div>
</div>
<div className={styles.formItem}>
<div
className={classnames({
[styles.formItemLable]: true,
[styles.required]: true,
})}
>
输出路径
</div>
<div className={styles.formItem}>
<MyInput
value={outputPath || ""}
InputProps={{
endAdornment: (
<img
onClick={() => handleOpenFileSelect()}
src={fileSelectIcon}
alt="选择输出路径"
className={styles.fileSelectImg}
/>
),
}}
error={outputPathHelp.error}
helperText={outputPathHelp.helperText}
></MyInput>
</div>
</div>
</div>
{renderTasks.map((task, taskIndex) => {
return (
<div className={styles.taskBox} key={task.id + taskIndex}>
<div
className={classnames({
[styles.backgroundTitle]: true,
[styles.backgroundTitlePass]: true,
})}
>
<img
className={classnames({
[styles.backgroundTitleTextIcon]: true,
[styles.backgroundTitleTextIconShow]: task.isCheck,
})}
src={jobSueIcon}
alt=""
/>
<span className={styles.backgroundTitleText}>{task.title}</span>
{task.description && (
<Tooltip title={task.description} placement="top">
<img className={styles.taskDescIcon} src={tipsIcon} alt="" />
</Tooltip>
)}
</div>
<div className={styles.taskConfigBox}>
{randerParameters(task.parameters, task.id)}
{task.flows.map((flow) => {
return (
<div className={styles.flowConfigBox} key={flow.id}>
<div className={styles.flowTitle}>
{flow.title}
{flow.description && (
<Tooltip title={flow.description} placement="top">
<img
className={styles.flowDescIcon}
src={tipsIcon}
alt=""
/>
</Tooltip>
)}
</div>
{randerParameters(flow.parameters, flow.id)}
</div>
);
})}
</div>
</div>
);
})}
{fileSelectOpen && <FileSelect
onClose={handleFileSelectOnClose}
open={fileSelectOpen}
onConfirm={onFileSelectConfirm}
/>}
</div>
);
};
export default ConfigForm;
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-21 15:25:25
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-27 20:50:36
* @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;
}
const WorkFlow = (props: IProps) => {
const { templateConfigInfo } = props;
return <Flow tasks={templateConfigInfo?.tasks} />;
};
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);
}
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-21 20:03:56
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-26 17:24:46
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React, { useEffect, useState } from "react";
import styles from "./index.module.css";
import ConfigForm from "./ConfigForm";
import WorkFlow from "./WorkFlow";
import ButtonComponent from "@/components/mui/Button";
import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
import IconButton from "@mui/material/IconButton";
import { ITemplateConfig } from "./interface";
import _ from "lodash";
import useMyRequest from "@/hooks/useMyRequest";
import { fetchTemplateConfigInfo, submitWorkFlow } from "@/api/project_api";
import { useLocation, useNavigate } from "react-router-dom";
import { getCheckResult } from "./util";
import { IResponse } from "@/api/http";
import { templateConfigJson } from "./mock";
import { useMessage } from "@/components/MySnackbar";
import { toJS } from "mobx";
import { useStores } from "@/store";
import MyPopconfirm from "@/components/mui/MyPopconfirm";
const ProjectSubmitWork = () => {
const Message = useMessage();
const { currentProjectStore } = useStores();
const projectId = toJS(currentProjectStore.currentProjectInfo.id);
const [templateConfigInfo, setTemplateConfigInfo] =
useState<ITemplateConfig>();
const location: any = useLocation();
const navigate = useNavigate();
let configFormRef: any = React.createRef();
// 前往工作台
const goToWorkbench = () => {
navigate("/product/cadd/projectWorkbench");
};
// 返回
const handleGoBack = () => {
goToWorkbench();
};
if (!location?.state?.id) {
goToWorkbench();
}
/** 获取模版数据 */
const { run } = useMyRequest(fetchTemplateConfigInfo, {
onSuccess: (res: IResponse<ITemplateConfig>) => {
// setTemplateConfigInfo(templateConfigJson as ITemplateConfig);
setTemplateConfigInfo(res.data);
configFormRef.current.setInitName(res.data.title);
},
onError: () => {
// setTemplateConfigInfo(templateConfigJson as ITemplateConfig);
},
});
const { run: submitWorkFlowRun } = useMyRequest(submitWorkFlow, {
onSuccess: (res) => {
Message.success("提交成功");
goToWorkbench();
},
});
useEffect(() => {
run({
id: location?.state?.id,
});
}, [location?.state?.id, run]);
const setParameter = (value: any, taskId: string, parameterName: string) => {
const result: ITemplateConfig = _.cloneDeep(templateConfigInfo);
result.tasks.forEach((tack) => {
if (tack.id === taskId) {
let isCheck = true;
tack.parameters.forEach((parameter) => {
if (parameter.name === parameterName) {
parameter.value = value;
const checkResult = getCheckResult(parameter, value);
parameter.error = checkResult.error;
parameter.helperText = checkResult.helperText;
} else {
return;
}
if (getCheckResult(parameter, value).error === true) {
isCheck = false;
}
tack.isCheck = isCheck;
});
} else {
return;
}
});
setTemplateConfigInfo(result);
};
const handleSubmitForm = () => {
let check = true;
const { name, outputPath, nameAndOutputPathCheck } =
configFormRef.current.getNameAndPath();
if (!nameAndOutputPathCheck) {
console.log(123);
check = false;
}
const result: ITemplateConfig = _.cloneDeep(templateConfigInfo);
result.tasks.forEach((tack) => {
tack.parameters
.filter((parameter) => parameter.hidden === false)
.forEach((parameter) => {
const checkResult = getCheckResult(parameter, parameter.value);
parameter.error = checkResult.error;
parameter.helperText = checkResult.helperText;
if (checkResult.error) {
console.log(tack);
console.log(parameter);
check = false;
}
});
});
setTemplateConfigInfo(result);
if (check) {
let promotedParameters: any = {};
result.tasks.forEach((tack) => {
tack.parameters
.filter((parameter) => parameter.hidden === false)
.forEach((parameter) => {
let value: string = "";
if (Array.isArray(parameter.value)) {
value = parameter.value.join(",");
} else {
value = parameter.value;
}
if (
parameter.domType.toLowerCase() === "path" ||
parameter.domType.toLowerCase() === "dataset" ||
parameter.domType.toLowerCase() === "file"
) {
if (value === "ProjectData") {
value = "/home/cloudam";
} else {
value = `/home/cloudam${value.slice(11)}`;
}
}
promotedParameters[parameter.name] = {
[parameter.classTypeName]: value,
};
});
});
submitWorkFlowRun({
name,
outputPath:
outputPath === "ProjectData"
? "/home/cloudam"
: `/home/cloudam${outputPath.slice(11)}`,
projectId: projectId as string,
specId: templateConfigInfo?.id as string,
promotedParameters,
});
} else {
Message.error("请完善左侧表单再提交");
}
};
return (
<div className={styles.swBox}>
<div className={styles.swHeader}>
<div className={styles.swHeaderLeft}>
<MyPopconfirm
title="返回后,当前页面已填写内容将不保存,确认返回吗?"
onConfirm={handleGoBack}
>
<IconButton
color="primary"
// onClick={() => handleGoBack()}
aria-label="upload picture"
component="span"
size="small"
>
<ArrowBackIosNewIcon
sx={{
color: "rgba(194, 198, 204, 1)",
width: "12px",
height: "12px",
}}
/>
</IconButton>
</MyPopconfirm>
<div className={styles.swTemplateTitle}>
{templateConfigInfo?.title}
</div>
<div className={styles.swTemplateVersionBox}>
<span className={styles.swHeaderLable}>版本:</span>
<span className={styles.swHeaderValue}>
{templateConfigInfo?.version}
</span>
</div>
<div className={styles.swTemplateUpdateTimeBox}>
<span className={styles.swHeaderLable}>更新时间:</span>
<span className={styles.swHeaderValue}>
{templateConfigInfo?.updateTime}
</span>
</div>
<div className={styles.swHeaderGoback}></div>
</div>
<div className={styles.swHeaderRight}>
<MyPopconfirm
title="提交前请先确认参数填写无误,确认提交吗?"
onConfirm={handleSubmitForm}
>
<ButtonComponent
text="提交任务"
// click={handleSubmitForm}
></ButtonComponent>
</MyPopconfirm>
</div>
</div>
<div className={styles.swContent}>
<div className={styles.swFormBox}>
<ConfigForm
onRef={configFormRef}
templateConfigInfo={templateConfigInfo}
setParameter={setParameter}
/>
</div>
<div className={styles.swFlowBox}>
<WorkFlow templateConfigInfo={templateConfigInfo} />
</div>
</div>
</div>
);
};
export default ProjectSubmitWork;
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-21 20:03:56
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-28 16:22:13
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/interface.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
type IType = "BATCH" | "FLOW";
export interface IParameter {
hidden: boolean;
id?: string;
name: string;
required: boolean;
domType: IDomType;
classType: string;
classTypeName: string;
value: any;
description: string;
language: string;
languageVersion: string;
tags: Array<string>;
source: string;
productId: string;
tasks: ITask[];
validators: Array<IValidator>;
choices: Array<IChoice>;
error?: boolean;
helperText?: string;
}
export type IExecutionStatus = "Pending" | "Running" | "Done" | "Failed";
export interface ITask {
id: string;
title: string;
description: string;
position: {
x: number;
y: number;
};
type: IType;
parentNode?: string;
parameters: Array<IParameter>;
edges: Array<IEdge>;
isCheck?: boolean;
executionStatus?: IExecutionStatus;
}
export interface ITemplateConfig {
title: string;
version: string;
updateTime?: string;
description: string;
language: string;
languageVersion: string;
tags: Array<string>;
source: string;
productId: string;
tasks: ITask[];
id: string;
}
export type IDomType =
| "path"
| "dataset"
| "file"
| "input"
| "file"
| "select"
| "multipleselect"
| "radio"
| "checkbox";
// 待定
export type IValidator = {
regex: string;
message: string;
};
export interface IChoice {
key: string;
value: boolean | string | number;
}
export interface IEdge {
id: string;
source: string;
sourceHandle: string;
target: string;
targetHandle: string;
label: string;
}
// 提交任务时的动态表单的数据结构
export type IRenderTasks = Array<IRenderTask>;
export type IRenderTask = {
id: string;
title: string;
description: string;
position: {
x: number;
y: number;
};
type: IType;
parameters: Array<IParameter>;
edges: Array<IEdge>;
flows: ITask[];
isCheck: boolean; // 里面的子项表单校验是否全部通过
};
export interface ITaskInfo extends ITemplateConfig {
name: string;
outputPath: string;
state: IState;
specTitle: string;
specVersion: string;
jobCost: string;
creator: string;
createTime: string;
costTime: string;
logPath: string;
outputs?: any;
}
type IState = "SUCCEEDED" | "RUNNING" | "ABORTED" | "FAILED";
import { IEdge } from "./interface";
export const templateConfigJson = {
title: "slurm backend demo",
version: "1.0.0",
updateTime: "",
description: "简单的批任务工作流,测试slurm backend和流程是否能用",
language: "WDL",
languageVersion: "draft-2",
tags: ["Docking", "Gromax"],
source: "BASE64_ENCODED_WDL/CWL",
productId: "CADD",
id: "123",
tasks: [
{
id: "批式算子ID1",
title: "task_A",
description: "这是task_A",
position: {
x: 0,
y: 0,
},
type: "BATCH",
// parameters: [],
parameters: [
{
hidden: false,
name: "in",
required: true,
classType: "input",
classTypeName: "input",
// domType: "input",
domType: "select",
// domType: "multipleselect",
// domType: "radio",
// domType: "checkbox",
dataType: "stringParameter",
value: "",
// value: [],
description: "输入一段字符串",
validators: [
{
regex: "^[0-9]*$",
message: "只能输入数字",
},
],
choices: [
{
key: "1",
value: "a",
},
{
key: "2",
value: "2",
},
{
key: "3",
value: "3",
},
],
language: "1",
languageVersion: "1",
tags: ["1"],
source: "1",
productId: "1",
tasks: [
{
id: "id",
title: "title",
description: "description",
position: {
x: 100,
y: 200,
},
type: "BATCH",
parentNode: "1",
parameters: [],
edges: [],
},
],
},
],
edges: [] as Array<IEdge>,
},
// {
// id: "批式算子ID1",
// title: "task_A",
// description: "这是task_A",
// position: {
// x: 0,
// y: 0,
// },
// type: "FLOW",
// parameters: [
// {
// hidden: false,
// name: "in",
// required: true,
// classType: "input",
// classTypeName: "input",
// // domType: "input",
// domType: "select",
// // domType: "multipleselect",
// // domType: "radio",
// // domType: "checkbox",
// dataType: "stringParameter",
// value: "",
// // value: [],
// description: "输入一段字符串",
// validators: [
// {
// regex: "^[0-9]*$",
// message: "只能输入数字",
// },
// ],
// choices: [
// {
// key: "1",
// value: "a",
// },
// {
// key: "2",
// value: "2",
// },
// {
// key: "3",
// value: "3",
// },
// ],
// language: "1",
// languageVersion: "1",
// tags: ["1"],
// source: "1",
// productId: "1",
// tasks: [
// {
// id: "id",
// title: "title",
// description: "description",
// position: {
// x: 100,
// y: 200,
// },
// type: "BATCH",
// parentNode: "1",
// parameters: [],
// edges: [],
// },
// ],
// },
// ],
// edges: [] as Array<IEdge>,
// },
],
};
// {
// title: "workflow_gmx",
// version: "1.0.0",
// description: "Docking and Gromax",
// language: "WDL",
// languageVersion: "1.0",
// tags: ["Docking", "Gromax"],
// source: "",
// productId: "CADD",
// updateTime: "20220622",
// tasks: [
// {
// id: "批式算子ID1",
// title: "docking",
// description: "docking",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "BATCH",
// parameters: [],
// edges: [],
// },
// {
// id: "流式算子ID1",
// title: "actor 1",
// description: "actor 1",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "FLOW",
// parameters: [
// {
// hidden: false,
// name: "actor1_path",
// required: true,
// domType: "FILE",
// classType: "stringParameter",
// value: "",
// description: "路径",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor1_raw",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor1_chunk_size",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// ],
// edges: [],
// },
// {
// id: "流式算子ID2",
// title: "actor 2",
// description: "actor 2",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "FLOW",
// parameters: [],
// edges: [],
// },
// {
// id: "流式算子ID3",
// title: "actor 3",
// description: "actor 3",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "FLOW",
// parameters: [
// {
// hidden: false,
// name: "actor3_receptor",
// required: true,
// domType: "FILE",
// classType: "stringParameter",
// value: "",
// description: "路径",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor3_center",
// required: true,
// domType: "SELECT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor3_box_size",
// required: true,
// domType: "SELECT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor3_poses_num",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor3_verbosity",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// name: "actor3_exhaustiveness",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// ],
// edges: [],
// },
// {
// id: "流式算子ID4",
// title: "actor 4",
// description: "actor 4",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "FLOW",
// parameters: [
// {
// hidden: false,
// name: "actor4_path",
// required: true,
// domType: "FILE",
// classType: "stringParameter",
// value: "",
// description: "路径",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor4_compression",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor4_chunk_size",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// ],
// edges: [],
// },
// {
// id: "流式算子ID5",
// title: "actor 5",
// description: "actor 5",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "FLOW",
// parameters: [],
// edges: [],
// },
// {
// id: "流式算子ID6",
// title: "actor 6",
// description: "actor 6",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "FLOW",
// parameters: [
// {
// hidden: false,
// name: "actor6_path",
// required: true,
// domType: "FILE",
// classType: "stringParameter",
// value: "",
// description: "路径",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor6_many",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor6_chunk_size",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// {
// hidden: false,
// name: "actor6_suffix",
// required: true,
// domType: "SELECT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [
// {
// label: "SUFFIX",
// value: ".pdb",
// },
// ],
// },
// {
// hidden: false,
// name: "sdk_version",
// required: true,
// domType: "INPUT",
// classType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: [],
// choices: [],
// },
// ],
// edges: [],
// },
// {
// id: "批式算子ID2",
// title: "pdb2tpr",
// description: "docking",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "BATCH",
// parameters: [
// {
// hidden: true,
// name: "pdb_in",
// required: true,
// domType: "FILE",
// classType: "stringParameter",
// value: "f",
// description: "路径",
// validators: [],
// choices: [],
// },
// ],
// edges: [],
// },
// {
// id: "批式算子ID2",
// title: "pdb2tpr",
// description: "docking",
// position: {
// x: 0.0,
// y: 0.0,
// },
// type: "BATCH",
// parameters: [
// {
// hidden: true,
// name: "tpr_path",
// required: true,
// domType: "FILE",
// classType: "stringParameter",
// value: "f",
// description: "路径",
// validators: [],
// choices: [],
// },
// {
// hidden: true,
// name: "pdb_out",
// required: true,
// domType: "FILE",
// classType: "stringParameter",
// value: "f",
// description: "路径",
// validators: [],
// choices: [],
// },
// ],
// edges: [],
// },
// ],
// };
// {
// title: "slurm backend demo",
// version: "1.0.0",
// updateTime: "",
// description: "简单的批任务工作流,测试slurm backend和流程是否能用",
// language: "WDL",
// languageVersion: "draft-2",
// tags: ["Docking", "Gromax"],
// source: "BASE64_ENCODED_WDL/CWL",
// productId: "CADD",
// tasks: [
// {
// id: "批式算子ID1",
// title: "task_A",
// description: "这是task_A",
// position: {
// x: 0,
// y: 0,
// },
// type: "batch",
// parameters: [
// {
// hidden: false,
// name: "in",
// required: true,
// domType: "input",
// dataType: "stringParameter",
// value: "",
// description: "输入一段字符串",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// name: "out",
// required: true,
// domType: "File",
// dataType: "stringParameter",
// value: "/home/cloudam/task_a.out",
// description: "task_A的输出",
// validators: "",
// choices: [],
// },
// ],
// edges: [],
// },
// {
// id: "流式算子ID1",
// title: "task_B",
// description: "这是task_B",
// position: {
// x: 100,
// y: 50,
// },
// type: "batch",
// parameters: [
// {
// hidden: true,
// name: "in",
// required: true,
// domType: "pathSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "task_A.out",
// description: "这是task_B的输入",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// name: "sb",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是task_B的输入",
// validators: [],
// choices: [],
// },
// ],
// edges: [
// {
// id: "",
// source: "流式算子ID1",
// sourceHandle: "流式算子1出口A",
// target: "流式算子ID2",
// targetHandle: "流式算子2入口A",
// lable: "",
// },
// ],
// },
// {
// id: "流式算子ID1",
// title: "task_C",
// description: "这是task_C",
// position: {
// x: 100,
// y: 100,
// },
// type: "batch",
// parameters: [
// {
// hidden: true,
// name: "in",
// required: true,
// domType: "pathSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "task_A.out",
// description: "这是task_C的输入",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// name: "sc",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是task_C的输入",
// validators: [],
// choices: [],
// },
// ],
// edges: [
// {
// id: "",
// source: "流式算子ID1",
// sourceHandle: "流式算子1出口A",
// target: "流式算子ID2",
// targetHandle: "流式算子2入口A",
// lable: "",
// },
// ],
// },
// ],
// };
// {
// id: "模板ID",
// title: "Docking兼分子结合自由能计算",
// version: "1.0.0",
// updateTime: "2022-01-22",
// description:
// "这是一段模板描述这是一段模板描述这是一段模板描述这是一段模板描述这是一段模板描述这是一段模板描述",
// language: "WDL",
// languageVersion: "1.0",
// tags: ["Docking", "Gromax"],
// source: "BASE64_ENCODED_WDL/CWL",
// Apps: [
// {
// id: "批式算子ID1",
// title: "Docking(Vina)",
// description: "这是一段批式算子描述这是一段批式算子描述",
// position: {
// x: 0,
// y: 0,
// },
// type: "batch",
// parentNode: "",
// // "hasChildren":false 用于区分该批式算子内是否有流式算子,因为有与没有的流程图样式是不一样的,这个字段由前端自行判断添加
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "selected":false 前端自行生成,判断该算子是否被选中
// parameters: [],
// },
// edges: [],
// },
// {
// id: "流式算子ID1",
// title: "RecordFileReader",
// description:
// "这是一段RecordFileReader算子描述这是一段RecordFileReader算子描述",
// position: {
// x: 100,
// y: 50,
// },
// type: "flow",
// parentNode: "批式算子ID1",
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "completed":false 前端自行生成,判断该算子内参数是否全部填写完成
// parameters: [
// {
// hidden: false,
// id: "",
// name: "path",
// required: true,
// domType: "pathSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "raw",
// required: false,
// domType: "radio",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "booleanParameter",
// value: "false",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [
// {
// key: "true",
// value: "true",
// },
// {
// key: "false",
// value: "false",
// },
// ],
// },
// {
// hidden: false,
// id: "",
// name: "sep",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "contains_sep",
// required: false,
// domType: "radio",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "booleanParameter",
// value: "false",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [
// {
// key: "true",
// value: "true",
// },
// {
// key: "false",
// value: "false",
// },
// ],
// },
// {
// hidden: true,
// id: "",
// name: "encoding",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "UTF-8",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "chunk_size",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1000",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "compression",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "cpus",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "ntasks",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "partition",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "c-4-1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "parallelism",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "流式算子1出口A",
// name: "out",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordOutputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// ],
// },
// edges: [
// {
// id: "",
// source: "流式算子ID1",
// sourceHandle: "流式算子1出口A",
// target: "流式算子ID2",
// targetHandle: "流式算子2入口A",
// },
// ],
// },
// {
// id: "流式算子ID2",
// title: "standard",
// description: "这是一段standard算子描述这是一段standard算子描述",
// position: {
// x: 100,
// y: 100,
// },
// type: "flow",
// parentNode: "批式算子ID1",
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "completed":false 前端自行生成,判断该算子内参数是否全部填写完成
// parameters: [
// {
// hidden: true,
// id: "流式算子2入口A",
// name: "in",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordIntputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "cpus",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "ntasks",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "4",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "partition",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "c-4-1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "parallelism",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "6",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "流式算子2出口A",
// name: "out",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordOutputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// ],
// },
// edges: [
// {
// id: "",
// source: "流式算子ID2",
// sourceHandle: "流式算子2出口A",
// target: "流式算子ID3",
// targetHandle: "流式算子3入口A",
// },
// ],
// },
// {
// id: "流式算子ID3",
// title: "docking",
// description: "这是一段docking算子描述这是一段docking算子描述",
// position: {
// x: 100,
// y: 150,
// },
// type: "flow",
// parentNode: "批式算子ID1",
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "completed":false 前端自行生成,判断该算子内参数是否全部填写完成
// parameters: [
// {
// hidden: true,
// id: "流式算子3入口A",
// name: "in",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordInputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "receptor",
// required: true,
// domType: "fileSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "fileParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "core_num",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "centerX",
// required: true,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "centerY",
// required: true,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "centerZ",
// required: true,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "boxSizeX",
// required: true,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "boxSizeY",
// required: true,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "boxSizeZ",
// required: true,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "poses_num",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "9",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "verbosity",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "exhaustiveness",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "cpus",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "ntasks",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "4",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "partition",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "c-4-1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "parallelism",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "6",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "流式算子3出口A",
// name: "out",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordOutputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// ],
// },
// edges: [
// {
// id: "",
// source: "流式算子ID3",
// sourceHandle: "流式算子3出口A",
// target: "流式算子ID4",
// targetHandle: "流式算子4入口A",
// },
// {
// id: "",
// source: "流式算子ID3",
// sourceHandle: "流式算子3出口A",
// target: "流式算子ID5",
// targetHandle: "流式算子5入口A",
// },
// ],
// },
// {
// id: "流式算子ID4",
// title: "HitList",
// description: "这是一段HitList算子描述这是一段HitList算子描述",
// position: {
// x: 100,
// y: 200,
// },
// type: "flow",
// parentNode: "批式算子ID1",
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "completed":false 前端自行生成,判断该算子内参数是否全部填写完成
// parameters: [
// {
// hidden: true,
// id: "流式算子4入口A",
// name: "out",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordInputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "cpus",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "ntasks",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "partition",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "c-4-1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "parallelism",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "流式算子4出口A",
// name: "out",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordOutputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// ],
// },
// edges: [
// {
// id: "",
// source: "流式算子ID4",
// sourceHandle: "流式算子4出口A",
// target: "流式算子ID6",
// targetHandle: "流式算子6入口A",
// },
// ],
// },
// {
// id: "流式算子ID5",
// title: "DatasetWriter",
// description: "这是一段DatasetWriter算子描述这是一段DatasetWriter算子描述",
// position: {
// x: 200,
// y: 200,
// },
// type: "flow",
// parentNode: "批式算子ID1",
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "completed":false 前端自行生成,判断该算子内参数是否全部填写完成
// parameters: [
// {
// hidden: true,
// id: "流式算子5入口A",
// name: "in",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordInputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "path",
// required: true,
// domType: "pathSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "compression",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "snappy",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "chunk_size",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "100",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "cpus",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "ntasks",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "partition",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "c-4-1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "parallelism",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// ],
// },
// edges: [],
// },
// {
// id: "流式算子ID6",
// title: "RecordFileWriter",
// description:
// "这是一段RecordFileWriter算子描述这是一段RecordFileWriter算子描述",
// position: {
// x: 100,
// y: 250,
// },
// type: "flow",
// parentNode: "批式算子ID1",
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "completed":false 前端自行生成,判断该算子内参数是否全部填写完成
// parameters: [
// {
// hidden: true,
// id: "流式算子6入口A",
// name: "in",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "recordInputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "path",
// required: true,
// domType: "pathSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "many",
// required: false,
// domType: "radio",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "booleanParameter",
// value: "false",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [
// {
// key: "true",
// value: "true",
// },
// {
// key: "false",
// value: "false",
// },
// ],
// },
// {
// hidden: false,
// id: "",
// name: "compression",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "chunk_size",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1000",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "suffix",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: ".txt",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "cpus",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "ntasks",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "partition",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "c-4-1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "",
// name: "parallelism",
// required: false,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "numberParameter",
// value: "1",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "流式算子6出口A",
// name: "out",
// required: true,
// domType: "",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "fileOutputParameter",
// value: "xxxx.pdb",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// ],
// },
// edges: [
// {
// id: "",
// source: "流式算子ID6",
// sourceHandle: "流式算子6出口A",
// target: "批式算子ID2",
// targetHandle: "批式算子2入口A",
// label: "xxxx.pdb",
// },
// ],
// },
// {
// id: "批式算子ID2",
// title: "pdb2tpr",
// description: "这是一段批式算子描述这是一段批式算子描述",
// position: {
// x: 0,
// y: 350,
// },
// type: "batch",
// parentNode: "",
// // "hasChildren":false 用于区分该批式算子内是否有流式算子,因为有与没有的流程图样式是不一样的,这个字段由前端自行判断添加
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "selected":false 前端自行生成,判断该算子是否被选中
// // "completed":true 前端自行生成,判断该算子内参数是否全部填写完成,若该算子不需要填任何参数,则自动true
// parameters: [
// {
// hidden: true,
// id: "批式算子2入口A",
// name: "pdb_in",
// required: true,
// domType: "fileSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "fileInputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: true,
// id: "批式算子2出口A",
// name: "tpr_out",
// required: true,
// domType: "fileSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "fileOutputParameter",
// value: "xxxx.tpr",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// ],
// },
// edges: [
// {
// id: "",
// source: "批式算子ID2",
// sourceHandle: "批式算子2出口A",
// target: "批式算子ID3",
// targetHandle: "批式算子3入口A",
// label: "xxxx.ptr",
// },
// ],
// },
// {
// id: "批式算子ID3",
// title: "gromax run",
// description: "这是一段批式算子描述这是一段批式算子描述",
// position: {
// x: 0,
// y: 450,
// },
// type: "batch",
// parentNode: "",
// // "hasChildren":false 用于区分该批式算子内是否有流式算子,因为有与没有的流程图样式是不一样的,这个字段由前端自行判断添加
// data: {
// status: "wait", // 可选值有 success、error、run、wait
// // "selected":false 前端自行生成,判断该算子是否被选中
// // "completed":true 前端自行生成,判断该算子内参数是否全部填写完成,若该算子不需要填任何参数,则自动true
// parameters: [
// {
// hidden: true,
// id: "批式算子3入口A",
// name: "pdb_out",
// required: true,
// domType: "fileSelect",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "fileInputParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// {
// hidden: false,
// id: "",
// name: "tpr_name",
// required: true,
// domType: "input",
// // pathSelect-路径选择器 datasetSelect-数据集选择器 fileSelect-文件选择器 input-输入框 select-单选下拉框 multipleSelect-多选下拉框 radio-单选组 checkbox-多选组
// dataType: "stringParameter",
// value: "",
// description: "这是一段参数描述这是一段参数描述这是一段参数描述",
// validators: "",
// choices: [],
// },
// ],
// },
// edges: [],
// },
// ],
// };
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
}
}
\ No newline at end of file
......@@ -2,24 +2,25 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @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
* @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 { useStores } from "@/store";
import styles from "./index.module.css";
import { useNavigate } from "react-router-dom";
import { Box, Typography } from "@mui/material";
import OutlinedInput from "@mui/material/OutlinedInput";
import SearchIcon from "@mui/icons-material/Search";
import useMyRequest from "@/hooks/useMyRequest";
import LinearProgress, { linearProgressClasses } from '@mui/material/LinearProgress';
import { TablePagination } from '@mui/material';
import ActionsComponent from "../../../../components/Material.Ui/Table/ActionsComponent"
import TextField from '@mui/material/TextField';
import MenuItem from '@mui/material/MenuItem';
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 jobCost from '../../../../assets/project/jobCost.svg'
import jobSue from '../../../../assets/project/jobSue.svg'
......@@ -35,6 +36,9 @@ import {
cancelWorkflowJob
} from "@/api/workbench_api";
import styles from "./index.module.css";
const currencies = [
{
value: 'ALL',
......@@ -78,6 +82,7 @@ const ProjectMembers = () => {
setCount(result.data.totalElements)
},
});
const navigate = useNavigate()
// 删除作业
const { run: delWorkflowJob } = useMyRequest(deleteWorkflowJob, {
......@@ -223,6 +228,16 @@ const ProjectMembers = () => {
}
}
/** 点击每一行 */
const rowClick = useCallback(
(id: string) => {
navigate(`/product/cadd/projectJobDetail`, {
state: { taskId: id },
});
},
[navigate],
);
return (
<Box className={styles.headerBox}>
......@@ -247,12 +262,12 @@ const ProjectMembers = () => {
size="small"
sx={{
width: 180, height: 32,
['& .MuiOutlinedInput-root']: {
'& .MuiOutlinedInput-root': {
height: '32px',
color: "#1E2633",
fontSize: '14px'
},
['& .MuiInputLabel-root']: {
'& .MuiInputLabel-root': {
color: "#8A9099",
fontSize: '14px'
},
......@@ -282,7 +297,7 @@ const ProjectMembers = () => {
{
jobList.length > 0 && jobList.map((item: any, key) => {
return (
<Box className={styles.tabBox}>
<Box className={styles.tabBox} onClick={()=>rowClick(item.id)}>
<Box className={styles.tabBoxInfo}>
<div className={styles.tabBoxTitle}>{item.name}</div>
<Box className={styles.tabBoxDescInfo}>
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-17 14:48:57
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-24 16:41:40
* @FilePath: /bkunyun/src/views/Project/ProjectWorkbench/workbenchTemplate/components/templateBox.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import styles from "../index.module.css";
import { Box, Typography } from "@mui/material";
import Button from "@/components/mui/Button";
import usePass from "@/hooks/usePass";
import { useNavigate } from "react-router-dom";
const TemplateBox = (props: any) => {
const info = props.data
const info = props.data;
const isPass = usePass();
const navigate = useNavigate();
const addTemplateBlock = useCallback(
(id: string) => {
navigate(`/product/cadd/projectSubmitWork`, {
state: { id },
});
},
[navigate]
);
return (
<Box className={styles.templateBlock} >
<Box className={styles.templateBlock}>
<Box>
<Typography sx={{ fontSize: '14px', fontWeight: '600', color: '#1E2633', marginBottom: "4px", overflow: 'hidden', textOverflow: 'ellipsis' }}>{info.title}</Typography>
<Box sx={{ display: 'flex', marginBottom: "8px" }} >
<Typography sx={{ fontSize: '12px', fontWeight: '400', color: '#1370FF', marginRight: "24px" }}>版本:{info.version}</Typography>
<Typography sx={{ fontSize: '12px', fontWeight: '400', color: '#1370FF' }}>更新时间:{info.updateTime}</Typography>
<Typography
sx={{
fontSize: "14px",
fontWeight: "600",
color: "#1E2633",
marginBottom: "4px",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
{info.title}
</Typography>
<Box sx={{ display: "flex", marginBottom: "8px" }}>
<Typography
sx={{
fontSize: "12px",
fontWeight: "400",
color: "#1370FF",
marginRight: "24px",
}}
>
版本:{info.version}
</Typography>
<Typography
sx={{ fontSize: "12px", fontWeight: "400", color: "#1370FF" }}
>
更新时间:{info.updateTime}
</Typography>
</Box>
<Typography className={styles.templateDescText}>
{info.description}
</Typography>
</Box>
<Typography className={styles.templateDescText} >{info.description}</Typography>
<Box
sx={{
display: "flex",
justifyContent: "end",
}}
>
{isPass("PROJECT_WORKBENCH_FLOES_USE", "MANAGER") && (
<Button
size={"small"}
text={"删除模版"}
click={() => {
props.startDialog(info.id);
}}
style={{ backgroundColor: "#F0F2F5", color: "#565C66" }}
/>
)}
{isPass("PROJECT_WORKBENCH_FLOES_USE", "USER") && (
<Button
size={"small"}
text={"使用模版"}
click={() => addTemplateBlock(info.id)}
style={{ marginLeft: "12px" }}
/>
)}
</Box>
<Box sx={{
display: 'flex', justifyContent: 'end'
}} >
{
isPass("PROJECT_WORKBENCH_FLOES_USE", 'MANAGER') &&
<Button size={"small"} text={'删除模版'} click={() => { props.startDialog(info.id) }} style={{ backgroundColor: "#F0F2F5", color: "#565C66" }} />
}
{
isPass("PROJECT_WORKBENCH_FLOES_USE", 'USER') &&
<Button size={"small"} text={'使用模版'} click={() => { }} style={{ marginLeft: "12px" }} />
}
</Box>
</Box >
);
};
......
.batchNode {
background-color: #fff;
border-radius: 4px;
/* padding: 12px 20px; */
border: 1px solid #e6e8eb;
border-left: 4px solid #e6e8eb;
display: flex;
align-items: center;
}
.selectBatchNode {
border-left: 4px solid #1370ff;
}
.batchRotate {
transform: translateX(-50%) rotate(-90deg);
}
.flowNode {
background-color: #f5f6f7;
border-radius: 2px;
padding: 6px 12px;
}
.successDot {
display: inline-block;
line-height: 22px;
vertical-align: middle;
width: 8px;
height: 8px;
background-color: #0dd09b;
border-radius: 8px;
margin-left: 8px;
}
.selectedBatchBox {
border: 1px solid #1370ff;
border-left: 4px solid #1370ff;
}
import ReactFlow, {
Controls,
Background,
useNodesState,
useEdgesState,
Handle,
Position,
ReactFlowProps,
Node,
} from "react-flow-renderer";
import { useCallback, useEffect, useMemo, useState } from "react";
import classNames from "classnames";
import jobFail from "@/assets/project/jobFail.svg";
import jobRun from "@/assets/project/jobRun.svg";
import jobSue from "@/assets/project/jobSue.svg";
import { IEdge, IExecutionStatus, ITask } from "../../ProjectSubmitWork/interface";
import { IBatchNode, ILine } from "./interface";
import styles from "./index.module.css";
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-22 10:15:22
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-22 11:10:35
* @FilePath: /bkunyun/src/views/Project/components/Flow/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
interface IProps extends ReactFlowProps {
tasks?: ITask[];
/** 点击batch事件 */
onBatchClick?: (val: string) => void;
}
/** 获取imgUrl */
const getImgUrl = (type: IExecutionStatus) => {
if(type === 'Done'){
return jobSue
}
if(type === 'Failed'){
return jobFail
}
if(type === 'Running'){
return jobRun
}
return undefined
}
/** 自定义batch节点 */
const BatchNode = (props: IBatchNode) => {
const { data } = props;
const { dotStatus, style, isFlowNode, label, selectedStatus } = data;
return (
<div
className={classNames({
[styles.batchNode]: true,
[styles.selectedBatchBox]: selectedStatus,
[styles.selectBatchNode]: selectedStatus,
})}
style={style}
>
{dotStatus?.isInput ? (
<Handle
style={{ background: "#fff ", border: "1px solid #D1D6DE", left: 20 }}
type="target"
position={Position.Top}
/>
) : null}
<div
className={classNames({
[styles.batchRotate]: isFlowNode,
})}
>
{label || ""}
</div>
{dotStatus?.isOutput ? (
<Handle
style={{ background: "#fff ", border: "1px solid #D1D6DE", left: 20 }}
type="source"
position={Position.Bottom}
/>
) : null}
</div>
);
};
/** 自定义flow节点 */
const FlowNode = (props: any) => {
const { data } = props;
return (
<div
className={classNames({
[styles.flowNode]: true,
})}
>
{data?.dotStatus?.isInput ? (
<Handle
style={{ background: "#C2C6CC ", left: 12 }}
type="target"
position={Position.Top}
/>
) : null}
<div style={{ display: "flex", alignItems: "center" }}>
{data?.label || ""}
{data.isCheck && <span className={styles.successDot}></span>}
{getImgUrl(data.executionStatus) && <img style={{ marginLeft: "6px" }} src={getImgUrl(data.executionStatus)} alt="" />}
</div>
{data?.dotStatus?.isOutput ? (
<Handle
style={{ background: "#C2C6CC ", left: 12 }}
type="source"
position={Position.Bottom}
id="a"
/>
) : null}
</div>
);
};
const Flow = (props: IProps) => {
const { tasks, onBatchClick } = props;
console.log(tasks,'tasks')
const [selectedNodeId, setSelectedNodeId] = useState<string>("");
/** 自定义的节点类型 */
const nodeTypes = useMemo(() => {
return { batchNode: BatchNode, flowNode: FlowNode };
}, []);
/** 获取是否有输入节点或者是否有输出节点 */
const nodesInputAndOutputStatus = useCallback(
(id: string) => {
/** 所有的连线 */
const lineArr: IEdge[] = [];
tasks?.length &&
tasks.forEach((item) => {
lineArr.push(...item.edges);
});
/** 所有的输入节点ID */
const isInput = lineArr?.some((item) => item.target === id);
/** 所有的输出节点ID */
const isOutput = lineArr?.some((item) => item.source === id);
return {
isInput,
isOutput,
};
},
[tasks]
);
/** 获取是否有流节点 */
const isFlowNode = useCallback(
(id: string) => {
return (
tasks?.length &&
tasks?.some((item) => {
return item.parentNode === id;
})
);
},
[tasks]
);
/** 通过子flow节点计算batch节点的样式 */
const getBatchStyle = useCallback(
(value: ITask) => {
const positionXArr: number[] = [];
const positionYArr: number[] = [];
tasks?.length &&
tasks?.forEach((item) => {
if (item.parentNode === value.id) {
positionXArr.push(item.position?.x || 0);
positionYArr.push(item.position?.y || 0);
}
});
positionXArr.sort((a, b) => {
return a - b;
});
positionYArr.sort((a, b) => {
return a - b;
});
let width = 176,
height = 22;
if (positionXArr?.length) {
const val = positionXArr[positionXArr.length - 1] + 150;
width = val > 176 ? val : width;
}
if (positionYArr?.length) {
const val = positionYArr[positionYArr.length - 1];
height = val > 22 ? val : height;
}
return {
width,
height,
};
},
[tasks]
);
/** 生成初始化node节点 */
const initialNodes = useMemo(() => {
const val: any = [];
tasks?.length &&
tasks.forEach((item) => {
val.push({
id: item.id,
type: item.type === "BATCH" ? "batchNode" : "flowNode",
data: {
label: item.title || "",
...(item.type === "BATCH"
? {
/** 是否有流节点 */
isFlowNode: isFlowNode(item.id),
/** 选中状态 */
selectedStatus: selectedNodeId === item.id,
}
: { isCheck: item.isCheck }),
executionStatus: item.executionStatus,
/** 输入输出圆点状态 */
dotStatus: nodesInputAndOutputStatus(item.id),
/** 样式 */
style: {
...getBatchStyle(item),
padding: isFlowNode(item.id) ? "20px" : "12px 20px",
},
},
position: { x: Number(item.position.x), y: Number(item.position.y) },
...(item.type === "BATCH" ? { style: { zIndex: -1 } } : {}),
...(item.parentNode ? { parentNode: item.parentNode } : {}),
...(item.type === "BATCH" ? { extent: "parent" } : {}),
});
});
return val;
}, [
tasks,
isFlowNode,
selectedNodeId,
nodesInputAndOutputStatus,
getBatchStyle,
]);
/** 生成初始化的连线节点 */
const initialEdges = useMemo(() => {
const val: ILine[] = [];
tasks?.length &&
tasks.forEach((item) => {
item.edges.forEach((every) => {
const newLine = {
...every,
batchId: item.parentNode ? item.parentNode : item.id,
};
val.push(newLine);
}, []);
});
return val.map((item: ILine) => {
return {
id: item.id,
source: item.source,
target: item.target,
type: "smoothstep",
...(item?.batchId === selectedNodeId
? { style: { stroke: "#1370FF" }, animated: true }
: {}),
labelStyle: { fill: "#8A9099" },
labelBgStyle: { fill: "#F7F8FA " },
label: item.label ? `(${item.label})` : "",
};
});
}, [selectedNodeId, tasks]);
/** flowNode点击事件 */
const onNodeClick = (e: any, node: Node) => {
tasks?.forEach((item) => {
if (item.id === node.id) {
if (item.parentNode) {
setSelectedNodeId(item.parentNode);
onBatchClick && onBatchClick(item.parentNode);
} else {
setSelectedNodeId(node.id);
onBatchClick && onBatchClick(node.id || "");
}
}
});
};
const handlePaneClick = () => {
setSelectedNodeId('');
onBatchClick && onBatchClick('');
}
/** node节点 */
const [nodes, setNodes] = useNodesState(initialNodes);
/** 连线数组 */
const [edges, setEdges] = useEdgesState(initialEdges);
useEffect(() => {
setEdges(initialEdges);
}, [initialEdges, setEdges]);
useEffect(() => {
setNodes(initialNodes);
}, [initialNodes, setNodes]);
return (
<ReactFlow
nodes={nodes}
edges={edges}
fitView
proOptions={{ hideAttribution: true, account: "" }}
nodeTypes={nodeTypes}
onPaneClick={handlePaneClick}
onNodeClick={onNodeClick}
{...props}
>
<Controls />
<Background color="#aaa" gap={16} />
</ReactFlow>
);
};
export default Flow;
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-23 11:00:29
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-27 15:32:29
* @FilePath: /bkunyun/src/views/Project/components/Flow/interface.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { CSSProperties } from "react";
/** 线的参数 */
export interface ILine {
id: string,
label: string,
batchId?: string,
source: string,
target: string,
}
export interface IDotStatus {
/** 是否为输入 */
isInput: boolean;
/** 是否为输出 */
isOutput: boolean
}
export interface IBatchNodeData {
/** label 文案 */
label: string;
/** 是否存在flow节点 */
isFlowNode: boolean;
/** 连线圆点状态 */
dotStatus: IDotStatus;
/** 样式 */
style?: CSSProperties;
/** 是否选中状态 */
selectedStatus?: boolean;
}
export interface IBatchNode {
data: IBatchNodeData
}
\ No newline at end of file
......@@ -31,7 +31,7 @@
"resolved" "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz"
"version" "7.17.10"
"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.16.0", "@babel/core@^7.4.0-0", "@babel/core@^7.7.2", "@babel/core@^7.8.0", "@babel/core@>=7.11.0":
"@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0":
"integrity" "sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA=="
"resolved" "https://registry.npmjs.org/@babel/core/-/core-7.17.10.tgz"
"version" "7.17.10"
......@@ -488,7 +488,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.3"
"@babel/plugin-syntax-flow@^7.14.5", "@babel/plugin-syntax-flow@^7.16.7":
"@babel/plugin-syntax-flow@^7.16.7":
"integrity" "sha512-UDo3YGQO0jH6ytzVwgSLv9i/CzMcUjbKenL67dTrAZPPv6GFAtDhe6jqnvmoKzC/7htNTohhos+onPtDMqJwaQ=="
"resolved" "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.7.tgz"
"version" "7.16.7"
......@@ -793,7 +793,7 @@
dependencies:
"@babel/plugin-transform-react-jsx" "^7.16.7"
"@babel/plugin-transform-react-jsx@^7.14.9", "@babel/plugin-transform-react-jsx@^7.16.7":
"@babel/plugin-transform-react-jsx@^7.16.7":
"integrity" "sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ=="
"resolved" "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.3.tgz"
"version" "7.17.3"
......@@ -1025,6 +1025,13 @@
dependencies:
"regenerator-runtime" "^0.13.4"
"@babel/runtime@^7.18.0":
"integrity" "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug=="
"resolved" "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.18.3.tgz"
"version" "7.18.3"
dependencies:
"regenerator-runtime" "^0.13.4"
"@babel/template@^7.16.7", "@babel/template@^7.3.3":
"integrity" "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w=="
"resolved" "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz"
......@@ -1190,7 +1197,7 @@
"source-map" "^0.5.7"
"stylis" "4.0.13"
"@emotion/cache@^11.7.1":
"@emotion/cache@*", "@emotion/cache@^11.7.1":
"integrity" "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A=="
"resolved" "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz"
"version" "11.7.1"
......@@ -1201,6 +1208,17 @@
"@emotion/weak-memoize" "^0.2.5"
"stylis" "4.0.13"
"@emotion/cache@^11.9.3":
"integrity" "sha512-0dgkI/JKlCXa+lEXviaMtGBL0ynpx4osh7rjOXE71q9bIF8G+XhJgvi+wDu0B0IdCVx37BffiwXlN9I3UuzFvg=="
"resolved" "https://registry.npmmirror.com/@emotion/cache/-/cache-11.9.3.tgz"
"version" "11.9.3"
dependencies:
"@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/hash@^0.8.0":
"integrity" "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
"resolved" "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz"
......@@ -1218,20 +1236,20 @@
"resolved" "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz"
"version" "0.7.5"
"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0", "@emotion/react@^11.9.0":
"integrity" "sha512-lBVSF5d0ceKtfKCDQJveNAtkC7ayxpVlgOohLgXqRwqWr9bOf4TZAFFyIcNngnV6xK6X4x2ZeXq7vliHkoVkxQ=="
"resolved" "https://registry.npmjs.org/@emotion/react/-/react-11.9.0.tgz"
"version" "11.9.0"
"@emotion/react@^11.9.3":
"integrity" "sha512-g9Q1GcTOlzOEjqwuLF/Zd9LC+4FljjPjDfxSM7KmEakm+hsHXk+bYZ2q+/hTJzr0OUNkujo72pXLQvXj6H+GJQ=="
"resolved" "https://registry.npmmirror.com/@emotion/react/-/react-11.9.3.tgz"
"version" "11.9.3"
dependencies:
"@babel/runtime" "^7.13.10"
"@emotion/babel-plugin" "^11.7.1"
"@emotion/cache" "^11.7.1"
"@emotion/serialize" "^1.0.3"
"@emotion/cache" "^11.9.3"
"@emotion/serialize" "^1.0.4"
"@emotion/utils" "^1.1.0"
"@emotion/weak-memoize" "^0.2.5"
"hoist-non-react-statics" "^3.3.1"
"@emotion/serialize@^1.0.2", "@emotion/serialize@^1.0.3":
"@emotion/serialize@*", "@emotion/serialize@^1.0.2":
"integrity" "sha512-2mSSvgLfyV3q+iVh3YWgNlUc2a9ZlDU7DjuP5MjK3AXRR0dYigCrP99aeFtaB2L/hjfEZdSThn5dsZ0ufqbvsA=="
"resolved" "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.3.tgz"
"version" "1.0.3"
......@@ -1242,12 +1260,28 @@
"@emotion/utils" "^1.0.0"
"csstype" "^3.0.2"
"@emotion/serialize@^1.0.4":
"integrity" "sha512-1JHamSpH8PIfFwAMryO2bNka+y8+KA5yga5Ocf2d7ZEiJjb7xlLW7aknBGZqJLajuLOvJ+72vN+IBSwPlXD1Pg=="
"resolved" "https://registry.npmmirror.com/@emotion/serialize/-/serialize-1.0.4.tgz"
"version" "1.0.4"
dependencies:
"@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@^1.1.0":
"integrity" "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g=="
"resolved" "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz"
"version" "1.1.0"
"@emotion/styled@^11.3.0", "@emotion/styled@^11.8.1":
"@emotion/sheet@^1.1.1":
"integrity" "sha512-J3YPccVRMiTZxYAY0IOq3kd+hUP8idY8Kz6B/Cyo+JuXq52Ek+zbPbSQUrVQp95aJ+lsAW7DPL1P2Z+U1jGkKA=="
"resolved" "https://registry.npmmirror.com/@emotion/sheet/-/sheet-1.1.1.tgz"
"version" "1.1.1"
"@emotion/styled@^11.8.1":
"integrity" "sha512-OghEVAYBZMpEquHZwuelXcRjRJQOVayvbmNR0zr174NHdmMgrNkLC6TljKC5h9lZLkN5WGrdUcrKlOJ4phhoTQ=="
"resolved" "https://registry.npmjs.org/@emotion/styled/-/styled-11.8.1.tgz"
"version" "11.8.1"
......@@ -1263,7 +1297,7 @@
"resolved" "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz"
"version" "0.7.5"
"@emotion/utils@^1.0.0", "@emotion/utils@^1.1.0":
"@emotion/utils@*", "@emotion/utils@^1.0.0", "@emotion/utils@^1.1.0":
"integrity" "sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ=="
"resolved" "https://registry.npmjs.org/@emotion/utils/-/utils-1.1.0.tgz"
"version" "1.1.0"
......@@ -1599,7 +1633,7 @@
dependencies:
"@babel/runtime" "^7.17.2"
"@mui/lab@^5.0.0-alpha.83":
"@mui/lab@^5.0.0-alpha.84":
"integrity" "sha512-HLYD6E3PAlzKMGZkkpiPI7trHP3WYDvrjQstEsFwdaGy9AMWPmyTxhwUyfB4VVHOx3zcj4p/a36kECDtEOAJ+g=="
"resolved" "https://registry.npmmirror.com/@mui/lab/-/lab-5.0.0-alpha.84.tgz"
"version" "5.0.0-alpha.84"
......@@ -1615,7 +1649,7 @@
"react-transition-group" "^4.4.2"
"rifm" "^0.12.1"
"@mui/material@^5.0.0", "@mui/material@^5.2.3", "@mui/material@^5.6.4":
"@mui/material@^5.6.4":
"integrity" "sha512-7TD+u/SExZK2a55w6reX56oPk37gKr/M/XGt156X+m0d9LhzOsW864nkErIX/H8oSkX/6kCimxu1FDsO+gjiVw=="
"resolved" "https://registry.npmjs.org/@mui/material/-/material-5.6.4.tgz"
"version" "5.6.4"
......@@ -1674,7 +1708,21 @@
"jss-plugin-vendor-prefixer" "^10.8.2"
"prop-types" "^15.8.1"
"@mui/system@^5.2.3", "@mui/system@^5.6.4", "@mui/system@^5.8.2":
"@mui/system@^5.6.4":
"integrity" "sha512-N74gDNKM+MnWvKTMmCPvCVLH4f0ZzakP1bcMDaPctrHwcyxNcEmtTGNpIiVk0Iu7vtThZAFL3DjHpINPGF7+cg=="
"resolved" "https://registry.npmmirror.com/@mui/system/-/system-5.8.2.tgz"
"version" "5.8.2"
dependencies:
"@babel/runtime" "^7.17.2"
"@mui/private-theming" "^5.8.0"
"@mui/styled-engine" "^5.8.0"
"@mui/types" "^7.1.3"
"@mui/utils" "^5.8.0"
"clsx" "^1.1.1"
"csstype" "^3.1.0"
"prop-types" "^15.8.1"
"@mui/system@^5.8.2":
"integrity" "sha512-N74gDNKM+MnWvKTMmCPvCVLH4f0ZzakP1bcMDaPctrHwcyxNcEmtTGNpIiVk0Iu7vtThZAFL3DjHpINPGF7+cg=="
"resolved" "https://registry.npmmirror.com/@mui/system/-/system-5.8.2.tgz"
"version" "5.8.2"
......@@ -1934,7 +1982,7 @@
"@svgr/plugin-svgo" "^5.5.0"
"loader-utils" "^2.0.0"
"@testing-library/dom@^8.5.0", "@testing-library/dom@>=7.21.4":
"@testing-library/dom@^8.5.0":
"integrity" "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ=="
"resolved" "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz"
"version" "8.13.0"
......@@ -1994,7 +2042,7 @@
"resolved" "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz"
"version" "4.2.2"
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.9":
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14":
"integrity" "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw=="
"resolved" "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz"
"version" "7.1.19"
......@@ -2057,6 +2105,11 @@
dependencies:
"@types/node" "*"
"@types/crypto-js@^4.1.1":
"integrity" "sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA=="
"resolved" "https://registry.npmmirror.com/@types/crypto-js/-/crypto-js-4.1.1.tgz"
"version" "4.1.1"
"@types/eslint-scope@^3.7.3":
"integrity" "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g=="
"resolved" "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz"
......@@ -2229,7 +2282,7 @@
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^17.0.0", "@types/react@^17.0.0 || ^18.0.0", "@types/react@^18.0.9":
"@types/react@*", "@types/react@^18.0.9":
"integrity" "sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw=="
"resolved" "https://registry.npmjs.org/@types/react/-/react-18.0.9.tgz"
"version" "18.0.9"
......@@ -2320,7 +2373,7 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@^4.0.0 || ^5.0.0", "@typescript-eslint/eslint-plugin@^5.5.0":
"@typescript-eslint/eslint-plugin@^5.5.0":
"integrity" "sha512-YCiy5PUzpAeOPGQ7VSGDEY2NeYUV1B0swde2e0HzokRsHBYjSdF6DZ51OuRZxVPHx0032lXGLvOMls91D8FXlg=="
"resolved" "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.22.0.tgz"
"version" "5.22.0"
......@@ -2342,7 +2395,7 @@
dependencies:
"@typescript-eslint/utils" "5.22.0"
"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.5.0":
"@typescript-eslint/parser@^5.5.0":
"integrity" "sha512-piwC4krUpRDqPaPbFaycN70KCP87+PC5WZmrWs+DlVOxxmF+zI6b6hETv7Quy4s9wbkV16ikMeZgXsvzwI3icQ=="
"resolved" "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.22.0.tgz"
"version" "5.22.0"
......@@ -2583,11 +2636,6 @@
"resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz"
"version" "7.2.0"
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", "acorn@^8", "acorn@^8.2.4", "acorn@^8.4.1", "acorn@^8.5.0", "acorn@^8.7.1":
"integrity" "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A=="
"resolved" "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz"
"version" "8.7.1"
"acorn@^7.0.0":
"integrity" "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
"resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
......@@ -2598,6 +2646,11 @@
"resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
"version" "7.4.1"
"acorn@^8.2.4", "acorn@^8.4.1", "acorn@^8.5.0", "acorn@^8.7.1":
"integrity" "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A=="
"resolved" "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz"
"version" "8.7.1"
"address@^1.0.1", "address@^1.1.2":
"integrity" "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig=="
"resolved" "https://registry.npmjs.org/address/-/address-1.2.0.tgz"
......@@ -2656,7 +2709,7 @@
dependencies:
"fast-deep-equal" "^3.1.3"
"ajv@^6.10.0", "ajv@^6.12.2", "ajv@^6.12.4", "ajv@^6.12.5", "ajv@^6.9.1":
"ajv@^6.10.0", "ajv@^6.12.2", "ajv@^6.12.4", "ajv@^6.12.5":
"integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="
"resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
"version" "6.12.6"
......@@ -2676,7 +2729,7 @@
"require-from-string" "^2.0.2"
"uri-js" "^4.2.2"
"ajv@^8.6.0", "ajv@>=8":
"ajv@^8.6.0":
"integrity" "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg=="
"resolved" "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz"
"version" "8.11.0"
......@@ -2686,7 +2739,7 @@
"require-from-string" "^2.0.2"
"uri-js" "^4.2.2"
"ajv@^8.8.0", "ajv@^8.8.2":
"ajv@^8.8.0":
"integrity" "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg=="
"resolved" "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz"
"version" "8.11.0"
......@@ -2858,6 +2911,11 @@
"resolved" "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz"
"version" "2.1.2"
"attr-accept@^2.2.2":
"integrity" "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg=="
"resolved" "https://registry.npmmirror.com/attr-accept/-/attr-accept-2.2.2.tgz"
"version" "2.2.2"
"autoprefixer@^10.4.6":
"integrity" "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA=="
"resolved" "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz"
......@@ -3135,7 +3193,7 @@
"resolved" "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz"
"version" "1.0.0"
"browserslist@^4.0.0", "browserslist@^4.14.5", "browserslist@^4.16.6", "browserslist@^4.18.1", "browserslist@^4.20.2", "browserslist@^4.20.3", "browserslist@>= 4", "browserslist@>=4":
"browserslist@^4.0.0", "browserslist@^4.14.5", "browserslist@^4.16.6", "browserslist@^4.18.1", "browserslist@^4.20.2", "browserslist@^4.20.3":
"integrity" "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg=="
"resolved" "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz"
"version" "4.20.3"
......@@ -3153,6 +3211,11 @@
dependencies:
"node-int64" "^0.4.0"
"buffer-from@^0.1.1":
"integrity" "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg=="
"resolved" "https://registry.npmmirror.com/buffer-from/-/buffer-from-0.1.2.tgz"
"version" "0.1.2"
"buffer-from@^1.0.0":
"integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
"resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
......@@ -3328,6 +3391,11 @@
"resolved" "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz"
"version" "1.2.2"
"classcat@^5.0.3":
"integrity" "sha512-6dK2ke4VEJZOFx2ZfdDAl5OhEL8lvkl6EHF92IfRePfHxQTqir5NlcNVUv+2idjDqCX2NDc8m8YSAI5NI975ZQ=="
"resolved" "https://registry.npmmirror.com/classcat/-/classcat-5.0.3.tgz"
"version" "5.0.3"
"classnames@^2.3.1":
"integrity" "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
"resolved" "https://registry.npmmirror.com/classnames/-/classnames-2.3.1.tgz"
......@@ -3412,6 +3480,14 @@
"resolved" "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz"
"version" "2.0.16"
"combine-errors@^3.0.3":
"integrity" "sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q=="
"resolved" "https://registry.npmmirror.com/combine-errors/-/combine-errors-3.0.3.tgz"
"version" "3.0.3"
dependencies:
"custom-error-instance" "2.1.1"
"lodash.uniqby" "4.5.0"
"combined-stream@^1.0.8":
"integrity" "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="
"resolved" "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
......@@ -3567,6 +3643,11 @@
"shebang-command" "^2.0.0"
"which" "^2.0.1"
"crypto-js@^4.1.1":
"integrity" "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
"resolved" "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz"
"version" "4.1.1"
"crypto-random-string@^2.0.0":
"integrity" "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA=="
"resolved" "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz"
......@@ -3792,6 +3873,73 @@
"resolved" "https://registry.npmmirror.com/csstype/-/csstype-3.1.0.tgz"
"version" "3.1.0"
"custom-error-instance@2.1.1":
"integrity" "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg=="
"resolved" "https://registry.npmmirror.com/custom-error-instance/-/custom-error-instance-2.1.1.tgz"
"version" "2.1.1"
"d3-color@1 - 3":
"integrity" "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="
"resolved" "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz"
"version" "3.1.0"
"d3-dispatch@1 - 3":
"integrity" "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="
"resolved" "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz"
"version" "3.0.1"
"d3-drag@^3.0.0", "d3-drag@2 - 3":
"integrity" "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg=="
"resolved" "https://registry.npmmirror.com/d3-drag/-/d3-drag-3.0.0.tgz"
"version" "3.0.0"
dependencies:
"d3-dispatch" "1 - 3"
"d3-selection" "3"
"d3-ease@1 - 3":
"integrity" "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="
"resolved" "https://registry.npmmirror.com/d3-ease/-/d3-ease-3.0.1.tgz"
"version" "3.0.1"
"d3-interpolate@1 - 3":
"integrity" "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="
"resolved" "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz"
"version" "3.0.1"
dependencies:
"d3-color" "1 - 3"
"d3-selection@^3.0.0", "d3-selection@2 - 3", "d3-selection@3":
"integrity" "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="
"resolved" "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz"
"version" "3.0.0"
"d3-timer@1 - 3":
"integrity" "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="
"resolved" "https://registry.npmmirror.com/d3-timer/-/d3-timer-3.0.1.tgz"
"version" "3.0.1"
"d3-transition@2 - 3":
"integrity" "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w=="
"resolved" "https://registry.npmmirror.com/d3-transition/-/d3-transition-3.0.1.tgz"
"version" "3.0.1"
dependencies:
"d3-color" "1 - 3"
"d3-dispatch" "1 - 3"
"d3-ease" "1 - 3"
"d3-interpolate" "1 - 3"
"d3-timer" "1 - 3"
"d3-zoom@^3.0.0":
"integrity" "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="
"resolved" "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz"
"version" "3.0.0"
dependencies:
"d3-dispatch" "1 - 3"
"d3-drag" "2 - 3"
"d3-interpolate" "1 - 3"
"d3-selection" "2 - 3"
"d3-transition" "2 - 3"
"damerau-levenshtein@^1.0.7":
"integrity" "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="
"resolved" "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz"
......@@ -3806,7 +3954,7 @@
"whatwg-mimetype" "^2.3.0"
"whatwg-url" "^8.0.0"
"dayjs@^1.10.7", "dayjs@^1.8.17", "dayjs@^1.9.1":
"dayjs@^1.9.1":
"integrity" "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw=="
"resolved" "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz"
"version" "1.11.2"
......@@ -4430,7 +4578,7 @@
"normalize-path" "^3.0.0"
"schema-utils" "^3.1.1"
"eslint@*", "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^7.0.0 || ^8.0.0", "eslint@^7.5.0 || ^8.0.0", "eslint@^8.0.0", "eslint@^8.1.0", "eslint@^8.3.0", "eslint@>= 6", "eslint@>=5":
"eslint@^8.3.0":
"integrity" "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA=="
"resolved" "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz"
"version" "8.15.0"
......@@ -4663,6 +4811,13 @@
"loader-utils" "^2.0.0"
"schema-utils" "^3.0.0"
"file-selector@^0.6.0":
"integrity" "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw=="
"resolved" "https://registry.npmmirror.com/file-selector/-/file-selector-0.6.0.tgz"
"version" "0.6.0"
dependencies:
"tslib" "^2.4.0"
"filelist@^1.0.1":
"integrity" "sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q=="
"resolved" "https://registry.npmjs.org/filelist/-/filelist-1.0.3.tgz"
......@@ -5275,7 +5430,7 @@
"resolved" "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz"
"version" "5.2.0"
"immer@^9.0.12", "immer@^9.0.7", "immer@>=2.0.0":
"immer@^9.0.12", "immer@^9.0.7":
"integrity" "sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA=="
"resolved" "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz"
"version" "9.0.12"
......@@ -5856,7 +6011,7 @@
"jest-regex-util" "^27.5.1"
"jest-snapshot" "^27.5.1"
"jest-resolve@*", "jest-resolve@^27.4.2", "jest-resolve@^27.5.1":
"jest-resolve@^27.4.2", "jest-resolve@^27.5.1":
"integrity" "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw=="
"resolved" "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz"
"version" "27.5.1"
......@@ -6057,7 +6212,7 @@
"merge-stream" "^2.0.0"
"supports-color" "^8.0.0"
"jest@^27.0.0 || ^28.0.0", "jest@^27.4.3":
"jest@^27.4.3":
"integrity" "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ=="
"resolved" "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz"
"version" "27.5.1"
......@@ -6066,6 +6221,11 @@
"import-local" "^3.0.2"
"jest-cli" "^27.5.1"
"js-base64@^2.4.9":
"integrity" "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ=="
"resolved" "https://registry.npmmirror.com/js-base64/-/js-base64-2.6.4.tgz"
"version" "2.6.4"
"js-cookie@^2.x.x":
"integrity" "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ=="
"resolved" "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz"
......@@ -6181,9 +6341,8 @@
"resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz"
"version" "6.1.0"
dependencies:
"universalify" "^2.0.0"
optionalDependencies:
"graceful-fs" "^4.1.6"
"universalify" "^2.0.0"
"jsonpointer@^5.0.0":
"integrity" "sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg=="
......@@ -6375,6 +6534,43 @@
dependencies:
"p-locate" "^5.0.0"
"lodash._baseiteratee@~4.7.0":
"integrity" "sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ=="
"resolved" "https://registry.npmmirror.com/lodash._baseiteratee/-/lodash._baseiteratee-4.7.0.tgz"
"version" "4.7.0"
dependencies:
"lodash._stringtopath" "~4.8.0"
"lodash._basetostring@~4.12.0":
"integrity" "sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw=="
"resolved" "https://registry.npmmirror.com/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz"
"version" "4.12.0"
"lodash._baseuniq@~4.6.0":
"integrity" "sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A=="
"resolved" "https://registry.npmmirror.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz"
"version" "4.6.0"
dependencies:
"lodash._createset" "~4.0.0"
"lodash._root" "~3.0.0"
"lodash._createset@~4.0.0":
"integrity" "sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA=="
"resolved" "https://registry.npmmirror.com/lodash._createset/-/lodash._createset-4.0.3.tgz"
"version" "4.0.3"
"lodash._root@~3.0.0":
"integrity" "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ=="
"resolved" "https://registry.npmmirror.com/lodash._root/-/lodash._root-3.0.1.tgz"
"version" "3.0.1"
"lodash._stringtopath@~4.8.0":
"integrity" "sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ=="
"resolved" "https://registry.npmmirror.com/lodash._stringtopath/-/lodash._stringtopath-4.8.0.tgz"
"version" "4.8.0"
dependencies:
"lodash._basetostring" "~4.12.0"
"lodash.debounce@^4.0.8":
"integrity" "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
"resolved" "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz"
......@@ -6395,14 +6591,27 @@
"resolved" "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz"
"version" "4.7.0"
"lodash.throttle@^4.1.1":
"integrity" "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
"resolved" "https://registry.npmmirror.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz"
"version" "4.1.1"
"lodash.uniq@^4.5.0":
"integrity" "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
"resolved" "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz"
"version" "4.5.0"
"lodash.uniqby@4.5.0":
"integrity" "sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ=="
"resolved" "https://registry.npmmirror.com/lodash.uniqby/-/lodash.uniqby-4.5.0.tgz"
"version" "4.5.0"
dependencies:
"lodash._baseiteratee" "~4.7.0"
"lodash._baseuniq" "~4.6.0"
"lodash@^4.17.15", "lodash@^4.17.20", "lodash@^4.17.21", "lodash@^4.7.0":
"integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
"resolved" "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz"
"resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
"version" "4.17.21"
"loose-envify@^1.1.0", "loose-envify@^1.4.0":
......@@ -6586,7 +6795,7 @@
dependencies:
"mobx-react-lite" "^3.4.0"
"mobx@^6.1.0", "mobx@^6.5.0":
"mobx@^6.5.0":
"integrity" "sha512-pHZ/cySF00FVENDWIDzJyoObFahK6Eg4d0papqm6d7yMkxWTZ/S/csqJX1A3PsYy4t5k3z2QnlwuCfMW5lSEwA=="
"resolved" "https://registry.npmjs.org/mobx/-/mobx-6.5.0.tgz"
"version" "6.5.0"
......@@ -6598,7 +6807,7 @@
dependencies:
"commander" "*"
"moment@^2.24.0", "moment@^2.29.1", "moment@^2.29.3":
"moment@^2.29.3":
"integrity" "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw=="
"resolved" "https://registry.npmmirror.com/moment/-/moment-2.29.3.tgz"
"version" "2.29.3"
......@@ -7555,15 +7764,6 @@
"resolved" "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
"version" "4.2.0"
"postcss@^7.0.0 || ^8.0.1", "postcss@^8", "postcss@^8.0.0", "postcss@^8.0.2", "postcss@^8.0.3", "postcss@^8.0.9", "postcss@^8.1.0", "postcss@^8.1.2", "postcss@^8.1.4", "postcss@^8.2.14", "postcss@^8.2.15", "postcss@^8.2.2", "postcss@^8.3", "postcss@^8.3.3", "postcss@^8.3.5", "postcss@^8.4", "postcss@^8.4.12", "postcss@^8.4.4", "postcss@^8.4.6", "postcss@^8.4.7", "postcss@>= 8", "postcss@>=8", "postcss@>=8.0.9":
"integrity" "sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA=="
"resolved" "https://registry.npmjs.org/postcss/-/postcss-8.4.13.tgz"
"version" "8.4.13"
dependencies:
"nanoid" "^3.3.3"
"picocolors" "^1.0.0"
"source-map-js" "^1.0.2"
"postcss@^7.0.35":
"integrity" "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA=="
"resolved" "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz"
......@@ -7572,6 +7772,15 @@
"picocolors" "^0.2.1"
"source-map" "^0.6.1"
"postcss@^8.3.5", "postcss@^8.4.12", "postcss@^8.4.4", "postcss@^8.4.7":
"integrity" "sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA=="
"resolved" "https://registry.npmjs.org/postcss/-/postcss-8.4.13.tgz"
"version" "8.4.13"
dependencies:
"nanoid" "^3.3.3"
"picocolors" "^1.0.0"
"source-map-js" "^1.0.2"
"prelude-ls@^1.2.1":
"integrity" "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
"resolved" "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
......@@ -7643,6 +7852,14 @@
"object-assign" "^4.1.1"
"react-is" "^16.13.1"
"proper-lockfile@^2.0.1":
"integrity" "sha512-rjaeGbsmhNDcDInmwi4MuI6mRwJu6zq8GjYCLuSuE7GF+4UjgzkL69sVKKJ2T2xH61kK7rXvGYpvaTu909oXaQ=="
"resolved" "https://registry.npmmirror.com/proper-lockfile/-/proper-lockfile-2.0.1.tgz"
"version" "2.0.1"
dependencies:
"graceful-fs" "^4.1.2"
"retry" "^0.10.0"
"proxy-addr@~2.0.7":
"integrity" "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="
"resolved" "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz"
......@@ -7673,6 +7890,11 @@
dependencies:
"side-channel" "^1.0.4"
"querystringify@^2.1.1":
"integrity" "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
"resolved" "https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz"
"version" "2.2.0"
"queue-microtask@^1.2.2":
"integrity" "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
"resolved" "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
......@@ -7754,7 +7976,7 @@
"strip-ansi" "^6.0.1"
"text-table" "^0.2.0"
"react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2 || ^18.0.0", "react-dom@^18.0.0", "react-dom@^18.1.0", "react-dom@>=16.6.0", "react-dom@>=16.8":
"react-dom@^18.1.0":
"integrity" "sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w=="
"resolved" "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz"
"version" "18.1.0"
......@@ -7762,11 +7984,32 @@
"loose-envify" "^1.1.0"
"scheduler" "^0.22.0"
"react-dropzone@^14.2.1":
"integrity" "sha512-jzX6wDtAjlfwZ+Fbg+G17EszWUkQVxhMTWMfAC9qSUq7II2pKglHA8aarbFKl0mLpRPDaNUcy+HD/Sf4gkf76Q=="
"resolved" "https://registry.npmmirror.com/react-dropzone/-/react-dropzone-14.2.1.tgz"
"version" "14.2.1"
dependencies:
"attr-accept" "^2.2.2"
"file-selector" "^0.6.0"
"prop-types" "^15.8.1"
"react-error-overlay@^6.0.11":
"integrity" "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
"resolved" "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz"
"version" "6.0.11"
"react-flow-renderer@^10.3.7":
"integrity" "sha512-0WGyozT4SzMpim8MQRFBR8hqm11FGApXm+UD05BoAejhcUgohvmckBTRIQKxzGC2WQLR/6oXRzwzRYGQdrb4rw=="
"resolved" "https://registry.npmmirror.com/react-flow-renderer/-/react-flow-renderer-10.3.7.tgz"
"version" "10.3.7"
dependencies:
"@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"
"react-is@^16.13.1":
"integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
"resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
......@@ -7787,7 +8030,7 @@
"resolved" "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz"
"version" "18.1.0"
"react-refresh@^0.11.0", "react-refresh@>=0.10.0 <1.0.0":
"react-refresh@^0.11.0":
"integrity" "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
"resolved" "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz"
"version" "0.11.0"
......@@ -7817,7 +8060,7 @@
"loose-envify" "^1.4.0"
"prop-types" "^15.6.2"
"react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.1 || ^18.0.0", "react@^17.0.0", "react@^17.0.0 || ^18.0.0", "react@^17.0.2 || ^18.0.0", "react@^18.0.0", "react@^18.1.0", "react@>=16.6.0", "react@>=16.8", "react@>=16.8.0":
"react@^18.1.0":
"integrity" "sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ=="
"resolved" "https://registry.npmjs.org/react/-/react-18.1.0.tgz"
"version" "18.1.0"
......@@ -8021,6 +8264,11 @@
"is-core-module" "^2.2.0"
"path-parse" "^1.0.6"
"retry@^0.10.0":
"integrity" "sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ=="
"resolved" "https://registry.npmmirror.com/retry/-/retry-0.10.1.tgz"
"version" "0.10.1"
"retry@^0.13.1":
"integrity" "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="
"resolved" "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz"
......@@ -8053,7 +8301,7 @@
"serialize-javascript" "^4.0.0"
"terser" "^5.0.0"
"rollup@^1.20.0 || ^2.0.0", "rollup@^1.20.0||^2.0.0", "rollup@^2.0.0", "rollup@^2.43.1":
"rollup@^2.43.1":
"integrity" "sha512-KqtR2YcO35/KKijg4nx4STO3569aqCUeGRkKWnJ6r+AvBBrVY9L4pmf4NHVrQr4mTOq6msbohflxr2kpihhaOA=="
"resolved" "https://registry.npmjs.org/rollup/-/rollup-2.72.0.tgz"
"version" "2.72.0"
......@@ -8872,11 +9120,20 @@
"resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
"version" "1.14.1"
"tslib@^2.0.3":
"tslib@^2.0.3", "tslib@^2.4.0":
"integrity" "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
"resolved" "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz"
"version" "2.4.0"
"tss-react@^3.7.0":
"integrity" "sha512-thvJWR+sr3ZGMcV/Ryo1F5RzjXd1gMTzYV/ckfUEBhu701uTYE3KyL9DNxv827uRFPFSLYG7bKefuc7kmYMB9Q=="
"resolved" "https://registry.npmmirror.com/tss-react/-/tss-react-3.7.0.tgz"
"version" "3.7.0"
dependencies:
"@emotion/cache" "*"
"@emotion/serialize" "*"
"@emotion/utils" "*"
"tsutils@^3.21.0":
"integrity" "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA=="
"resolved" "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz"
......@@ -8884,6 +9141,18 @@
dependencies:
"tslib" "^1.8.1"
"tus-js-client@2.1.1":
"integrity" "sha512-ILpgHlR0nfKxmlkXfrZ2z61upkHEXhADOGbGyvXSPjp7bn1NhU50p/Mu59q577Xirayr9vlW4tmoFqUrHKcWeQ=="
"resolved" "https://registry.npmmirror.com/tus-js-client/-/tus-js-client-2.1.1.tgz"
"version" "2.1.1"
dependencies:
"buffer-from" "^0.1.1"
"combine-errors" "^3.0.3"
"js-base64" "^2.4.9"
"lodash.throttle" "^4.1.1"
"proper-lockfile" "^2.0.1"
"url-parse" "^1.4.3"
"type-check@^0.4.0", "type-check@~0.4.0":
"integrity" "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="
"resolved" "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
......@@ -8913,7 +9182,7 @@
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
"version" "0.20.2"
"type-fest@^0.21.3", "type-fest@>=0.17.0 <3.0.0":
"type-fest@^0.21.3":
"integrity" "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz"
"version" "0.21.3"
......@@ -8933,7 +9202,7 @@
dependencies:
"is-typedarray" "^1.0.0"
"typescript@^4.6.4", "typescript@>= 2.7", "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta":
"typescript@^4.6.4":
"integrity" "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg=="
"resolved" "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz"
"version" "4.6.4"
......@@ -9010,6 +9279,14 @@
dependencies:
"punycode" "^2.1.0"
"url-parse@^1.4.3":
"integrity" "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ=="
"resolved" "https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz"
"version" "1.5.10"
dependencies:
"querystringify" "^2.1.1"
"requires-port" "^1.0.0"
"use-immer@^0.7.0":
"integrity" "sha512-Re4hjrP3a/2ABZjAc0b7AK9s626bnO+H33RO2VUhiDZ2StBz5B663K6WNNlr4QtHWaGUmvLpwt3whFvvWuolQw=="
"resolved" "https://registry.npmjs.org/use-immer/-/use-immer-0.7.0.tgz"
......@@ -9131,7 +9408,7 @@
"range-parser" "^1.2.1"
"schema-utils" "^4.0.0"
"webpack-dev-server@^4.6.0", "webpack-dev-server@3.x || 4.x":
"webpack-dev-server@^4.6.0":
"integrity" "sha512-+Nlb39iQSOSsFv0lWUuUTim3jDQO8nhK3E68f//J2r5rIcp4lULHXz2oZ0UVdEeWXEh5lSzYUlzarZhDAeAVQw=="
"resolved" "https://registry.npmmirror.com/webpack-dev-server/-/webpack-dev-server-4.9.0.tgz"
"version" "4.9.0"
......@@ -9194,7 +9471,7 @@
"resolved" "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz"
"version" "3.2.3"
"webpack@^4.0.0 || ^5.0.0", "webpack@^4.37.0 || ^5.0.0", "webpack@^4.4.0 || ^5.9.0", "webpack@^4.44.2 || ^5.47.0", "webpack@^5.0.0", "webpack@^5.1.0", "webpack@^5.20.0", "webpack@^5.64.4", "webpack@>= 4", "webpack@>=2", "webpack@>=4.43.0 <6.0.0":
"webpack@^5.64.4":
"integrity" "sha512-qmSmbspI0Qo5ld49htys8GY9XhS9CGqFoHTsOVAnjBdg0Zn79y135R+k4IR4rKK6+eKaabMhJwiVB7xw0SJu5w=="
"resolved" "https://registry.npmjs.org/webpack/-/webpack-5.72.0.tgz"
"version" "5.72.0"
......@@ -9558,3 +9835,8 @@
"integrity" "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
"resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
"version" "0.1.0"
"zustand@^3.7.2":
"integrity" "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA=="
"resolved" "https://registry.npmmirror.com/zustand/-/zustand-3.7.2.tgz"
"version" "3.7.2"
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