|
|
|
|
@ -3,13 +3,13 @@
|
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
|
|
import React, {
|
|
|
|
|
useState, useRef, useEffect, Component,
|
|
|
|
|
useState, useRef, useEffect, RefObject,
|
|
|
|
|
} from 'react';
|
|
|
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
|
|
|
import { useHistory } from 'react-router';
|
|
|
|
|
import { Col, Row } from 'antd/lib/grid';
|
|
|
|
|
import Text from 'antd/lib/typography/Text';
|
|
|
|
|
import Form, { FormComponentProps, WrappedFormUtils } from '@ant-design/compatible/lib/form/Form';
|
|
|
|
|
import Form, { FormInstance } from 'antd/lib/form';
|
|
|
|
|
import Button from 'antd/lib/button';
|
|
|
|
|
import Input from 'antd/lib/input';
|
|
|
|
|
import notification from 'antd/lib/notification';
|
|
|
|
|
@ -19,66 +19,57 @@ import { CombinedState } from 'reducers/interfaces';
|
|
|
|
|
import LabelsEditor from 'components/labels-editor/labels-editor';
|
|
|
|
|
import { createProjectAsync } from 'actions/projects-actions';
|
|
|
|
|
|
|
|
|
|
type FormRefType = Component<FormComponentProps<any>, any, any> & WrappedFormUtils;
|
|
|
|
|
|
|
|
|
|
const ProjectNameEditor = Form.create<FormComponentProps>()(
|
|
|
|
|
(props: FormComponentProps): JSX.Element => {
|
|
|
|
|
const { form } = props;
|
|
|
|
|
const { getFieldDecorator } = form;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Form onSubmit={(e): void => e.preventDefault()}>
|
|
|
|
|
<Form.Item hasFeedback label={<span>Name</span>}>
|
|
|
|
|
{getFieldDecorator('name', {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: 'Please, specify a name',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
})(<Input />)}
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const AdvanvedConfigurationForm = Form.create<FormComponentProps>()(
|
|
|
|
|
(props: FormComponentProps): JSX.Element => {
|
|
|
|
|
const { form } = props;
|
|
|
|
|
const { getFieldDecorator } = form;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Form onSubmit={(e): void => e.preventDefault()}>
|
|
|
|
|
<Form.Item
|
|
|
|
|
label={<span>Issue tracker</span>}
|
|
|
|
|
extra='Attach issue tracker where the project is described'
|
|
|
|
|
hasFeedback
|
|
|
|
|
>
|
|
|
|
|
{getFieldDecorator('bug_tracker', {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
validator: (_, value, callback): void => {
|
|
|
|
|
if (value && !patterns.validateURL.pattern.test(value)) {
|
|
|
|
|
callback('Issue tracker must be URL');
|
|
|
|
|
} else {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
})(<Input />)}
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
function NameConfigurationForm({ formRef }: { formRef: RefObject<FormInstance> }): JSX.Element {
|
|
|
|
|
return (
|
|
|
|
|
<Form layout='vertical' ref={formRef}>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name='name'
|
|
|
|
|
hasFeedback
|
|
|
|
|
label='Name'
|
|
|
|
|
rules={[
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: 'Please, specify a name',
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<Input />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function AdvanvedConfigurationForm({ formRef }: { formRef: RefObject<FormInstance> }): JSX.Element {
|
|
|
|
|
return (
|
|
|
|
|
<Form layout='vertical' ref={formRef}>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name='bug_tracker'
|
|
|
|
|
label='Issue tracker'
|
|
|
|
|
extra='Attach issue tracker where the project is described'
|
|
|
|
|
hasFeedback
|
|
|
|
|
rules={[
|
|
|
|
|
{
|
|
|
|
|
validator: (_, value, callback): void => {
|
|
|
|
|
if (value && !patterns.validateURL.pattern.test(value)) {
|
|
|
|
|
callback('Issue tracker must be URL');
|
|
|
|
|
} else {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<Input />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function CreateProjectContent(): JSX.Element {
|
|
|
|
|
const [projectLabels, setProjectLabels] = useState<any[]>([]);
|
|
|
|
|
const shouldShowNotification = useRef(false);
|
|
|
|
|
const nameFormRef = useRef<FormRefType>(null);
|
|
|
|
|
const advancedFormRef = useRef<FormRefType>(null);
|
|
|
|
|
const nameFormRef = useRef<FormInstance>(null);
|
|
|
|
|
const advancedFormRef = useRef<FormInstance>(null);
|
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
const history = useHistory();
|
|
|
|
|
|
|
|
|
|
@ -102,28 +93,19 @@ export default function CreateProjectContent(): JSX.Element {
|
|
|
|
|
shouldShowNotification.current = true;
|
|
|
|
|
}, [newProjectId]);
|
|
|
|
|
|
|
|
|
|
const onSumbit = (): void => {
|
|
|
|
|
const onSumbit = async (): Promise<void> => {
|
|
|
|
|
interface Project {
|
|
|
|
|
[key: string]: any;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const projectData: Project = {};
|
|
|
|
|
if (nameFormRef.current !== null) {
|
|
|
|
|
nameFormRef.current.validateFields((error, value) => {
|
|
|
|
|
if (!error) {
|
|
|
|
|
projectData.name = value.name;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (advancedFormRef.current !== null) {
|
|
|
|
|
advancedFormRef.current.validateFields((error, values) => {
|
|
|
|
|
if (!error) {
|
|
|
|
|
for (const [field, value] of Object.entries(values)) {
|
|
|
|
|
projectData[field] = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (nameFormRef.current && advancedFormRef.current) {
|
|
|
|
|
const basicValues = await nameFormRef.current.validateFields();
|
|
|
|
|
const advancedValues = await advancedFormRef.current.validateFields();
|
|
|
|
|
projectData.name = basicValues.name;
|
|
|
|
|
for (const [field, value] of Object.entries(advancedValues)) {
|
|
|
|
|
projectData[field] = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
projectData.labels = projectLabels;
|
|
|
|
|
@ -136,7 +118,7 @@ export default function CreateProjectContent(): JSX.Element {
|
|
|
|
|
return (
|
|
|
|
|
<Row type='flex' justify='start' align='middle' className='cvat-create-project-content'>
|
|
|
|
|
<Col span={24}>
|
|
|
|
|
<ProjectNameEditor ref={nameFormRef} />
|
|
|
|
|
<NameConfigurationForm formRef={nameFormRef} />
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={24}>
|
|
|
|
|
<Text className='cvat-text-color'>Labels:</Text>
|
|
|
|
|
@ -148,7 +130,7 @@ export default function CreateProjectContent(): JSX.Element {
|
|
|
|
|
/>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={24}>
|
|
|
|
|
<AdvanvedConfigurationForm ref={advancedFormRef} />
|
|
|
|
|
<AdvanvedConfigurationForm formRef={advancedFormRef} />
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={24}>
|
|
|
|
|
<Button type='primary' onClick={onSumbit}>
|
|
|
|
|
|