Commit 26ae1b6c authored by wuyongsheng's avatar wuyongsheng

Merge branch 'release' into 'staging'

Release

See merge request !173
parents e5fc0ad2 e4ad730c
......@@ -10561,6 +10561,11 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
......@@ -10594,6 +10599,19 @@
"prop-types": "^15.6.2"
}
},
"react-virtualized": {
"version": "9.22.3",
"resolved": "https://registry.npmmirror.com/react-virtualized/-/react-virtualized-9.22.3.tgz",
"integrity": "sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==",
"requires": {
"@babel/runtime": "^7.7.2",
"clsx": "^1.0.4",
"dom-helpers": "^5.1.3",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-lifecycles-compat": "^3.0.4"
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
......
......@@ -74,6 +74,7 @@
"react-flow-renderer": "^10.3.7",
"react-refresh": "^0.11.0",
"react-router-dom": "^6.3.0",
"react-virtualized": "^9.22.3",
"resolve": "^1.20.0",
"resolve-url-loader": "^4.0.0",
"sass": "^1.55.0",
......
......@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-19 17:09:23
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-27 11:23:29
* @LastEditTime: 2022-10-31 11:22:34
* @FilePath: /bkunyun/src/api/resourceCenter.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -118,9 +118,9 @@ const getWorkflowspecList = (params: {productId?: string, title?: string}) => {
// API_WORKFLOWSPEC_LIST
// 新增应用环境
const saveOperator = (params: any, isEdit: boolean) => {
const saveOperator = (params: any) => {
return request({
url: `${Api.API_SAVE_OPERATOR}?isEdit=${isEdit}`,
url: `${Api.API_SAVE_OPERATOR}`,
method: "post",
data: params,
});
......
......@@ -9,6 +9,7 @@ interface ICardTableProps {
numberOfColumns?: number; // 列数 每行渲染几个
horizontalSpacing?: number; // 水平方向的间隔
verticalSpacing?: number; // 垂直方向的间隔
renderBefore?: any;
}
const CardTable = (props: ICardTableProps) => {
......@@ -20,6 +21,7 @@ const CardTable = (props: ICardTableProps) => {
horizontalSpacing = 20,
verticalSpacing = 20,
itemMinWidth,
renderBefore,
} = props;
const [numberOfColumns, setNumberOfColumns] = useState(3);
......@@ -59,6 +61,20 @@ const CardTable = (props: ICardTableProps) => {
}}
ref={tableBoxRef}
>
{renderBefore && renderBefore() && (
<div
className={style.itemBox}
style={{
width: boxWidth,
paddingLeft: `${horizontalSpacing / 2}px`,
paddingRight: `${horizontalSpacing / 2}px`,
paddingBottom: `${verticalSpacing}px`,
boxSizing: "border-box",
}}
>
{renderBefore()}
</div>
)}
{data.map((item, index) => {
return (
<div
......
import { List } from "react-virtualized";
interface IVirtuallyListProps {
list: Array<any>;
renderRow: any;
}
const VirtuallyList = (props: IVirtuallyListProps) => {
const { list, renderRow } = props;
return (
<List
width={300}
height={300}
rowCount={list.length}
rowHeight={20}
rowRenderer={renderRow}
overscanRowCount={20}
/>
);
};
export default VirtuallyList;
......@@ -15,6 +15,7 @@ import { ThemeProvider, createTheme } from "@mui/material/styles";
import { TabContext, TabList, TabPanel } from "@mui/lab";
import { Typography } from "@mui/material";
import classNames from "classnames";
import { useNavigate } from "react-router-dom";
import styles from "./index.module.css";
......@@ -46,6 +47,8 @@ interface IProps {
tabPanelSx?: any;
/** 是否允许空值 */
allowNullValue?: boolean;
/** 路由地址 配合navigate和MyTabs组件的defaultValue组合使用、F5刷新也可以保存激活的tab */
navigateUrl?: string;
}
const theme = createTheme({
......@@ -101,8 +104,11 @@ const Tabs = (props: IProps) => {
tabPanelSx = { padding: "20px 0 0 0" },
title,
titleClass,
navigateUrl,
} = props;
const navigate = useNavigate();
const [tabValue, setTabValue] = useState(
defaultValue
? defaultValue
......@@ -116,6 +122,10 @@ const Tabs = (props: IProps) => {
const onTabChange = (val: string) => {
setTabValue(val);
onChange && onChange(val);
navigateUrl &&
navigate(navigateUrl, {
state: { defaultTab: val },
});
};
const getImgSrc = useCallback(
......
......@@ -86,4 +86,6 @@ declare module "tus-js-client";
declare module "uuid";
declare module "kekule";
declare module 'ngl';
declare module 'react-virtualized';
......@@ -52,7 +52,13 @@ const OperatorList = (props: IProps) => {
};
});
setIsLastPage(res?.data?.last);
setList([...list, ...arr]);
/** 兼容更改其他条件初始化,重置数据 */
if (res?.data?.pageable?.pageNumber === 0) {
setList(arr);
} else {
setList([...list, ...arr]);
}
},
});
......
......@@ -20,42 +20,26 @@
overflow: overlay;
}
.templateList {
/* height: 2000px; */
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.templateLi {
height: 170px;
.addTemplate {
border: 2px solid #fff;
box-shadow: 0px 3px 12px 0px rgba(3, 47, 105, 0.09);
border-radius: 6px;
background: linear-gradient(180deg, #f5f7fa 0%, #ffffff 100%);
height: 208px;
box-sizing: border-box;
padding: 16px 20px;
/* cursor: pointer; */
border: 1px solid rgba(235, 237, 240, 1);
border-radius: 4px;
min-width: 20%;
flex: 1;
margin-right: 16px;
margin-bottom: 16px;
transition: box-shadow .2s cubic-bezier(0, 0, 1, 1);
}
.templateLiCustom {
height: 170px;
}
.templateLiHidden {
visibility: hidden;
}
.addCustomTemplate {
height: 170px;
box-sizing: border-box;
transition: box-shadow 0.2s cubic-bezier(0, 0, 1, 1);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 208px;
box-sizing: border-box;
cursor: pointer;
}
.addTemplate:hover {
box-shadow: 0px 6px 24px 0px rgb(3 47 105 / 14%);
}
.addCustomTemplateText {
......@@ -65,53 +49,7 @@
color: rgba(138, 144, 153, 1);
}
.templateLi:hover {
box-shadow: 6px 8px 22px 0px rgba(0, 24, 57, 0.08);
}
.templateLi:nth-child(4n) {
margin-right: 0;
}
.templateLiTop {
display: flex;
justify-content: space-between;
align-items: center;
}
.templateTitle {
font-size: 14px;
font-weight: 600;
color: #1e2633;
margin-bottom: 4px;
overflow: hidden;
text-overflow: ellipsis;
line-height: 22px;
}
.templateLiInfo {
margin-bottom: 8px;
}
.templateLiInfoText {
line-height: 20px;
font-size: 12px;
color: rgba(19, 112, 255, 1);
}
.templateLiDesc {
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
display: -webkit-box;
height: 54px;
font-size: 12px;
color: rgba(138, 144, 153, 1);
}
.templateLiEditBox {
display: flex;
justify-content: flex-end;
/* margin-top: 16px; */
}
\ No newline at end of file
}
......@@ -12,6 +12,8 @@ import AddIcon from "@mui/icons-material/Add";
import WorkFlowEdit from "@/views/WorkFlowEdit";
import noData from "../../../../../../assets/project/noTemplate.svg";
import { ICustomTemplate } from "../../interface";
import TemplateItem from "@/views/ResourceCenter/UserResources/UserResourcesTemplate/TemplateItem";
import CardTable from "@/components/CommonComponents/CardTable";
import { useMessage } from "@/components/MySnackbar";
import {
getAddWorkbenchTemplate,
......@@ -203,16 +205,6 @@ const AddTemplate = (props: IAddTemplateProps) => {
}
};
const hiddenBoxArr = useMemo(() => {
const length =
templateType === "public"
? addTemplateList.length
: addTemplateList.length + 1;
const hiddenBoxNumber = 4 - (length % 4);
const arr = new Array(hiddenBoxNumber).fill("");
return arr;
}, [addTemplateList, templateType]);
return (
<FullScreenDrawer handleClose={setShowAddTemplate}>
<div className={style.content}>
......@@ -259,19 +251,6 @@ const AddTemplate = (props: IAddTemplateProps) => {
radioOptions={radioOptions}
handleRadio={handleRadio}
/>
{/* <MyButton
onClick={handleAddTemplate}
size={"small"}
style={{
marginLeft: "12px",
}}
text={
"添加模版" +
(selectTemplateData.length === 0
? ""
: `(${selectTemplateData.length})`)
}
/> */}
</Box>
</Box>
</div>
......@@ -294,90 +273,45 @@ const AddTemplate = (props: IAddTemplateProps) => {
</Typography>
</Box>
)}
<div className={style.templateList}>
{templateType !== "public" && (
<div
className={classNames({
[style.templateLi]: true,
[style.addCustomTemplate]: true,
})}
onClick={handleAddCustomTemplate}
>
<AddIcon />
<span className={style.addCustomTemplateText}>
创建自定义模板
</span>
</div>
)}
{addTemplateList.map((item: any, index) => {
return (
<div
className={classNames({
[style.templateLi]: true,
[style.templateLiCustom]: templateType !== "public",
})}
key={index}
onClick={() => {
handleSelectTemplate(item.id);
}}
>
<div className={style.templateLiTop}>
<span className={style.templateTitle}>{item.title}</span>
{/* <Checkbox
size="small"
sx={{ padding: "0px" }}
checked={selectTemplateData.includes(item.id)}
/> */}
</div>
<div className={style.templateLiInfo}>
<span
className={style.templateLiInfoText}
style={{ marginRight: "24px" }}
>
版本:{item.version}
</span>
<span className={style.templateLiInfoText}>
更新时间:{item.updatedTime}
</span>
</div>
<div className={style.templateLiDesc}>{item.description}</div>
<div className={style.templateLiEditBox}>
<MySwitch
defaultChecked={item.favorited}
onChange={(e: any) => templateSwitch(e, item.id)}
></MySwitch>
</div>
{/* {templateType !== "public" && (
<MyButton
onClick={() => handleEditTemplate(item)}
size={"small"}
style={{
height: "32px",
}}
color="inherit"
text="编辑模板"
/>
</div>
)} */}
</div>
);
})}
{hiddenBoxArr.length !== 4 &&
hiddenBoxArr.map((item, index) => {
<CardTable
data={addTemplateList}
renderBefore={() => {
if (templateType !== "public") {
return (
<div
key={`-${index}`}
className={classNames({
[style.templateLi]: true,
[style.templateLiHidden]: true,
[style.addTemplate]: true,
})}
/>
onClick={handleAddCustomTemplate}
>
<AddIcon />
<span className={style.addCustomTemplateText}>
创建自定义模板
</span>
</div>
);
})}
</div>
}
return null;
}}
renderItem={(item: any) => {
return (
<TemplateItem
templateInfo={item}
footer={() => {
return (
<div className={style.templateLiEditBox}>
<MySwitch
defaultChecked={item.favorited}
onChange={(e: any) => templateSwitch(e, item.id)}
></MySwitch>
</div>
);
}}
></TemplateItem>
);
}}
itemMinWidth={377}
></CardTable>
</div>
</div>
{customTemplateInfo?.show ? (
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-17 14:48:57
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-27 14:02:54
* @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, useState } from "react";
import styles from "../index.module.css";
import { Box, Typography } from "@mui/material";
import MyButton from "@/components/mui/MyButton";
import usePass from "@/hooks/usePass";
import RemindBudgetDialog from "./RemindBudgetDialog";
import { useNavigate } from "react-router-dom";
import { toJS } from "mobx";
import { useStores } from "@/store";
import { observer } from "mobx-react-lite";
const TemplateBox = observer((props: any) => {
const info = props.data;
const { isParentUser, isOwner, greaterThan100 } = props;
const { currentProjectStore } = useStores();
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
const isPass = usePass();
const navigate = useNavigate();
const [rbOpen, setRbOpen] = useState(false);
const [id, setId] = useState("");
const goToProjectSubmitWork = useCallback(
(id: string) => {
navigate(`/product/${productId || "cadd"}/projectSubmitWork`, {
state: { id },
});
},
[navigate, productId]
);
const handleJudgeBudget = useCallback(
(id: string) => {
setId(id);
if (greaterThan100) {
goToProjectSubmitWork(id);
} else {
setRbOpen(true);
}
},
[goToProjectSubmitWork, setRbOpen, setId, greaterThan100]
);
return (
<>
<Box className={styles.template}>
<Box className={styles.templateBlock}>
<Box>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Typography
sx={{
fontSize: "14px",
fontWeight: "600",
color: "#1E2633",
marginBottom: "4px",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
{info.title}
</Typography>
{info.creator !== "root" && (
<Box
sx={{
backgroundColor: "rgba(227, 250, 236, 1)",
color: "rgba(2, 171, 131, 1)",
lineHeight: "20px",
padding: "1px 9px",
fontSize: "12px",
}}
>
自定义
</Box>
)}
</Box>
<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.updatedTime}
</Typography>
</Box>
<Typography className={styles.templateDescText}>
{info.description ? info.description : "此模板暂无描述。"}
</Typography>
</Box>
<Box
sx={{
display: "flex",
justifyContent: "end",
}}
>
{isPass("PROJECT_WORKBENCH_FLOES_USE", "MANAGER") && (
<MyButton
size="medium"
text="移除模版"
onClick={() => {
props.startDialog(info.id);
}}
style={{ backgroundColor: "#F0F2F5", color: "#565C66" }}
/>
)}
{isPass("PROJECT_WORKBENCH_FLOES_USE", "USER") && (
<MyButton
size="medium"
text="使用模版"
onClick={() => handleJudgeBudget(info.id)}
style={{ marginLeft: "12px" }}
/>
)}
</Box>
</Box>
</Box>
{rbOpen && (
<RemindBudgetDialog
rbOpen={rbOpen}
rbClose={() => setRbOpen(false)}
id={id}
goToProjectSubmitWork={goToProjectSubmitWork}
isParentUser={isParentUser}
isOwner={isOwner}
></RemindBudgetDialog>
)}
</>
);
});
export default memo(TemplateBox);
......@@ -6,7 +6,7 @@
* @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, useEffect, useState, useCallback } from "react";
import { Box, Typography } from "@mui/material";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
......@@ -16,10 +16,13 @@ import { getLoaclStorageOfKey } from "@/api/fileserver/utils";
import MyButton from "@/components/mui/MyButton";
import SearchInput from "@/components/BusinessComponents/SearchInput";
import useMyRequest from "@/hooks/useMyRequest";
import TemplateBox from "./components/templateBox";
import { useNavigate } from "react-router-dom";
import TemplateItem from "@/views/ResourceCenter/UserResources/UserResourcesTemplate/TemplateItem";
import SimpleDialog from "./components/simpleDialog";
import AddTemplate from "./components/AddTemplate/index";
import noData from "../../../../assets/project/noTemplate.svg";
import RemindBudgetDialog from "./components/RemindBudgetDialog";
import CardTable from "@/components/CommonComponents/CardTable";
import {
getWorkbenchTemplate,
deleteWorkbenchTemplate,
......@@ -37,7 +40,10 @@ const ProjectMembers = observer(() => {
const { currentProjectStore } = useStores();
const projectIdData = toJS(currentProjectStore.currentProjectInfo.id);
const productId = toJS(currentProjectStore.currentProductInfo.id);
const navigate = useNavigate();
const isPass = usePass();
const [selectId, setSelectId] = useState("");
const [rbOpen, setRbOpen] = useState(false);
/** 搜索模板名称 */
const [templateName, setTemplateName] = useState("");
......@@ -156,6 +162,27 @@ const ProjectMembers = observer(() => {
});
}, [currentProjectStore.currentProjectInfo.id, getProjectFn]);
const goToProjectSubmitWork = useCallback(
(id: string) => {
navigate(`/product/${productId || "cadd"}/projectSubmitWork`, {
state: { id },
});
},
[navigate, productId]
);
const handleJudgeBudget = useCallback(
(id: string) => {
setSelectId(id);
if (greaterThan100) {
goToProjectSubmitWork(id);
} else {
setRbOpen(true);
}
},
[goToProjectSubmitWork, setRbOpen, setSelectId, greaterThan100]
);
return (
<Box className={styles.headerBox}>
<Box className={styles.tabBox}>
......@@ -188,24 +215,49 @@ const ProjectMembers = observer(() => {
</Typography>
</Box>
)}
{templateList.length > 0 && (
<Box className={styles.templateBox}>
{templateList &&
templateList.length > 0 &&
templateList.map((item, key) => {
return (
<TemplateBox
key={key}
data={item}
startDialog={startDialog}
isParentUser={isParentUser}
isOwner={isOwner}
greaterThan100={greaterThan100}
/>
);
})}
</Box>
)}
<CardTable
data={templateList}
renderItem={(item: any) => {
return (
<TemplateItem
templateInfo={item}
footer={() => {
return (
<Box
sx={{
display: "flex",
justifyContent: "end",
}}
>
{isPass("PROJECT_WORKBENCH_FLOES_USE", "MANAGER") && (
<MyButton
size="medium"
text="移除模版"
onClick={() => {
startDialog(item.id);
}}
style={{
backgroundColor: "#F0F2F5",
color: "#565C66",
}}
/>
)}
{isPass("PROJECT_WORKBENCH_FLOES_USE", "USER") && (
<MyButton
size="medium"
text="使用模版"
onClick={() => handleJudgeBudget(item.id)}
style={{ marginLeft: "12px" }}
/>
)}
</Box>
);
}}
></TemplateItem>
);
}}
itemMinWidth={377}
></CardTable>
{showAddTemplate && (
<AddTemplate
......@@ -222,6 +274,17 @@ const ProjectMembers = observer(() => {
/>
)}
{rbOpen && (
<RemindBudgetDialog
rbOpen={rbOpen}
rbClose={() => setRbOpen(false)}
id={selectId}
goToProjectSubmitWork={goToProjectSubmitWork}
isParentUser={isParentUser}
isOwner={isOwner}
></RemindBudgetDialog>
)}
<SimpleDialog
text={"确认移除该模板吗?"}
title="移除模板"
......
......@@ -78,6 +78,18 @@
.code {
background-color: rgba(247, 248, 250, 1);
flex: 1;
position: relative;
}
.codeHelper {
width: 100%;
box-sizing: border-box;
position: absolute;
bottom: 0;
color: rgba(255, 78, 78, 1);
font-size: 12px;
line-height: 20px;
padding: 6px 20px;
background-color: rgba(255, 232, 232, 1);
}
.label {
color: rgba(30, 38, 51, 1);
......
......@@ -27,10 +27,11 @@ import { getTokenInfo } from "@/utils/util";
type IAddEnvironmentProps = {
setAddopen: any;
setTitle: any;
};
const AddEnvironment = (props: IAddEnvironmentProps) => {
const { setAddopen } = props;
const { setAddopen, setTitle } = props;
const Message = useMessage();
let tokenInfo = getTokenInfo();
const [hpczoneList, setHpczoneList] = useState<Array<any>>([]); // 计算区列表 通过计算区列表和计算区id拿fileServerEndPoint
......@@ -63,6 +64,14 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
error: false,
text: "",
});
const [shellHelper] = useState({
error: false,
text: "请输入Shell脚本",
});
const [pythonHelper] = useState({
error: false,
text: "请输入Python脚本",
});
const onDrop = useCallback(
(acceptedFiles: any) => {
let origin = "";
......@@ -111,6 +120,10 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
setIsUploading(false);
setFilePaths([`/ProjectData/${homeDirectoryMountPoint}/${path}`]);
setFileName(path);
setFilePathsHelper({
error: false,
text: "",
});
},
});
setIsUploading(true);
......@@ -164,6 +177,7 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
{
onSuccess: () => {
Message.success("开始构建应用环境");
setTitle("");
setAddopen(false);
},
}
......@@ -339,7 +353,10 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
<SwitchBatchFolw
active={taskType}
setActive={setTaskType}
goBack={() => setAddopen(false)}
goBack={() => {
setTitle("");
setAddopen(false);
}}
></SwitchBatchFolw>
</div>
<div className={style.right}>
......@@ -499,6 +516,9 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
height="535px"
width={`${codeWidth}px`}
/>
{taskType === "BATCH" && !code && (
<div className={style.codeHelper}>{shellHelper.text}</div>
)}
</div>
</div>
</div>
......@@ -508,13 +528,16 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
Python脚本
<span className={style.required}>*</span>
</div>
<div className={style.code} id="addEnvironmentCode">
<div className={style.code}>
<Code
value={flowCode}
onChange={(e: string) => setFlowCode(e)}
height="535px"
width={`${codeWidth + 368}px`}
/>
{!flowCode && (
<div className={style.codeHelper}>{pythonHelper.text}</div>
)}
</div>
</div>
)}
......
.environment {
padding: 19px 24px 0;
padding: 20px 24px 0;
}
.top {
display: flex;
......
......@@ -198,19 +198,21 @@ const UserResourcesEnvironment = () => {
<div className={style.environment}>
<div className={style.top}>
<div className={style.topLeft}>
<SearchInput
sx={{ width: 340, marginRight: "16px" }}
onKeyUp={(e: any) => {
if (e.keyCode === 13) {
setTitle(e.target.value);
}
}}
></SearchInput>
{!addOpen && (
<SearchInput
sx={{ width: 340, marginRight: "16px" }}
onKeyUp={(e: any) => {
if (e.keyCode === 13) {
setTitle(e.target.value);
}
}}
></SearchInput>
)}
{!addOpen && (
<MySelect
options={[
{
label: "全部",
label: "全部环境",
value: "ALL",
},
{
......@@ -264,7 +266,12 @@ const UserResourcesEnvironment = () => {
setSortState={setSortState}
></MyTable>
</div>
{addOpen && <AddEnvironment setAddopen={setAddopen}></AddEnvironment>}
{addOpen && (
<AddEnvironment
setAddopen={setAddopen}
setTitle={setTitle}
></AddEnvironment>
)}
{deleteOpen && (
<DeleteEnvironment
id={id}
......
.templateBox {
border: 2px solid #fff;
box-shadow: 0px 3px 12px 0px rgba(3, 47, 105, 0.09);
border-radius: 6px;
background: linear-gradient(180deg, #f5f7fa 0%, #ffffff 100%);
height: 208px;
box-sizing: border-box;
padding: 16px 20px;
transition: box-shadow 0.2s cubic-bezier(0, 0, 1, 1);
&:hover {
box-shadow: 0px 6px 24px 0px rgb(3 47 105 / 14%);
}
.templateTop {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 12px;
.templateTopItem {
font-size: 12px;
line-height: 20px;
color: rgba(138, 144, 153, 1);
}
.templateTopLine {
width: 1px;
height: 16px;
background-color: rgba(221, 225, 230, 1);
margin: 0 11px;
}
}
.templateTitleBox {
height: 24px;
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 12px;
.templateTitle {
font-size: 15px;
line-height: 22px;
color: rgba(30, 38, 51, 1);
margin-left: 8px;
font-weight: 550;
}
}
.templateDesc {
height: 60px;
font-size: 12px;
line-height: 20px;
color: rgba(86, 92, 102, 1);
margin-bottom: 16px;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
display: -webkit-box;
}
}
import { useStores } from "@/store";
import { toJS } from "mobx";
import templateIcon from "@/assets/resourceCenter/templateIcon.svg";
import style from "./index.module.scss";
interface ITemplateItemPorps {
templateInfo: any;
footer: any;
}
const TemplateItem = (props: ITemplateItemPorps) => {
const { templateInfo, footer } = props;
const { productListStore } = useStores();
const getProductName = (productId: string) => {
let res = "-";
toJS(productListStore.productList).forEach((item) => {
if (item.value === productId) {
res = item.label;
}
});
return res;
};
return (
<div className={style.templateBox}>
<div className={style.templateTop}>
<div className={style.templateTopItem}>
{getProductName(templateInfo.productId)}
</div>
{templateInfo.creator !== "root" && (
<>
<div className={style.templateTopLine}></div>
<div className={style.templateTopItem}>自定义</div>
</>
)}
<div className={style.templateTopLine}></div>
<div className={style.templateTopItem}>{templateInfo.version}</div>
<div className={style.templateTopLine}></div>
<div className={style.templateTopItem}>{templateInfo.updatedTime}</div>
</div>
<div className={style.templateTitleBox}>
<img src={templateIcon} alt="" />
<div className={style.templateTitle}>{templateInfo.title}</div>
</div>
<div className={style.templateDesc}>{templateInfo.description}</div>
{footer && footer()}
</div>
);
};
export default TemplateItem;
.template {
padding: 19px 24px 0;
padding: 20px 24px 0;
}
.top {
display: flex;
......@@ -10,60 +10,7 @@
.tableBox {
height: calc(100vh - 177px);
}
.templateBox {
border: 2px solid #fff;
box-shadow: 0px 3px 12px 0px rgba(3, 47, 105, 0.09);
border-radius: 6px;
background: linear-gradient(180deg, #f5f7fa 0%, #ffffff 100%);
height: 208px;
box-sizing: border-box;
padding: 16px 20px;
}
.templateTop {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 12px;
}
.templateTopItem {
font-size: 12px;
line-height: 20px;
color: rgba(138, 144, 153, 1);
}
.templateTopLine {
width: 1px;
height: 16px;
background-color: rgba(221, 225, 230, 1);
margin: 0 11px;
}
.templateTitleBox {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 12px;
}
.templateTitleBox {
height: 24px;
}
.templateTitle {
font-size: 14px;
line-height: 22px;
color: rgba(30, 38, 51, 1);
margin-left: 8px;
font-weight: 550;
}
.templateDesc {
height: 60px;
font-size: 12px;
line-height: 20px;
color: rgba(86, 92, 102, 1);
margin-bottom: 16px;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
display: -webkit-box;
}
.templateButtons {
display: flex;
align-items: center;
......
......@@ -8,14 +8,13 @@ import CardTable from "@/components/CommonComponents/CardTable";
import useMyRequest from "@/hooks/useMyRequest";
import { getWorkflowspecList, deleteWorkflowspec } from "@/api/resourceCenter";
import MyDialog from "@/components/mui/MyDialog";
import templateIcon from "@/assets/resourceCenter/templateIcon.svg";
import { useStores } from "@/store";
import { toJS } from "mobx";
import ProductSelect from "@/components/BusinessComponents/ProductSelect";
import WorkFlowEdit from "@/views/WorkFlowEdit";
import { useMessage } from "@/components/MySnackbar";
import TemplateDetail from "./TemplateDetail";
import style from "./index.module.css";
import TemplateItem from "./TemplateItem";
import NoData from "@/components/BusinessComponents/NoData";
const UserResourcesTemplate = observer(() => {
......@@ -26,74 +25,56 @@ const UserResourcesTemplate = observer(() => {
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [showDetail, setShowDetail] = useState(false); // 详情
const [templateId, setTemplateId] = useState("");
const [product, setProduct] = useState(""); // 搜索列表用
const [product, setProduct] = useState("all"); // 搜索列表用
const [productId, setProductId] = useState(""); // 新增模板用
const [list, setList] = useState([]);
const { productListStore } = useStores();
const getProductName = (productId: string) => {
let res = "-";
toJS(productListStore.productList).forEach((item) => {
if (item.value === productId) {
res = item.label;
}
});
return res;
};
const renderItem = (item: any) => {
return (
<div className={style.templateBox}>
<div className={style.templateTop}>
<div className={style.templateTopItem}>
{getProductName(item.productId)}
</div>
<div className={style.templateTopLine}></div>
<div className={style.templateTopItem}>{item.version}</div>
<div className={style.templateTopLine}></div>
<div className={style.templateTopItem}>{item.updatedTime}</div>
</div>
<div className={style.templateTitleBox}>
<img src={templateIcon} alt="" />
<div className={style.templateTitle}>{item.title}</div>
</div>
<div className={style.templateDesc}>{item.description}</div>
<div className={style.templateButtons}>
<div className={style.templateBL}>
<span
className={style.button}
onClick={() => {
setTemplateId(item.id);
setProductId(item.productId);
setShowAddTemplate(true);
}}
>
升级
</span>
</div>
<div className={style.templateBR}>
<MyButton
text="删除"
variant="outlined"
style={{
border: "1px solid rgba(221, 225, 230, 1)",
color: "rgba(138, 144, 153, 1)",
marginRight: "12px",
}}
onClick={() => {
setShowDeleteDialog(true);
setTemplateId(item.id);
}}
></MyButton>
<MyButton
text="查看"
variant="outlined"
onClick={() => {
setTemplateId(item.id);
setShowDetail(true);
}}
></MyButton>
</div>
</div>
</div>
<TemplateItem
templateInfo={item}
footer={() => {
return (
<div className={style.templateButtons}>
<div className={style.templateBL}>
<span
className={style.button}
onClick={() => {
setTemplateId(item.id);
setProductId(item.productId);
setShowAddTemplate(true);
}}
>
升级
</span>
</div>
<div className={style.templateBR}>
<MyButton
text="删除"
variant="outlined"
style={{
border: "1px solid rgba(221, 225, 230, 1)",
color: "rgba(138, 144, 153, 1)",
marginRight: "12px",
}}
onClick={() => {
setShowDeleteDialog(true);
setTemplateId(item.id);
}}
></MyButton>
<MyButton
text="查看"
variant="outlined"
onClick={() => {
setTemplateId(item.id);
setShowDetail(true);
}}
></MyButton>
</div>
</div>
);
}}
></TemplateItem>
);
};
......@@ -143,7 +124,7 @@ const UserResourcesTemplate = observer(() => {
<MySelect
options={
[
{ label: "全部", value: "all" },
{ label: "全部产品", value: "all" },
...productListStore?.productList,
] || []
}
......
......@@ -33,12 +33,12 @@
.content {
display: flex;
/* position: relative; */
/* overflow: hidden; */
position: relative;
border-radius: 4px;
margin-bottom: 20px;
height: 600px;
height: 562px;
}
.form {
width: 368px;
min-width: 368px;
......@@ -97,6 +97,11 @@
padding-left: 32px;
}
.helpBox {
width: 368px;
height: 100%;
}
.codeErrorBox {
padding-left: 20px;
height: 32px;
......@@ -109,3 +114,34 @@
.react-flow > div:last-child {
display: none;
}
.formOpen {
position: absolute;
height: 100%;
left: -420px;
}
.formClose {
height: 100%;
}
.helpOpen {
height: 100%;
}
.helpClose {
position: absolute;
height: 100%;
right: -420px;
}
.preBox {
background-color: #f7f8fa;
height: calc(100% - 84px);
padding: 20px;
font-size: 12px;
color: #1e2633;
overflow: auto;
word-wrap: break-word;
white-space: pre-wrap;
}
......@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-18 16:12:55
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-28 16:48:21
* @LastEditTime: 2022-11-01 11:34:04
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -41,13 +41,13 @@ import {
import batchOperator from "@/assets/resourceCenter/batchOperator.svg";
import flowOperator from "@/assets/resourceCenter/flowOperator.svg";
import { useMessage } from "@/components/MySnackbar";
import MyPopover from "@/components/mui/MyPopover";
import CloseIcon from "@mui/icons-material/Close";
import useCheckOperator from "@/views/CustomOperator/useCheckOperator";
import { saveBatchActor } from "@/api/project_api";
import positionTransform from "@/views/CustomOperator/utils";
import MyTooltip from "@/components/mui/MyTooltip";
import style from "./index.module.css";
import MyTooltip from "@/components/mui/MyTooltip";
interface IAddOperator {
pageType: string;
......@@ -326,7 +326,7 @@ const AddOperator = observer((props: IAddOperator) => {
body: positionTransform(params?.parameters || []),
});
} else {
runSaveOperator(params, detailsId ? true : false);
runSaveOperator(params);
}
}, [
batchBuildType,
......@@ -348,7 +348,7 @@ const AddOperator = observer((props: IAddOperator) => {
try {
const newData = JSON.parse(code);
const nameArr = newData?.map((item: any) => {
return `${item.name}: ~{$actorName$.${item.name}}`;
return `${item.title}: ~{$actorName$.${item.name}}`;
});
newText = nameArr?.join("\n");
} catch (err) {
......@@ -392,12 +392,13 @@ const AddOperator = observer((props: IAddOperator) => {
/>
</div>
) : null}
<div className={style.content}>
<div
className={classNames({
[style.form]: batchBuildType === "ENVIRONMENT",
[style.newForm]: batchBuildType !== "ENVIRONMENT",
[style.formOpen]: batchBuildType !== "OPERATOR" && tipsOpen,
[style.formClose]: !tipsOpen,
})}
>
<FormItemBox
......@@ -418,7 +419,6 @@ const AddOperator = observer((props: IAddOperator) => {
placeholder="请输入算子名称"
value={formData?.title}
onChange={(e) => {
if (e.target.value?.length > 15) return;
changeFormData({ title: e.target.value });
}}
/>
......@@ -499,7 +499,7 @@ const AddOperator = observer((props: IAddOperator) => {
style={{
position: "absolute",
fontSize: "14px",
bottom: "7px",
top: "96px",
right: "12px",
color:
Number(formData?.description?.length) >= 300
......@@ -517,19 +517,12 @@ const AddOperator = observer((props: IAddOperator) => {
<div className={style.codeBox}>
<div className={style.codeTitle}>
<span>参数配置</span>
<MyPopover
open={tipsOpen}
changeOpen={(val) => setTipsOpen(val)}
content={<pre>{text}</pre>}
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
<span
onClick={() => setTipsOpen(!tipsOpen)}
style={{ color: "#1370FF", cursor: "pointer" }}
>
<span style={{ color: "#1370FF", cursor: "pointer" }}>
帮助手册
</span>
</MyPopover>
帮助手册
</span>
</div>
<div className={style.code}>
<Code
......@@ -539,7 +532,7 @@ const AddOperator = observer((props: IAddOperator) => {
setCode(e);
}}
onBlur={paramsConfigBlur}
height={parametersError ? "480px" : "512px"}
height={parametersError ? "486px" : "518px"}
width="600"
style={{ flex: 1 }}
/>
......@@ -572,7 +565,7 @@ const AddOperator = observer((props: IAddOperator) => {
style={{
position: "absolute",
fontSize: "14px",
bottom: "7px",
top: "216px",
right: "12px",
color:
Number(formData?.description?.length) >= 300
......@@ -585,8 +578,40 @@ const AddOperator = observer((props: IAddOperator) => {
</FormItemBox>
</div>
)}
<div></div>
{batchBuildType !== "OPERATOR" && (
<div
className={classNames({
[style.helpBox]: true,
[style.helpOpen]: tipsOpen,
[style.helpClose]: !tipsOpen,
})}
>
<div className={style.codeTitle}>
<span>帮助手册</span>
<CloseIcon
onClick={() => setTipsOpen(false)}
sx={{
fontSize: "16px",
color: "#C2C6CC",
cursor: "pointer",
":hover": {
background: "#f0f2f5",
borderRadius: "2px",
},
}}
/>
</div>
<pre
className={classNames({
[style.preBox]: true,
})}
>
{text}
</pre>
</div>
)}
</div>
{taskType === "FLOW" ? null : (
<div
className={style.parameterConfigBox}
......
......@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-20 17:36:14
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-28 15:22:13
* @LastEditTime: 2022-11-01 11:05:39
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/utils.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -146,57 +146,51 @@ export const initCode = [{
}
],
"validators" : [
{
"regex" : "^.*\\.(pdb|PDB|pdbqt|PDBQT)$",
"message" : "请输入PDB或PDBQT文件"
}
]
{
"regex" : "^.*\\.(pdb|PDB|pdbqt|PDBQT)$",
"message" : "请输入PDB或PDBQT文件"
}
]
}]
export const text = `{
// 参数名, 必填, 在15字符以内,仅限大小写字母、数字、"_",且只能以大小写字母开头
// 参数名; 必填, 在15字符以内,仅限大小写字母、数字、"_",且只能以大小写字母开头
"name" : "timeout",
/** 参数类型, 必填, 可选值有 STRING:字符串、FILE:文件、DATASET:数据集、INT:整型、FLOAT:单精度浮点型、
* DOUBLE:多精度浮点型、BOOLEAN:布尔值、ARRAY_STRING:字符串数组、ARRAY_FILE:文件数组、ARRAY_DATASET:数据集数组、
* ARRAY_INT:整型数组、ARRAY_FLOAT:单精度浮点型数组、ARRAY_DOUBLE:多精度浮点型数组、ARRAY_BOOLEAN:布尔值数组
*/
"classType" : "INT",
// 是否必填。在使用该算子时是否必须输入改参数的值
// 参数类型; 必填, 可选值有 STRING:字符串、FILE:文件、DATASET:数据集、INT:整型、FLOAT:单精度浮点型、DOUBLE:多精度浮点型、BOOLEAN:布尔值、ARRAY_STRING:字符串数组、ARRAY_FILE:文件数组、ARRAY_DATASET:数据集数组、ARRAY_INT:整型数组、ARRAY_FLOAT:单精度浮点型数组、ARRAY_DOUBLE:多精度浮点型数组、ARRAY_BOOLEAN:布尔值数组
"classType" : "INT",
// 是否必填; 在使用该算子时是否必须输入改参数的值
"required" : false,
// 默认值
"defaultValue" : 10000,
// 参数描述在300字符以内
// 参数描述; 在300字符以内
"description" : "",
// 是否隐藏, 必填, 隐藏就在页面不显示该参数 必填
// 是否隐藏; 必填, 隐藏就在页面不显示该参数 必填
"hidden" : true,
// 页面展示的参数的名称 必填, 在15字符以内,仅限大小写字母、数字、中文
// 页面展示的参数的名称; 必填, 在15字符以内,仅限大小写字母、数字、中文
"title" : "",
// 参数展示的顺序优先级
"order" : 0,
// 参数分组 必填, 可选值有 in: 输入、out:输出、basis:基础、senior:高级
// 参数分组; 必填, 可选值有 in: 输入、out:输出、basis:基础、senior:高级
"parameterGroup": "in",
/**
* 前端填值的方式, 必填, 可选值有 PATH:路径选择器、DATASET:数据集选择器、FILE:文件选择器、INPUT:输入框、
* SELECT:下拉框、MULTIPLESELECT:多选下拉框、RADIO:单选按钮、CHECKBOX:多选按钮
*/
// 前端填值的方式; 必填, 可选值有 PATH:路径选择器、DATASET:数据集选择器、FILE:文件选择器、INPUT:输入框、SELECT:下拉框、MULTIPLESELECT:多选下拉框、RADIO:单选按钮、CHECKBOX:多选按钮
"domType" : "INPUT",
// 选项当domType为SELECT、MULTIPLESELECT、RADIO、CHECKBOX时生效。以对象数组的形式保存
// 选项; 当domType为SELECT、MULTIPLESELECT、RADIO、CHECKBOX时生效。以对象数组的形式保存
"choices" : [
{
// 在前端展示的值
"label" : "是",
//选中时传递服务使用的值
"value" : "true"
},
],
//用于校验输入值。以对象数组的形式保存
"validators" : [
{
//正则表达式
"regex" : "^.*\\.(pdb|PDB|pdbqt|PDBQT)$",
//不符合正则时的报错信息
"message" : "请输入PDB或PDBQT文件"
}
]
{
// 在前端展示的值
"label" : "是",
//选中时传递服务使用的值
"value" : "true"
},
],
//用于校验输入值; 以对象数组的形式保存
"validators" : [
{
//正则表达式
"regex" : "^.*\\.(pdb|PDB|pdbqt|PDBQT)$",
//不符合正则时的报错信息
"message" : "请输入PDB或PDBQT文件"
}
]
}`
\ No newline at end of file
......@@ -6,10 +6,14 @@
box-shadow: 0px 3px 12px 0px rgba(3, 47, 105, 0.09);
border-radius: 6px;
border: 2px solid #ffffff;
transition: box-shadow 0.2s cubic-bezier(0, 0, 1, 1);
}
.itemBox:hover {
box-shadow: 0px 6px 24px 0px rgba(3, 47, 105, 0.14);
}
.itemBox:hover .titleBox {
color: #1370ff;
}
.itemHeaderBox {
display: flex;
......
......@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-17 14:35:11
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-28 14:54:39
* @LastEditTime: 2022-11-01 10:59:40
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -209,9 +209,10 @@ const OperatorDetails = observer(() => {
{ label: "应用环境", value: envName },
]}
/>
{description ? (
<BasicInfo infoList={[{ label: "描述", value: description }]} />
) : null}
<BasicInfo
infoList={[{ label: "描述", value: description || "暂无描述" }]}
/>
</div>
{type === "BATCH" ? (
<div style={{ padding: "26px 0 16px 0" }}>
......
......@@ -16,3 +16,6 @@
.contentBox {
padding: 0 20px 24px;
}
.noDataHeight {
height: calc(100vh - 177px);
}
......@@ -79,7 +79,6 @@ const WorkflowOperator = observer(() => {
<div>
<SearchInput
sx={{ width: 340, marginRight: "16px" }}
placeholder="输入关键词搜索"
value={searchParams.keyword}
onKeyUp={handleKeyWordChangeKeyUp}
onChange={(e) => {
......@@ -87,11 +86,9 @@ const WorkflowOperator = observer(() => {
}}
/>
<MySelect
title="所属产品"
isTitle={true}
options={
[
{ label: "全部", value: "all" },
{ label: "全部产品", value: "all" },
...productListStore?.productList,
] || []
}
......@@ -103,14 +100,12 @@ const WorkflowOperator = observer(() => {
sx={{ width: "150px", height: "32px" }}
/>
<MySelect
title="环境类型"
isTitle={true}
value={searchParams.type}
onChange={(e) => {
setSearchParams({ ...searchParams, type: e });
}}
options={[
{ label: "全部", value: "all" },
{ label: "全部环境", value: "all" },
{
label: "批式",
value: "BATCH",
......@@ -148,7 +143,7 @@ const WorkflowOperator = observer(() => {
></CardTable>
</div>
) : (
<div style={{ height: 300 }}>
<div className={styles.noDataHeight}>
<NoData text="暂无工作流算子"></NoData>
</div>
)}
......
......@@ -40,6 +40,7 @@ const UserResources = () => {
tabList={tabList}
defaultValue={location?.state?.defaultTab || "USERRESOURCES_TEMPLATE"}
tabPanelSx={{ padding: "0" }}
navigateUrl="/utility/resourceCenter/userResources"
/>
{/* <OperatorDetails /> */}
</div>
......
import VirtuallyList from "@/components/CommonComponents/VirtuallyList";
const VirtuallyListDemo = () => {
let listData: Array<any> = [];
for (let i = 0; i < 10000; i++) {
listData.push({
name: "data" + i,
id: "data" + i,
});
}
const renderRow = ({
index,
isScrolling,
isVisible,
key,
parent,
style,
}: any) => {
// const name = listData[index].name;
// // const content = isScrolling ? "..." : <div>{name}</div>;
// const content = <div>{name}</div>;
return (
<div key={key} style={style}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
</div>
</div>
);
};
return (
<div>
<div>
<VirtuallyList list={listData} renderRow={renderRow}></VirtuallyList>;
</div>
<div style={{ width: "300px", height: "300px", overflow: "auto" }}>
{listData.map((item, index) => {
return (
<div
key={index}
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
<div>{listData[index].name}</div>
</div>
);
})}
</div>
</div>
);
};
export default VirtuallyListDemo;
......@@ -2,6 +2,7 @@ import MyTableDemo from "./MyTableDemo";
import QueueSelectDemo from "./QueueSelectDemo";
import IconfontDemo from "./IconfontDemo";
import CardTableDemo from "./CardTableDemo";
import VirtuallyListDemo from "./VirtuallyListDemo";
import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfButtonStyle";
import { useState } from "react";
import styles from "./index.module.css";
......@@ -9,6 +10,10 @@ import style from "./index.module.scss";
const Demo = () => {
const radioOptionsArr = [
{
value: "virtuallyListDemo",
label: "virtuallyListDemo",
},
{
value: "cardTable",
label: "cardTable",
......@@ -33,7 +38,7 @@ const Demo = () => {
const handleRadio = (e: string) => {
setSelectDemo(e);
};
const [selectDemo, setSelectDemo] = useState("cardTable");
const [selectDemo, setSelectDemo] = useState("virtuallyListDemo");
return (
<div className={styles.demoBox}>
......@@ -43,13 +48,15 @@ const Demo = () => {
handleRadio={handleRadio}
/>
<div className={styles.demoContentBox}>
{selectDemo === "virtuallyListDemo" && (
<VirtuallyListDemo></VirtuallyListDemo>
)}
{selectDemo === "cardTable" && <CardTableDemo></CardTableDemo>}
{selectDemo === "iconfont" && <IconfontDemo></IconfontDemo>}
{selectDemo === "队列选择器" && <QueueSelectDemo></QueueSelectDemo>}
{selectDemo === "表格" && <MyTableDemo></MyTableDemo>}
{selectDemo === "box" && <div>box</div>}
</div>
<div className={style.box}>123</div>
</div>
);
};
......
......@@ -3477,6 +3477,11 @@ cliui@^7.0.2:
strip-ansi "^6.0.0"
wrap-ansi "^7.0.0"
clsx@^1.0.4:
version "1.2.1"
resolved "https://registry.npmmirror.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
clsx@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz"
......@@ -4202,7 +4207,7 @@ dom-converter@^0.2.0:
dependencies:
utila "~0.4"
dom-helpers@^5.0.1:
dom-helpers@^5.0.1, dom-helpers@^5.1.3:
version "5.2.1"
resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
......@@ -8053,6 +8058,11 @@ react-is@^18.0.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz"
integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.npmmirror.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-refresh@^0.11.0:
version "0.11.0"
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz"
......@@ -8083,6 +8093,18 @@ react-transition-group@^4.4.2:
loose-envify "^1.4.0"
prop-types "^15.6.2"
react-virtualized@^9.22.3:
version "9.22.3"
resolved "https://registry.npmmirror.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
integrity sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==
dependencies:
"@babel/runtime" "^7.7.2"
clsx "^1.0.4"
dom-helpers "^5.1.3"
loose-envify "^1.4.0"
prop-types "^15.7.2"
react-lifecycles-compat "^3.0.4"
react@^18.1.0:
version "18.1.0"
resolved "https://registry.npmjs.org/react/-/react-18.1.0.tgz"
......
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