You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
5.8 KiB
TypeScript

// Copyright (C) 2020-2022 Intel Corporation
// Copyright (C) 2022 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
import React from 'react';
import { connect } from 'react-redux';
import { uniqBy } from 'lodash';
import { TreeNodeNormal } from 'antd/lib/tree/Tree';
import FileManagerComponent, { Files } from 'components/file-manager/file-manager';
import { loadShareDataAsync } from 'actions/share-actions';
import { ShareItem, CombinedState, ShareFileInfo } from 'reducers';
interface OwnProps {
ref: any;
many: boolean
onChangeActiveKey(key: string): void;
onUploadLocalFiles(files: File[]): void;
onUploadRemoteFiles(urls: string[]): void;
onUploadShareFiles(shareFiles: {
key: string;
type: string;
mime_type: string;
}[]): void;
onUploadCloudStorageFiles(urls: string[]): void;
}
interface StateToProps {
treeData: (TreeNodeNormal & { mime_type: string })[];
share: any;
}
interface DispatchToProps {
getTreeData(key: string): Promise<ShareFileInfo[]>;
}
function mapStateToProps(state: CombinedState): StateToProps {
function convert(items: ShareItem[], path?: string): (TreeNodeNormal & { mime_type: string })[] {
return items.map(
(item): (TreeNodeNormal & { mime_type: string }) => {
const isLeaf = item.type !== 'DIR';
const key = `${path}${item.name}${isLeaf ? '' : '/'}`;
return {
key,
isLeaf,
title: item.name || 'root',
mime_type: item.mime_type,
children: convert(item.children, key),
};
},
);
}
const { root } = state.share;
return {
treeData: convert([root], ''),
share: state.share,
};
}
function mapDispatchToProps(dispatch: any): DispatchToProps {
return {
getTreeData: (key: string):
Promise<ShareFileInfo[]> => dispatch(loadShareDataAsync(key)),
};
}
type Props = StateToProps & DispatchToProps & OwnProps;
export class FileManagerContainer extends React.PureComponent<Props> {
private managerComponentRef: any;
public constructor(props: Props) {
super(props);
this.managerComponentRef = React.createRef();
}
private handleUploadShareFiles = (keys: string[]): Promise<void> => new Promise(() => {
const { onUploadShareFiles, getTreeData } = this.props;
const getItemTreeDataByPath = (data: any, partsPath: string[]): any => {
if (partsPath.length === 1) return data.children.find((child: any) => child.title === partsPath[0]);
return getItemTreeDataByPath(
data.children.find((child: any) => child.title === partsPath[0]),
[...partsPath].filter((it, index) => index !== 0),
);
};
const getShareFiles = async (localKeys: string[]): Promise<{
key: string;
type: string;
mime_type: string;
}[]> => {
const { treeData } = this.props;
let files: {
key: string;
type: string;
mime_type: string;
}[] = [];
for await (const key of localKeys) {
const partsPath = key.split('/').filter(Boolean);
const itemTreeData = partsPath.length ? getItemTreeDataByPath(treeData[0], partsPath) : treeData[0];
console.log(itemTreeData);
if (itemTreeData.isLeaf) {
files = [...files, {
...itemTreeData,
key,
type: itemTreeData.type,
mime_type: itemTreeData.mime_type,
}];
} else {
const children: {
key: string;
type: string;
mime_type: string;
}[] = await getTreeData(key)
.then((items) => items.map(
(item): string => {
const isLeaf = item.type !== 'DIR';
return `${key}${item.name}${isLeaf ? '' : '/'}`;
},
))
.then(getShareFiles);
files = [...files, ...children];
}
}
return files;
};
getShareFiles(keys).then((data) => {
onUploadShareFiles(uniqBy(data, 'key'));
});
});
public getFiles(): Files {
return this.managerComponentRef.getFiles();
}
public getCloudStorageId(): number | null {
return this.managerComponentRef.getCloudStorageId();
}
public reset(): Files {
return this.managerComponentRef.reset();
}
public render(): JSX.Element {
const {
treeData,
share,
getTreeData,
many,
onChangeActiveKey,
onUploadLocalFiles,
onUploadRemoteFiles,
onUploadCloudStorageFiles,
} = this.props;
return (
<FileManagerComponent
treeData={treeData}
share={share}
many={many}
onLoadData={getTreeData}
onUploadLocalFiles={onUploadLocalFiles}
onUploadRemoteFiles={onUploadRemoteFiles}
onUploadShareFiles={this.handleUploadShareFiles}
onUploadCloudStorageFiles={onUploadCloudStorageFiles}
onChangeActiveKey={onChangeActiveKey}
ref={(component): void => {
this.managerComponentRef = component;
}}
/>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true })(FileManagerContainer);