export default function UploadFiles()

in frontend/src/js/components/Uploads/UploadFiles.tsx [220:360]


export default function UploadFiles(props: Props) {
    let target: WorkspaceTarget | undefined = undefined;

    const appDispatch = useDispatch();
    const [state, dispatch] = useReducer(reducer, { files: new Map() });

    const currentUpload = getCurrentlyUploading(state);
    const isUploading = currentUpload !== undefined;

    const completeCount = [...state.files.values()].filter(({ state }) => state.description === 'uploaded').length;
    const isComplete = [...state.files.values()].some(({ state }) => state.description === 'uploaded');

    const isEditDisabled = isUploading || isComplete;

    function dismissAndResetModal() {
        setOpen(false);
        dispatch({ type: "Reset", state: { files: new Map(), target: undefined } });
    }

    const [open, setOpen] = useState(false);
    const [focusedWorkspaceFolder, setFocusedWorkspaceFolder] = useState<TreeNode<WorkspaceEntry> | null>(null);

    async function onSubmit() {

        const { username, workspace, collections, getResource } = props;
        if (!collections) {
            throw new Error('No collections when submitting upload dialog');
        }

        try {
            target = await getUploadTarget(username, workspace, collections, focusedWorkspaceFolder);

            if (isComplete) {
                dismissAndResetModal();
                history.push(`/workspaces/${target.workspace.id}`);
            } else {
                await uploadFiles(target, state.files, dispatch).then(() => {
                    getResource(workspace.id);
                });
            }
        } catch(error) {
            appDispatch({
                type: AppActionType.APP_SHOW_ERROR,
                message: `Error uploading files ${error}`,
                error: error,
            });
        }
    }

    function onDismiss() {
        setOpen(false);

        setFocusedWorkspaceFolder(null);
        dispatch({ type: "Reset", state: { files: new Map(), target: undefined } });
    }

    function onClick() {
        setOpen(true);
        if (props.focusedWorkspaceEntry) {
            const { focusedWorkspaceEntry } = props;

            // Set the folder we are focused on. If we are focused on a leaf, then
            // the focused leaf is the parent of that folder.
            if (isTreeNode(focusedWorkspaceEntry)) {
                setFocusedWorkspaceFolder(focusedWorkspaceEntry);
            }
            else if (isTreeLeaf(focusedWorkspaceEntry)) {
                const rootNodeId = props.workspace.rootNode.id;
                const parentId = focusedWorkspaceEntry.data.maybeParentId;

                if (parentId && parentId !== rootNodeId) {
                    const focusedUploadFolder = props.expandedNodes && props.expandedNodes.find(node => node.id === parentId);
                    if (focusedUploadFolder) {
                        setFocusedWorkspaceFolder(focusedUploadFolder);
                    }
                }
            }
        }
    }

    const focusedWorkspaceRelativePath = (focusedWorkspaceFolder && props.workspace.rootNode)
        ? displayRelativePath(props.workspace.rootNode, focusedWorkspaceFolder.id)
        : null;

    return (
        <React.Fragment>
            <button
                className='btn file-upload__button'
                onClick={onClick}
            >
              <MdFileUpload className='file-upload__icon'/>
              Upload to workspace
            </button>
            <Modal isOpen={open} dismiss={onDismiss} isDismissable={!isUploading}>
                <Form onSubmit={onSubmit}>
                    <h2 className='form__title'>Upload Files (limit {MAX_FILE_UPLOAD_SIZE_MBYTES}MB per file)</h2>
                    { focusedWorkspaceRelativePath ? <div className='form__row'>Uploading to folder {focusedWorkspaceRelativePath}</div> : false}
                    <Form.Field>
                        <FilePicker
                            disabled={isEditDisabled}
                            onAddFiles={(files) => {
                                dispatch({ type: "Add_Files", files })
                            }}
                        />
                    </Form.Field>
                    <Form.Field>
                        <FileList
                            files={state.files}
                            disabled={isEditDisabled}
                            removeByPath={(path: string) => {
                                dispatch({ type: "Remove_Path", path })
                            }}
                        />
                    </Form.Field>
                    {currentUpload ? <FileUploadProgressBar file={currentUpload.file} uploadState={currentUpload.uploadState} /> : false}
                    { !isComplete ?
                        <Button
                            type="submit"
                            primary
                            disabled={state.files.size === 0 || isUploading}
                            loading={isUploading}
                        >
                            {'Upload'}
                        </Button>
                    : false }
                    {isComplete && !isUploading ?
                        <Button
                            type="button"
                            onClick={() => dismissAndResetModal()}
                        >
                            Close
                        </Button>
                    : false}
                    {isUploading ?
                        <span>Uploaded {completeCount}/{state.files.size}</span>
                    : false}
                </Form>
            </Modal>
        </React.Fragment>
    );
}