Files
alab-amis-fix-exam/src/renderer/DataSetPicker.tsx

302 lines
10 KiB
TypeScript
Raw Normal View History

2024-11-13 09:05:45 +08:00
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}
</>
);
}
}