// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React, { RefObject } from 'react'; import { RouteComponentProps } from 'react-router'; import { withRouter } from 'react-router-dom'; import { Row, Col } from 'antd/lib/grid'; import Alert from 'antd/lib/alert'; import Button from 'antd/lib/button'; import Collapse from 'antd/lib/collapse'; import notification from 'antd/lib/notification'; import Text from 'antd/lib/typography/Text'; import ConnectedFileManager from 'containers/file-manager/file-manager'; import LabelsEditor from 'components/labels-editor/labels-editor'; import { Files } from 'components/file-manager/file-manager'; import BasicConfigurationForm, { BaseConfiguration } from './basic-configuration-form'; import ProjectSearchField from './project-search-field'; import ProjectSubsetField from './project-subset-field'; import AdvancedConfigurationForm, { AdvancedConfiguration } from './advanced-configuration-form'; export interface CreateTaskData { projectId: number | null; basic: BaseConfiguration; subset: string; advanced: AdvancedConfiguration; labels: any[]; files: Files; activeFileManagerTab: string; } interface Props { onCreate: (data: CreateTaskData) => void; status: string; taskId: number | null; projectId: number | null; installedGit: boolean; } type State = CreateTaskData; const defaultState = { projectId: null, basic: { name: '', }, subset: '', advanced: { lfs: false, useZipChunks: true, useCache: true, }, labels: [], files: { local: [], share: [], remote: [], }, activeFileManagerTab: 'local', }; class CreateTaskContent extends React.PureComponent { private basicConfigurationComponent: RefObject; private advancedConfigurationComponent: RefObject; private fileManagerContainer: any; public constructor(props: Props & RouteComponentProps) { super(props); this.state = { ...defaultState }; this.basicConfigurationComponent = React.createRef(); this.advancedConfigurationComponent = React.createRef(); } public componentDidMount(): void { const { projectId } = this.props; if (projectId) { this.handleProjectIdChange(projectId); } } public componentDidUpdate(prevProps: Props): void { const { status, history, taskId } = this.props; if (status === 'CREATED' && prevProps.status !== 'CREATED') { const btn = ; notification.info({ message: 'The task has been created', btn, className: 'cvat-notification-create-task-success', }); if (this.basicConfigurationComponent.current) { this.basicConfigurationComponent.current.resetFields(); } if (this.advancedConfigurationComponent.current) { this.advancedConfigurationComponent.current.resetFields(); } this.fileManagerContainer.reset(); this.setState({ ...defaultState, }); } } private validateLabelsOrProject = (): boolean => { const { projectId, labels } = this.state; return !!labels.length || !!projectId; }; private validateFiles = (): boolean => { const files = this.fileManagerContainer.getFiles(); this.setState({ files, }); const totalLen = Object.keys(files).reduce((acc, key) => acc + files[key].length, 0); return !!totalLen; }; private handleProjectIdChange = (value: null | number): void => { const { projectId, subset } = this.state; this.setState({ projectId: value, subset: value && value === projectId ? subset : '', }); }; private handleSubmitBasicConfiguration = (values: BaseConfiguration): void => { this.setState({ basic: { ...values }, }); }; private handleSubmitAdvancedConfiguration = (values: AdvancedConfiguration): void => { this.setState({ advanced: { ...values }, }); }; private handleTaskSubsetChange = (value: string): void => { this.setState({ subset: value, }); }; private changeFileManagerTab = (key: string): void => { const values = this.state; this.setState({ ...values, activeFileManagerTab: key, }); }; private handleSubmitClick = (): void => { if (!this.validateLabelsOrProject()) { notification.error({ message: 'Could not create a task', description: 'A task must contain at least one label or belong to some project', className: 'cvat-notification-create-task-fail', }); return; } if (!this.validateFiles()) { notification.error({ message: 'Could not create a task', description: 'A task must contain at least one file', className: 'cvat-notification-create-task-fail', }); return; } if (this.basicConfigurationComponent.current) { this.basicConfigurationComponent.current .submit() .then(() => { if (this.advancedConfigurationComponent.current) { return this.advancedConfigurationComponent.current.submit(); } return new Promise((resolve): void => { resolve(); }); }) .then((): void => { const { onCreate } = this.props; onCreate(this.state); }) .catch((error: Error): void => { notification.error({ message: 'Could not create a task', description: error.toString(), className: 'cvat-notification-create-task-fail', }); }); } }; private renderBasicBlock(): JSX.Element { return ( ); } private renderProjectBlock(): JSX.Element { const { projectId } = this.state; return ( <> Project: ); } private renderSubsetBlock(): JSX.Element | null { const { projectId, subset } = this.state; if (projectId !== null) { return ( <> Subset: ); } return null; } private renderLabelsBlock(): JSX.Element { const { projectId, labels } = this.state; if (projectId) { return ( <> Labels: Project labels will be used ); } return ( * Labels: { this.setState({ labels: newLabels, }); }} /> ); } private renderFilesBlock(): JSX.Element { return ( * Select files: { this.fileManagerContainer = container; }} withRemote /> ); } private renderAdvancedBlock(): JSX.Element { const { installedGit } = this.props; const { activeFileManagerTab } = this.state; return ( Advanced configuration}> ); } public render(): JSX.Element { const { status } = this.props; const loading = !!status && status !== 'CREATED' && status !== 'FAILED'; return ( Basic configuration {this.renderBasicBlock()} {this.renderProjectBlock()} {this.renderSubsetBlock()} {this.renderLabelsBlock()} {this.renderFilesBlock()} {this.renderAdvancedBlock()} {loading ? : null} ); } } export default withRouter(CreateTaskContent);