19482: Fix context menu, breadcrumbs
[arvados-workbench2.git] / src / views-components / form-fields / project-form-fields.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from "react";
6 import { Field, FieldArray, Validator, WrappedFieldArrayProps } from "redux-form";
7 import { TextField, RichEditorTextField } from "components/text-field/text-field";
8 import { PROJECT_NAME_VALIDATION, PROJECT_NAME_VALIDATION_ALLOW_SLASH } from "validators/validators";
9 import { connect } from "react-redux";
10 import { RootState } from "store/store";
11 import { Participant, ParticipantSelect } from "views-components/sharing-dialog/participant-select";
12
13 interface ProjectNameFieldProps {
14     validate: Validator[];
15     label?: string;
16 }
17
18 // Validation behavior depends on the value of ForwardSlashNameSubstitution.
19 //
20 // Redux form doesn't let you pass anonymous functions to 'validate'
21 // -- it fails with a very confusing recursive-update-exceeded error.
22 // So we can't construct the validation function on the fly.
23 //
24 // As a workaround, use ForwardSlashNameSubstitution to choose between one of two const-defined validators.
25
26 export const ProjectNameField = connect(
27     (state: RootState) => {
28         return {
29             validate: (state.auth.config.clusterConfig.Collections.ForwardSlashNameSubstitution === "" ?
30                 PROJECT_NAME_VALIDATION : PROJECT_NAME_VALIDATION_ALLOW_SLASH)
31         };
32     })((props: ProjectNameFieldProps) =>
33         <span data-cy='name-field'><Field
34             name='name'
35             component={TextField as any}
36             validate={props.validate}
37             label={props.label || "Project Name"}
38             autoFocus={true} /></span>
39     );
40
41 export const ProjectDescriptionField = () =>
42     <Field
43         name='description'
44         component={RichEditorTextField as any}
45         label="Description - optional" />;
46
47 export const UsersField = () =>
48         <span data-cy='users-field'><FieldArray
49             name="users"
50             component={UsersSelect as any} /></span>;
51
52 export const UsersSelect = ({ fields }: WrappedFieldArrayProps<Participant>) =>
53         <ParticipantSelect
54             onlyPeople
55             label='Search for users to add to the group'
56             items={fields.getAll() || []}
57             onSelect={fields.push}
58             onDelete={fields.remove} />;