Commit ecdbac07 authored by chenshouchao's avatar chenshouchao

feat: 查看数据集细节、联调完成

parent 5ceeea43
......@@ -8,6 +8,7 @@ import { APIOPTION, urlToken } from "./raysyncApi";
// import UserStore from '../../../../console/common/stores/UserStore'
import { ApiUtils } from "./utils";
import Base64 from "crypto-js/enc-base64";
import { getUrlThroughParams } from "@/utils/util";
import Utf8 from "crypto-js/enc-utf8";
import { getLoaclStorageOfKey } from "./utils";
......@@ -15,6 +16,44 @@ let headers: any = {
"Content-Type": "application/json",
};
type IGetDatasetItemsListParams = {
type?: string;
projectId: string;
token: string;
filetoken: string;
path: string; // 数据集路径
name: string; // 数据集名称
page: number; //
size: number; //
query?: string; // 搜索的关键词
index?: string; // 选择的属性
sort?: string; // 排序
}
type ISaveDatasetParams = {
type?: string;
projectId: string;
token: string;
filetoken: string;
path: string; // 数据集路径
name: string; // 数据集名称
dpath: string; // 目标路径
dname: string; // 目标数据集名称
id: string; // 每个分子的index,逗号分隔
baseurl?: string; // 需要回调后台插入数据集元数据的url,比如http://47.57.4.97/)
}
type IDownloadDatasetItemsParams = {
type?: string;
projectId: string;
token: string;
filetoken: string;
path: string; // 数据集路径
name: string; // 数据集名称
id: string; // 每个分子的index,逗号分隔
downloadType: string; // 下载格式”,可选 SMILES(.smi)、SD(.sdf)、PDB(.pdb)、MOL(.mol)、MOL2(.mol2)
}
class CloudEController {
// 新建文件夹
static JobFileNewFolder(url: any, filetoken: string, projectId: string) {
......@@ -158,10 +197,6 @@ class CloudEController {
if (ApiUtils.getAuthorizationHeaders(headers)) {
url = url + urlToken(filetoken, projectId) + "&batch=true";
headers["Content-Type"] = "multipart/form-data";
// Base64.stringify(Utf8.parse(urls))
// headers["originalfilepath"] = encodeURIComponent(
// original_filepath.join(" ")
// );
headers["originalfilepath"] = Base64.stringify(
Utf8.parse(original_filepath.join(" "))
);
......@@ -193,5 +228,61 @@ class CloudEController {
document.body.removeChild(div);
}
}
// 获取分子列表
static GetDatasetItemsList(params: IGetDatasetItemsListParams) {
if (ApiUtils.getAuthorizationHeaders(headers)) {
headers["Cache-Control"] = "no-cache";
let url = getUrlThroughParams(params, ['filetoken','path','token'], '?')
return axios.get(
`${APIOPTION()}:5003/find/dataset${url}`,
{
headers: headers,
}
);
}
}
// 分子另存为
static SaveDataset(params: ISaveDatasetParams) {
if (ApiUtils.getAuthorizationHeaders(headers)) {
headers["Cache-Control"] = "no-cache";
let url = getUrlThroughParams(params, ['filetoken','path','token','dpath'], '?')
return axios.post(`${APIOPTION()}:5003/save${url}`,{}, {
headers: headers,
});
}
}
// 数据集分子下载
static DownloadDatasetItems(params: IDownloadDatasetItemsParams) {
if (ApiUtils.getAuthorizationHeaders(headers)) {
headers["Cache-Control"] = "no-cache";
let url = getUrlThroughParams(params, ['filetoken','path','token'], '?')
return axios.get(
`${APIOPTION()}:5003/download${url}`,
{
headers: headers,
}
);
}
}
// 生成文件并下载
static FunDownload(content: string, filename: string) {
// 创建隐藏的可下载链接
let eleLink = document.createElement('a');
eleLink.download = filename;
eleLink.style.display = 'none';
// 字符内容转变成blob地址
let blob = new Blob([content]);
eleLink.href = URL.createObjectURL(blob);
// 触发点击
document.body.appendChild(eleLink);
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
}
}
export default CloudEController;
......@@ -45,6 +45,19 @@ const FileSelect = observer((props: FileSelectProps) => {
const [dataSetList, setDataSetList] = useState<any>([]);
const [keyWord, setKeyWord] = useState("");
// 弹窗标题
const dialogTitle = useMemo(() => {
if (type === "dataset") {
return "数据集选择器";
} else if (type === "file") {
return "文件选择器";
} else if (type === "path") {
return "路径选择器";
} else {
return "路径选择器";
}
}, [type]);
// 点击确认时返回的路径
const resultPath = useMemo(() => {
if (keyWord) {
......@@ -68,7 +81,6 @@ const FileSelect = observer((props: FileSelectProps) => {
}
}
}, [path, selectFileName, keyWord, selectItem, type]);
console.log("resultPath", resultPath);
const fileSelectOnConfirm = () => {
if (type === "file") {
......@@ -415,7 +427,7 @@ const FileSelect = observer((props: FileSelectProps) => {
open={props.open}
onClose={props.onClose}
onConfirm={fileSelectOnConfirm}
title="文件选择器"
title={dialogTitle}
>
<div className={style.FSBox}>
<div className={style.FSTop}>
......
......@@ -53,7 +53,7 @@ const KekuleView = (props: IKekuleViewProps) => {
.setChemObj(molecule);
chemViewer.setEnableToolbar(toolbar);
chemViewer.setAutofit(true);
chemViewer.setPadding(16);
chemViewer.setPadding(26);
chemViewer.setEnableDirectInteraction(false);
} catch (err) {
console.log(err);
......
......@@ -54,6 +54,7 @@ export default function MySelect(props: IProps) {
variant = "outlined",
multiple = false,
onChange,
fullWidth,
...other
} = props;
......@@ -93,7 +94,7 @@ export default function MySelect(props: IProps) {
MuiInputLabel: {
styleOverrides: {
root: {
top: "-9px",
// top: "-9px",
},
},
},
......@@ -115,7 +116,7 @@ export default function MySelect(props: IProps) {
return (
<ThemeProvider theme={theme}>
<FormControl fullWidth variant={variant}>
<FormControl fullWidth={fullWidth} variant={variant}>
{isTitle ? (
<InputLabel id="demo-simple-select-label">
{title || "请选择"}
......@@ -132,9 +133,13 @@ export default function MySelect(props: IProps) {
onChange={handleChange}
>
{options.length
? options?.map((item: IOption) => {
? options?.map((item: IOption, index) => {
return (
<MenuItem value={item.value} disabled={item?.disabled}>
<MenuItem
value={item.value}
disabled={item?.disabled}
key={index}
>
{item.label}
</MenuItem>
);
......
......@@ -93,3 +93,23 @@ export const storageUnitFromB = (b: number) => {
return `${(b / (1024 * 1024 * 1024 * 1024)).toFixed(2)}t`;
}
};
// 从本地缓存拿token
export const getToken = (): string => {
return JSON.parse(localStorage.getItem('token_key') || "{}")?.access_token || ''
}
// 请求地址拼接 没值的不拼接 需要转义的通过encodeURIComponent转义
export const getUrlThroughParams = (params: any, encodeArr: Array<string> = [], initUrl= ''):string => { // params 是要穿的参数 是个对象 encodeArr 需要通过encodeURIComponent转换的字段数组
let url = initUrl
Object.keys(params).forEach((item: string, index) => {
if (params[item]) {
let value = params[item]
if (encodeArr.some(encodeItem => encodeItem = item)) {
value = encodeURIComponent(params[item])
}
url += `${index === 0 ? '' : '&'}${item}=${value}`
}
})
return url
}
import React, { useState } from "react";
import MyDialog from "@/components/mui/MyDialog";
import { useMessage } from "@/components/MySnackbar";
import CloudEController from "@/api/fileserver/CloudEController";
import MySelect from "@/components/mui/MySelect";
type IDownloadProps = {
type: string;
projectId: string;
token: string;
fileToken: string;
path: string;
name: string;
selectIds: Array<any>;
open: boolean;
setOpen: any;
};
const flieTypeMap = {
SMILES: ".smi",
SD: ".sdf",
PDB: ".pdb",
MOL: ".mol",
MOL2: ".mol2",
};
const Download = (props: IDownloadProps) => {
const {
type,
path,
projectId,
token,
fileToken,
selectIds,
name,
open,
setOpen,
} = props;
const Message = useMessage();
const [downloadType, setDownloadType] = useState("SMILES");
const options = [
{
label: "SMILES",
value: "SMILES",
},
{
label: "SD",
value: "SD",
},
{
label: "PDB",
value: "PDB",
},
{
label: "MOL",
value: "MOL",
},
{
label: "MOL2",
value: "MOL2",
},
];
const handleChange = (e: any) => {
setDownloadType(e);
};
const handleSubmit = () => {
CloudEController.DownloadDatasetItems({
type: type,
projectId: projectId,
token: token,
filetoken: fileToken,
name: name,
path: path,
id: selectIds.join(","),
downloadType: downloadType,
})
?.then((res) => {
// @ts-ignore
const filename = `${name}${flieTypeMap[downloadType]}`;
CloudEController.FunDownload(res.data, filename);
setOpen(false);
})
?.catch((error) => {
console.log(error);
Message.error(error?.response?.data?.message || "文件服务发生错误!");
});
};
return (
<>
<MyDialog
open={open}
onClose={() => setOpen(false)}
onConfirm={handleSubmit}
title="下载"
>
<div style={{ padding: "20px 0" }}>
<MySelect
value={downloadType}
options={options}
onChange={(e) => handleChange(e)}
// fullWidth={true}
title="下载格式"
isTitle={true}
sx={{
width: "388px",
}}
></MySelect>
</div>
</MyDialog>
</>
);
};
export default Download;
......@@ -7,6 +7,9 @@
justify-content: flex-start;
height: 100%;
}
.datasetBoxShowFoot {
padding-bottom: 64px;
}
.top {
margin-bottom: 20px;
}
......@@ -57,6 +60,8 @@
border-radius: 4px;
min-height: 275px;
box-sizing: border-box;
position: relative;
cursor: pointer;
}
.datasetLi:nth-child(4n) {
margin-right: 0;
......@@ -91,11 +96,22 @@
font-size: 14px;
text-align: center;
font-weight: 600;
width: 100%;
overflow: hidden;
}
.datasetLiDataList {
flex: 1;
overflow: auto;
}
.noDataList {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
color: rgba(138, 144, 153, 1);
font-size: 14px;
line-height: 22px;
}
.datasetLiDataLi {
height: 20px;
line-height: 20px;
......
import FullScreenDrawer from "@/components/CommonComponents/FullScreenDrawer";
import { useState, useMemo } from "react";
import { useState, useMemo, useCallback, useEffect } from "react";
import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfButtonStyle";
import MyMultipleMenu, { IOption } from "@/components/mui/MyMultipleMenu";
import MySelect from "../../ProjectSubmitWork/components/MySelect";
import MySelect from "@/components/mui/MySelect";
import MyInput from "@/components/mui/MyInput";
import ButtonComponent from "@/components/mui/MyButton";
import SearchIcon from "@mui/icons-material/Search";
import MyPagination from "@/components/mui/MyPagination";
import NglView from "@/components/BusinessComponents/NglView";
import KekuleView from "@/components/BusinessComponents/KekuleView";
import Checkbox from "@mui/material/Checkbox";
import CloudEController from "@/api/fileserver/CloudEController";
import { getToken } from "@/utils/util";
import { observer } from "mobx-react-lite";
import { useStores } from "@/store";
import { toJS } from "mobx";
import classNames from "classnames";
import Save from "./save";
import Download from "./download";
import style from "./index.module.css";
type ISeeDatasetProps = {
......@@ -23,154 +28,48 @@ type ISeeDatasetProps = {
name: string;
};
const contentDataMock = `REMARK VINA RESULT: -6.039 0.000 0.000
REMARK INTER + INTRA: -7.654
REMARK INTER: -7.995
REMARK INTRA: 0.341
REMARK UNBOUND: -0.203
REMARK SMILES CN1C(=O)c2ccc(N3C(=O)c4ccc(Oc5ccc([N+](=O)[O-])cc5)cc4C3=O)cc2C1=O
REMARK SMILES IDX 16 1 15 4 11 5 10 6 12 9 9 10 13 11 27 12 28 13 14 14 26 15
REMARK SMILES IDX 29 16 8 19 7 20 30 21 6 22 31 23 5 24 32 25 3 26 33 27 2 28
REMARK SMILES IDX 4 29 1 32 17 35 18 36 25 37 19 38 24 39 20 40 21 41 22 42
REMARK SMILES IDX 23 43
REMARK H PARENT
REMARK Flexibility Score: inf
COMPND UNNAMED
AUTHOR GENERATED BY OPEN BABEL 3.1.0
ATOM 1 O LIG 1 6.958 5.187 16.199 1.00 0.00 O
ATOM 2 WAT LIG 1 7.927 4.962 13.368 1.00 0.00 W
ATOM 3 WAT LIG 1 6.361 7.884 17.368 1.00 0.00 W
ATOM 4 C LIG 1 8.006 4.700 16.965 1.00 0.00 C
ATOM 5 O LIG 1 11.909 3.392 19.972 1.00 0.00 O
ATOM 6 C LIG 1 10.833 2.980 19.589 1.00 0.00 C
ATOM 7 WAT LIG 1 13.514 1.792 21.938 1.00 0.00 W
ATOM 8 WAT LIG 1 12.959 6.013 18.958 1.00 0.00 W
ATOM 9 C LIG 1 9.994 3.706 18.630 1.00 0.00 C
ATOM 10 N LIG 1 10.171 1.809 19.872 1.00 0.00 N
ATOM 11 C LIG 1 10.225 4.905 17.988 1.00 0.00 C
ATOM 12 C LIG 1 8.832 2.986 18.430 1.00 0.00 C
ATOM 13 C LIG 1 8.954 1.750 19.224 1.00 0.00 C
ATOM 14 C LIG 1 9.212 5.403 17.165 1.00 0.00 C
ATOM 15 C LIG 1 7.811 3.462 17.610 1.00 0.00 C
ATOM 16 O LIG 1 8.080 0.907 19.285 1.00 0.00 O
ATOM 17 WAT LIG 1 8.484 -1.556 20.949 1.00 0.00 W
ATOM 18 WAT LIG 1 5.518 1.290 17.771 1.00 0.00 W
ATOM 19 C LIG 1 10.690 0.788 20.704 1.00 0.00 C
ATOM 20 C LIG 1 10.990 1.073 22.059 1.00 0.00 C
ATOM 21 C LIG 1 10.894 -0.512 20.209 1.00 0.00 C
ATOM 22 C LIG 1 11.467 0.078 22.930 1.00 0.00 C
ATOM 23 C LIG 1 11.413 -1.466 21.079 1.00 0.00 C
ATOM 24 C LIG 1 11.677 -1.183 22.406 1.00 0.00 C
ATOM 25 C LIG 1 11.784 -2.870 20.853 1.00 0.00 C
ATOM 26 C LIG 1 12.163 -2.413 23.041 1.00 0.00 C
ATOM 27 O LIG 1 11.755 -3.417 19.771 1.00 0.00 O
ATOM 28 N LIG 1 12.172 -3.374 22.066 1.00 0.00 N
ATOM 29 O LIG 1 12.481 -2.503 24.210 1.00 0.00 O
ATOM 30 WAT LIG 1 12.552 -6.299 19.526 1.00 0.00 W
ATOM 31 WAT LIG 1 10.885 -1.889 17.340 1.00 0.00 W
ATOM 32 C LIG 1 12.561 -4.748 22.299 1.00 0.00 C
ATOM 33 WAT LIG 1 13.453 -5.123 25.301 1.00 0.00 W
ATOM 34 WAT LIG 1 12.296 -0.106 26.005 1.00 0.00 W
ATOM 35 C LIG 1 5.741 4.530 16.202 1.00 0.00 C
ATOM 36 C LIG 1 5.748 3.131 16.178 1.00 0.00 C
ATOM 37 C LIG 1 4.519 5.215 16.142 1.00 0.00 C
ATOM 38 C LIG 1 4.542 2.418 16.098 1.00 0.00 C
ATOM 39 C LIG 1 3.309 4.512 16.150 1.00 0.00 C
ATOM 40 C LIG 1 3.324 3.112 16.136 1.00 0.00 C
ATOM 41 N LIG 1 2.059 2.366 16.222 1.00 0.00 N
ATOM 42 O LIG 1 1.977 1.297 15.600 1.00 0.00 O
ATOM 43 O LIG 1 1.160 2.836 16.934 1.00 0.00 O
ATOM 44 WAT LIG 1 -0.556 -0.307 15.704 1.00 0.00 W
ATOM 45 WAT LIG 1 4.310 0.313 13.991 1.00 0.00 W
ATOM 46 WAT LIG 1 -1.462 1.400 17.183 1.00 0.00 W
ATOM 47 WAT LIG 1 1.606 5.411 18.407 1.00 0.00 W
CONECT 1 35 4
CONECT 4 1 14 14 15
CONECT 5 6 6
CONECT 6 9 10 5 5
CONECT 7 20
CONECT 9 11 11 12 6
CONECT 10 13 6 19
CONECT 11 14 9 9
CONECT 12 15 15 9 13
CONECT 13 12 16 16 10
CONECT 14 4 4 11
CONECT 15 4 12 12
CONECT 16 13 13
CONECT 17 21
CONECT 18 38
CONECT 19 10 21 21 20
CONECT 20 19 7 22 22
CONECT 21 19 19 17 23
CONECT 22 20 20 24
CONECT 23 21 25 24 24
CONECT 24 23 23 22 26
CONECT 25 27 27 23 28
CONECT 26 28 24 29 29
CONECT 27 25 25
CONECT 28 25 32 26
CONECT 29 26 26
CONECT 32 28
CONECT 35 37 37 36 1
CONECT 36 38 38 35
CONECT 37 39 35 35
CONECT 38 40 36 36 18
CONECT 39 40 40 37
CONECT 40 38 39 39 41
CONECT 41 42 42 40 43
CONECT 41 43
CONECT 42 41 41
CONECT 43 41 41
CONECT 44 46 46 46
CONECT 46 44 44 44
MASTER 0 0 0 0 0 0 0 0 47 0 47 0`;
const dataTypesMock = [
{
label: "123",
value: "1234",
},
{
label: "1232",
value: "12342",
},
{
label: "1233",
value: "12344",
},
];
const SeeDataset = observer((props: ISeeDatasetProps) => {
const { path, name, fileToken, projectId } = props;
const { currentProjectStore } = useStores();
const productName = toJS(currentProjectStore.currentProductInfo.name); // chan
// const projectId = toJS(currentProjectStore.currentProjectInfo.id);
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品id 如:cadd
const token = getToken();
const [graphicDimension, setGraphicDimension] = useState("2D"); // 分子结构图是2D还是3D
const [showData, setShowData] = useState<Array<string>>([]); //显示的数据类型
const [dataTypes, setdataTypes] = useState<Array<IOption>>(dataTypesMock); // 可选的数据类型
const [dataTypes, setdataTypes] = useState<Array<IOption>>([]); // 可选的数据类型
const [sort, setSort] = useState("null"); // 排序方式
const [keyword, setKeyword] = useState(""); // 关键字
const [searchDataType, setSearchDataType] = useState<string>(""); //显示的数据类型
const [searchDataType, setSearchDataType] = useState<any>(null); // 搜索的数据属性
const [page, setPage] = useState(1); // 当前页码
const size = 8; // 每页数量
const [count, setCount] = useState(1); // 总页数
const [list, setList] = useState<Array<any>>([]); // 分子列表
const [selectItems, setSelectItems] = useState<Array<any>>([]);
const [saveOpen, setSaveOpen] = useState(false); // 另存为弹窗显示控制
const [downloadOpen, setDownloadOpen] = useState(false); // 下载弹窗显示控制
const isCadd = useMemo(() => {
if (productId === "cadd") {
return true;
} else {
return false;
}
}, [productId]);
const handleSearchDataTypeChange = (e: any) => {
setSearchDataType(e.target.value);
setSearchDataType(e);
};
const handleSortChange = (e: any) => {
console.log(e);
setSort(e.target.value);
setSort(e);
};
const handleKeywordChange = (e: any) => {
console.log(e);
setKeyword(e.target.value);
};
const list = [1, 2, 3, 2, 1, 45, 7];
// const list = [1];
const pageChange = (value: number) => {
setPage(value);
};
// 空盒子用于布局
const nullBox = useMemo(() => {
if (list.length > 4) {
let nullBoxLength = 8 - list.length;
......@@ -180,30 +79,99 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
}
}, [list]);
console.log(nullBox);
// 获取分子列表
const getList = useCallback(
(paramsPage = 1) => {
setPage(paramsPage);
CloudEController.GetDatasetItemsList({
type: productId as string,
projectId: projectId as string,
token: token,
filetoken: fileToken as string,
path: path,
name: name,
page: paramsPage,
size,
index: searchDataType ? `meta.${searchDataType}` : "",
sort: sort === "null" ? "" : sort,
query: keyword,
})?.then((res) => {
setList(res.data.list);
setCount(res.data.totalPage);
if (res.data.list) {
if (res.data.list[0].meta) {
const meta = res.data.list[0].meta;
const arr = Object.keys(meta).map((item) => {
return { label: item, value: item };
});
setdataTypes(arr);
setSearchDataType(arr[0].value);
} else {
setdataTypes([]);
}
} else {
setdataTypes([]);
}
});
},
[
productId,
projectId,
token,
fileToken,
path,
name,
searchDataType,
sort,
keyword,
]
);
useEffect(() => {
getList(page);
}, [page]);
// 选择/取消分子
const handleSelectItem = (id: string) => {
let list: string[] = [...selectItems];
if (selectItems.filter((e) => e === id).length > 0) {
list = list.filter((e) => e !== id);
setSelectItems(list);
} else {
list.push(id);
setSelectItems(list);
}
};
return (
<FullScreenDrawer handleClose={props.handleClose}>
<div className={style.datasetBox}>
<div
className={classNames({
[style.datasetBox]: true,
[style.datasetBoxShowFoot]: true,
})}
>
<div className={style.top}>
<div className={style.title}>数据集title</div>
<div className={style.title}>{name}</div>
<div className={style.screens}>
<div className={style.screensLeft}>
<RadioGroupOfButtonStyle
handleRadio={setGraphicDimension}
value={graphicDimension}
radioOptions={[
{
value: "2D",
label: "2D",
},
{
value: "3D",
label: "3D",
},
]}
RadiosBoxStyle={{ width: "132px" }}
></RadioGroupOfButtonStyle>
{isCadd && (
<RadioGroupOfButtonStyle
handleRadio={setGraphicDimension}
value={graphicDimension}
radioOptions={[
{
value: "2D",
label: "2D",
},
{
value: "3D",
label: "3D",
},
]}
RadiosBoxStyle={{ width: "132px" }}
></RadioGroupOfButtonStyle>
)}
<MyMultipleMenu
value={showData}
options={dataTypes}
......@@ -218,13 +186,15 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
<div className={style.screensRight}>
<MySelect
options={dataTypes}
placeholder="选择属性"
title="选择属性"
isTitle={true}
value={searchDataType}
onChange={handleSearchDataTypeChange}
fullWidth={false}
sx={{
width: "160px",
marginRight: "16px",
height: "32px",
}}
></MySelect>
<MySelect
......@@ -235,11 +205,11 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
},
{
label: "正序",
value: "1",
value: "ASC",
},
{
label: "倒序",
value: "2",
value: "DESC",
},
]}
title="排序方式"
......@@ -250,6 +220,7 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
sx={{
width: "160px",
marginRight: "16px",
height: "32px",
}}
></MySelect>
<MyInput
......@@ -263,11 +234,15 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
sx={{
width: "340px",
marginRight: "16px",
height: "32px",
}}
></MyInput>
<ButtonComponent
text="确认"
style={{ width: "68px" }}
onClick={() => {
getList();
}}
></ButtonComponent>
</div>
</div>
......@@ -276,42 +251,81 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
<div className={style.list}>
{list.map((item, index) => {
return (
<div className={style.datasetLi} key={index}>
<div className={style.datasetLiTop}>
{graphicDimension === "2D" && (
<KekuleView
id={`${index}2d`}
smi="COc1ccc(c(c1)N(=O)=O)NC(=O)CSc1nc2c([nH]1)cccc2"
/>
)}
{graphicDimension === "3D" && (
<NglView id={`${index}3d`} content={contentDataMock} />
)}
</div>
<div
className={style.datasetLi}
key={item.id}
onClick={() => {
handleSelectItem(item.id);
}}
>
{isCadd && (
<div className={style.datasetLiTop}>
{graphicDimension === "2D" && (
<KekuleView id={`${index}2d`} smi={item.smiles} />
)}
{graphicDimension === "3D" && (
<NglView id={`${index}3d`} content={item.pdb} />
)}
</div>
)}
<div className={style.datasetLiBottom}>
<div className={style.datasetLiTitle}>12314SAS</div>
<div className={style.datasetLiDataList}>
<div className={style.datasetLiDataLi}>
<span className={style.datasetLiDataLiKey}>
1asdfjasg123454356245421zdg5s456s4fg878gasd5g74a877h8a7dfh8sa4dfh56s4dfh54adf56ha4df56h456adfhf23
</span>
<span className={style.datasetLiDataLiValue}>45</span>
</div>
<div className={style.datasetLiDataLi}>
<span className={style.datasetLiDataLiKey}>123</span>
<span className={style.datasetLiDataLiValue}>45</span>
</div>
<div className={style.datasetLiDataLi}>
<span className={style.datasetLiDataLiKey}>123</span>
<span className={style.datasetLiDataLiValue}>45</span>
</div>
<div className={style.datasetLiDataLi}>
<span className={style.datasetLiDataLiKey}>123</span>
<span className={style.datasetLiDataLiValue}>45</span>
</div>
<div className={style.datasetLiTitle} title={item.smiles}>
{item.smiles}
</div>
{showData.length !== 0 && (
<div className={style.datasetLiDataList}>
{Object.keys(item.meta)
.filter((key) => showData.indexOf(key) !== -1)
.map((key, index) => {
return (
<div
className={style.datasetLiDataLi}
key={index}
>
<span className={style.datasetLiDataLiKey}>
{key}
</span>
<span className={style.datasetLiDataLiValue}>
{item.meta[key]}
</span>
</div>
);
})}
</div>
)}
{showData.length === 0 && (
<div className={style.noDataList}>请选择显示数据</div>
)}
</div>
{graphicDimension === "2D" && (
<Checkbox
size="small"
sx={{
padding: "0px",
position: "absolute",
top: "16px",
right: "20px",
zIndex: 1,
}}
checked={selectItems.includes(item.id)}
/>
)}
{graphicDimension === "3D" && (
<Checkbox
size="small"
sx={{
padding: "0px",
position: "absolute",
top: "16px",
right: "20px",
zIndex: 1,
background: "RGBA(30, 38, 51, 1)",
border: "1px solid #565C66",
borderRadius: "2px",
}}
checked={selectItems.includes(item.id)}
/>
)}
</div>
);
})}
......@@ -332,14 +346,48 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
</div>
</div>
</div>
{/* <div className={style.foot}>
<div className={style.foot}>
{isCadd && (
<ButtonComponent
variant="outlined"
text={`下载(${selectItems.length})`}
style={{ marginRight: "12px" }}
disabled={selectItems.length === 0}
onClick={() => setDownloadOpen(true)}
></ButtonComponent>
)}
<ButtonComponent
variant="outlined"
text="下载"
style={{ marginRight: "12px" }}
disabled={selectItems.length === 0}
text={`另存为(${selectItems.length})`}
onClick={() => setSaveOpen(true)}
></ButtonComponent>
<ButtonComponent text="另存为"></ButtonComponent>
</div> */}
</div>
{saveOpen && (
<Save
type={productId as string}
projectId={projectId}
token={token}
fileToken={fileToken}
path={path}
name={name}
selectIds={selectItems}
open={saveOpen}
setOpen={setSaveOpen}
></Save>
)}
{downloadOpen && (
<Download
type={productId as string}
projectId={projectId}
token={token}
fileToken={fileToken}
path={path}
name={name}
selectIds={selectItems}
open={downloadOpen}
setOpen={setDownloadOpen}
></Download>
)}
</FullScreenDrawer>
);
});
......
import { useState, useEffect, useMemo } from "react";
import MyDialog from "@/components/mui/MyDialog";
import { checkIsNumberLetterChinese } from "@/utils/util";
import { useMessage } from "@/components/MySnackbar";
import CloudEController from "@/api/fileserver/CloudEController";
import FileSelect from "@/components/BusinessComponents/FileSelect";
import fileSelectIcon from "@/assets/project/fileSelect.svg";
import MyInput from "@/components/mui/MyInput";
import { BACKEND_API_URI_PREFIX } from "@/api/api_prefix";
import InputAdornment from "@mui/material/InputAdornment";
type ISaveProps = {
type: string;
projectId: string;
token: string;
fileToken: string;
path: string;
name: string;
selectIds: Array<any>;
open: boolean;
setOpen: any;
};
const Save = (props: ISaveProps) => {
const {
type,
path,
projectId,
token,
fileToken,
selectIds,
name,
open,
setOpen,
} = props;
const Message = useMessage();
const [dname, setDname] = useState("");
const [dpath, setDpath] = useState("/");
const [fileSelectOpen, setFileSelectOpen] = useState(false);
const [datasetNameCheck, setDatasetNameCheck] = useState({
error: false,
help: "",
});
const [dpathCheck, setDpathCheck] = useState({
error: false,
help: "",
});
useEffect(() => {
if (open) {
setDname("");
setDatasetNameCheck({
error: false,
help: "",
});
}
}, [open]);
const showDpath = useMemo(() => {
return `ProjectData${dpath === "/" ? "" : dpath}`;
}, [dpath]);
const handleSaveSubmit = () => {
if (dname && !datasetNameCheck.error && dpath) {
CloudEController.SaveDataset({
type: type,
projectId: projectId,
token: token,
filetoken: fileToken,
name: name,
path: path,
dpath: dpath,
dname: dname,
id: selectIds.join(","),
baseurl: BACKEND_API_URI_PREFIX,
})
?.then((res) => {
Message.success("另存为成功!");
setOpen(false);
})
?.catch((error) => {
console.log(error);
Message.error(error?.response?.data?.message || "文件服务发生错误!");
});
} else {
if (!dpath) {
setDpathCheck({
error: true,
help: "请选择另存为路径",
});
} else {
setDpathCheck({
error: false,
help: "",
});
}
if (!dname) {
setDatasetNameCheck({
error: true,
help: "数据集名称不能为空",
});
}
}
};
const handleDnameChange = (e: any) => {
const dname = e.target.value;
setDname(dname);
if (!dname) {
setDatasetNameCheck({
error: true,
help: "数据集名称不能为空",
});
} else if (!checkIsNumberLetterChinese(dname) || dname.length > 30) {
setDatasetNameCheck({
error: true,
help: "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文",
});
} else {
setDatasetNameCheck({
error: false,
help: "",
});
}
};
const onFileSelectConfirm = (path: string) => {
setFileSelectOpen(false);
setDpath(path);
};
return (
<>
<MyDialog
open={open}
onClose={() => setOpen(false)}
onConfirm={handleSaveSubmit}
title="另存为"
>
<MyInput
sx={{
width: "388px",
display: "block",
margin: "20px 0",
}}
required
error={datasetNameCheck.error}
label="数据集名称"
variant="outlined"
value={dname}
onChange={handleDnameChange}
helperText={datasetNameCheck.help}
InputProps={{
endAdornment: (
<InputAdornment position="end">{dname.length}/30</InputAdornment>
),
}}
size="small"
/>
<MyInput
sx={{
width: "388px",
}}
value={showDpath}
required
label="保存路径"
InputProps={{
endAdornment: (
<img
onClick={() => {
setFileSelectOpen(true);
}}
src={fileSelectIcon}
alt="选择输出路径"
style={{ cursor: "pointer" }}
/>
),
}}
error={dpathCheck.error}
helperText={dpathCheck.help}
></MyInput>
{fileSelectOpen && (
<FileSelect
onClose={() => {
setFileSelectOpen(false);
}}
open={fileSelectOpen}
onConfirm={onFileSelectConfirm}
/>
)}
</MyDialog>
</>
);
};
export default Save;
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