302 lines
10 KiB
TypeScript
302 lines
10 KiB
TypeScript
import { Button, FormItem, ScopedContext, Table } from 'amis';
|
|
import { FormControlProps } from 'amis/lib/renderers/Form/Item';
|
|
import React from 'react';
|
|
|
|
@FormItem({
|
|
test: /(^|\/)dataset\-picker$/,
|
|
name: 'dataset-picker',
|
|
})
|
|
export class DataestRenderer extends React.Component<
|
|
FormControlProps,
|
|
{
|
|
source: any;
|
|
breadcrumb: any;
|
|
hash: any;
|
|
showDialog: any;
|
|
}
|
|
> {
|
|
static contextType = ScopedContext;
|
|
|
|
constructor(props: FormControlProps) {
|
|
super(props);
|
|
this.state = {
|
|
source: [],
|
|
breadcrumb: ['根目录'],
|
|
hash: '',
|
|
showDialog: false,
|
|
};
|
|
}
|
|
|
|
fetchSource(prefix) {
|
|
if (prefix === '/') {
|
|
return new Promise((resolve, reject) => {
|
|
this.props.env
|
|
.resFetcher({
|
|
method: 'get',
|
|
url: '/res/api/shares',
|
|
})
|
|
.then((res) => resolve(res))
|
|
.catch((err) => reject(err));
|
|
});
|
|
} else {
|
|
return new Promise((resolve, reject) => {
|
|
this.props.env
|
|
.resFetcher({
|
|
method: 'get',
|
|
url: `/res/api/resources/${prefix}`,
|
|
})
|
|
.then((res) => resolve(res))
|
|
.catch((err) => reject(err));
|
|
});
|
|
}
|
|
}
|
|
|
|
async setSource(prefix) {
|
|
const result: any = await this.fetchSource(prefix);
|
|
const source =
|
|
prefix === '/'
|
|
? result.data.data
|
|
.filter((item) => !item.password_hash)
|
|
.map((item) => {
|
|
return {
|
|
...item,
|
|
name: item.path.replaceAll(/^\/|\/$/g, ''),
|
|
mimetype:
|
|
item.path[item.path.length - 1] === '/' ? '文件夹' : null,
|
|
};
|
|
})
|
|
: result.data.data.items.map((item) => {
|
|
return {
|
|
...item,
|
|
mimetype: item.isDir ? '文件夹' : item.type,
|
|
updated_at: item.modified.slice(0, 16).replace('T', ' '),
|
|
};
|
|
});
|
|
|
|
this.setState({ source });
|
|
}
|
|
|
|
getPath(breadcrumb, n) {
|
|
return breadcrumb.slice(n).toString().replaceAll(',', '/');
|
|
}
|
|
|
|
componentWillMount() {
|
|
const scoped = this.context;
|
|
scoped.registerComponent(this);
|
|
}
|
|
|
|
async componentDidMount() {
|
|
this.setSource('/');
|
|
}
|
|
|
|
componentDidUpdate(prevProps: any, prevState: any, snapshot: any) {
|
|
if (
|
|
JSON.stringify(prevState.breadcrumb) !==
|
|
JSON.stringify(this.state.breadcrumb)
|
|
) {
|
|
this.reload();
|
|
}
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
const scoped = this.context;
|
|
scoped.unRegisterComponent(this);
|
|
}
|
|
|
|
reload() {
|
|
this.setSource(`${this.getPath(this.state.breadcrumb, 1)}/`);
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<>
|
|
<Button
|
|
level="warning"
|
|
size="sm"
|
|
onClick={() => this.setState({ showDialog: true })}
|
|
>
|
|
目标选取
|
|
</Button>
|
|
{this.state.showDialog ? (
|
|
<div
|
|
id="dialog"
|
|
className="amis-dialog-widget cxd-Modal cxd-Modal--1th"
|
|
>
|
|
<div className="cxd-Modal-overlay in"></div>
|
|
<div className="cxd-Modal-content in">
|
|
<div className="cxd-Modal-header">
|
|
<div className="cxd-Modal-title">目标选取</div>
|
|
</div>
|
|
<div className="cxd-Modal-body">
|
|
<div
|
|
style={{ display: 'flex', justifyContent: 'space-between' }}
|
|
>
|
|
<span>
|
|
{this.state.breadcrumb.map((item, index) => {
|
|
if (index) {
|
|
if (index === this.state.breadcrumb.length - 1) {
|
|
return <span key={`${index}-${item}`}>/{item}</span>;
|
|
}
|
|
|
|
return (
|
|
<span key={`${index}-${item}`}>
|
|
/
|
|
<a
|
|
onClick={() => {
|
|
let temp_breadcrumb = JSON.parse(
|
|
JSON.stringify(this.state.breadcrumb)
|
|
);
|
|
temp_breadcrumb = temp_breadcrumb.slice(
|
|
0,
|
|
index + 1
|
|
);
|
|
this.setState({ breadcrumb: temp_breadcrumb });
|
|
}}
|
|
>
|
|
{item}
|
|
</a>
|
|
</span>
|
|
);
|
|
} else {
|
|
if (index === this.state.breadcrumb.length - 1) {
|
|
return <span key={`${index}-${item}`}>{item}</span>;
|
|
}
|
|
|
|
return (
|
|
<a
|
|
key={`${index}-${item}`}
|
|
onClick={() => {
|
|
let temp_breadcrumb = JSON.parse(
|
|
JSON.stringify(this.state.breadcrumb)
|
|
);
|
|
temp_breadcrumb = temp_breadcrumb.slice(
|
|
0,
|
|
index + 1
|
|
);
|
|
this.setState({ breadcrumb: temp_breadcrumb });
|
|
}}
|
|
>
|
|
{item}
|
|
</a>
|
|
);
|
|
}
|
|
})}
|
|
</span>
|
|
</div>
|
|
<Table
|
|
className={`m-t-xs`}
|
|
dataSource={this.state.source}
|
|
columns={[
|
|
{
|
|
title: '名称',
|
|
render: (item, rowData, rowIndex, i) => {
|
|
return {
|
|
props: { rowSpan: 1, colSpan: 1 },
|
|
children: (
|
|
<div key={`${rowIndex}-${rowData.name}`}>
|
|
{rowData.isDir ||
|
|
rowData.mimetype === '文件夹' ? (
|
|
<Button
|
|
level="link"
|
|
size="sm"
|
|
onClick={() => {
|
|
let temp_breadcrumb = JSON.parse(
|
|
JSON.stringify(this.state.breadcrumb)
|
|
);
|
|
|
|
temp_breadcrumb.push(rowData.name);
|
|
this.setState({
|
|
breadcrumb: temp_breadcrumb,
|
|
});
|
|
|
|
if (rowData.hash)
|
|
this.setState({
|
|
hash: rowData.hash,
|
|
});
|
|
}}
|
|
>
|
|
{rowData.name}
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
level="link"
|
|
size="sm"
|
|
className={`m-l-xs`}
|
|
onClick={() => {
|
|
const prefix = this.getPath(
|
|
this.state.breadcrumb,
|
|
2
|
|
);
|
|
const path = rowData.hash
|
|
? `${rowData.hash}`
|
|
: prefix
|
|
? `${this.state.hash}/${prefix}/${rowData.name}`
|
|
: `${this.state.hash}/${rowData.name}`;
|
|
this.props.onChange(path);
|
|
this.setState({ showDialog: false });
|
|
}}
|
|
>
|
|
{rowData.name}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
),
|
|
};
|
|
},
|
|
},
|
|
{
|
|
title: '类型',
|
|
render: (item, rowData, rowIndex, i) => {
|
|
return {
|
|
props: { rowSpan: 1, colSpan: 1 },
|
|
children: (
|
|
<div key={`${rowIndex}-${rowData.mimetype}`}>
|
|
{rowData.mimetype}
|
|
</div>
|
|
),
|
|
};
|
|
},
|
|
},
|
|
{
|
|
title: '大小',
|
|
render: (item, rowData, rowIndex, i) => {
|
|
return {
|
|
props: { rowSpan: 1, colSpan: 1 },
|
|
children: (
|
|
<div key={`${rowIndex}-${rowData.size}`}>
|
|
{rowData.size}
|
|
</div>
|
|
),
|
|
};
|
|
},
|
|
},
|
|
{
|
|
title: '修改日期',
|
|
render: (item, rowData, rowIndex, i) => {
|
|
return {
|
|
props: { rowSpan: 1, colSpan: 1 },
|
|
children: (
|
|
<div key={`${rowIndex}-${rowData.updated_at}`}>
|
|
{rowData.updated_at}
|
|
</div>
|
|
),
|
|
};
|
|
},
|
|
},
|
|
]}
|
|
rowClassName={(item) => !item.id && 'font-bold text-primary'}
|
|
/>
|
|
</div>
|
|
<div className="cxd-Modal-footer">
|
|
<Button onClick={() => this.setState({ showDialog: false })}>
|
|
取消
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : null}
|
|
</>
|
|
);
|
|
}
|
|
}
|