18219: Adds property editor to groups create dialog.
authorLucas Di Pentima <lucas.dipentima@curii.com>
Tue, 21 Dec 2021 12:39:39 +0000 (09:39 -0300)
committerLucas Di Pentima <lucas.dipentima@curii.com>
Tue, 21 Dec 2021 12:39:39 +0000 (09:39 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>

cypress/integration/group-manage.spec.js
cypress/integration/project.spec.js
src/store/groups-panel/groups-panel-actions.ts
src/store/projects/project-create-actions.ts
src/store/projects/project-update-actions.ts
src/views-components/dialog-create/dialog-project-create.tsx
src/views-components/dialog-forms/create-project-dialog.ts
src/views-components/dialog-forms/update-project-dialog.ts
src/views-components/dialog-update/dialog-project-update.tsx

index 5da1868771ba03e480cbc4848c00f980a542e6f3..848220344adfd9d43c547426edfabfdc24ada695 100644 (file)
@@ -45,13 +45,15 @@ describe('Group manage tests', function() {
         // Create new group
         cy.get('[data-cy=groups-panel-new-group]').click();
         cy.get('[data-cy=form-dialog]')
-            .should('contain', 'Create Group')
+            .should('contain', 'New Group')
             .within(() => {
                 cy.get('input[name=name]').type(groupName);
                 cy.get('[data-cy=users-field] input').type("three");
             });
         cy.get('[role=tooltip]').click();
-        cy.get('[data-cy=form-dialog] button[type=submit]').click();
+        cy.get('[data-cy=form-dialog]').within(() => {
+            cy.get('[data-cy=form-submit-btn]').click();
+        })
 
         // Check that the group was created
         cy.get('[data-cy=groups-panel-data-explorer]').contains(groupName).click();
index 3678b78a349268326fe96841c41dc453cce0d6c2..6b87a3c2c0b76e6c2334c256fd8f50e9d7cae01c 100644 (file)
@@ -34,7 +34,7 @@ describe('Project tests', function() {
         cy.get('[data-cy=side-panel-button]').click();
         cy.get('[data-cy=side-panel-new-project]').click();
         cy.get('[data-cy=form-dialog]')
-            .should('contain', 'New project')
+            .should('contain', 'New Project')
             .within(() => {
                 cy.get('[data-cy=name-field]').within(() => {
                     cy.get('input').type(projName);
@@ -74,7 +74,7 @@ describe('Project tests', function() {
             cy.get('[data-cy=side-panel-button]').click();
             cy.get('[data-cy=side-panel-new-project]').click();
             cy.get('[data-cy=form-dialog]')
-                .should('contain', 'New project')
+                .should('contain', 'New Project')
                 .within(() => {
                     cy.get('[data-cy=parent-field]').within(() => {
                         cy.get('input').invoke('val').then((val) => {
index c72b00177c35f2ba42e377ca12d647a581b8cd7a..6e63702e57ec676a009d21ceb691da519f1e480b 100644 (file)
@@ -16,6 +16,7 @@ import { PermissionLevel } from 'models/permission';
 import { PermissionService } from 'services/permission-service/permission-service';
 import { FilterBuilder } from 'services/api/filter-builder';
 import { ProjectUpdateFormDialogData, PROJECT_UPDATE_FORM_NAME } from 'store/projects/project-update-actions';
+import { PROJECT_CREATE_FORM_NAME } from 'store/projects/project-create-actions';
 
 export const GROUPS_PANEL_ID = "groupsPanel";
 
@@ -28,8 +29,13 @@ export const loadGroupsPanel = () => GroupsPanelActions.REQUEST_ITEMS();
 
 export const openCreateGroupDialog = () =>
     (dispatch: Dispatch, getState: () => RootState) => {
-        dispatch(initialize(PROJECT_UPDATE_FORM_NAME, {}));
-        dispatch(dialogActions.OPEN_DIALOG({ id: PROJECT_UPDATE_FORM_NAME, data: {sourcePanel: GroupClass.ROLE, create: true} }));
+        dispatch(initialize(PROJECT_CREATE_FORM_NAME, {}));
+        dispatch(dialogActions.OPEN_DIALOG({
+            id: PROJECT_CREATE_FORM_NAME,
+            data: {
+                sourcePanel: GroupClass.ROLE,
+            }
+        }));
     };
 
 export const openGroupAttributes = (uuid: string) =>
@@ -64,7 +70,12 @@ export const openRemoveGroupDialog = (uuid: string) =>
 export const openGroupUpdateDialog = (resource: ProjectUpdateFormDialogData) =>
     (dispatch: Dispatch, getState: () => RootState) => {
         dispatch(initialize(PROJECT_UPDATE_FORM_NAME, resource));
-        dispatch(dialogActions.OPEN_DIALOG({ id: PROJECT_UPDATE_FORM_NAME, data: {sourcePanel: GroupClass.ROLE} }));
+        dispatch(dialogActions.OPEN_DIALOG({
+            id: PROJECT_UPDATE_FORM_NAME,
+            data: {
+                sourcePanel: GroupClass.ROLE,
+            }
+        }));
     };
 
 export const updateGroup = (project: ProjectUpdateFormDialogData) =>
@@ -89,7 +100,7 @@ export const updateGroup = (project: ProjectUpdateFormDialogData) =>
 
 export const createGroup = ({ name, users = [], description }: ProjectUpdateFormDialogData) =>
     async (dispatch: Dispatch, _: {}, { groupsService, permissionService }: ServiceRepository) => {
-        dispatch(startSubmit(PROJECT_UPDATE_FORM_NAME));
+        dispatch(startSubmit(PROJECT_CREATE_FORM_NAME));
         try {
             const newGroup = await groupsService.create({ name, description, groupClass: GroupClass.ROLE });
             for (const user of users) {
@@ -100,8 +111,8 @@ export const createGroup = ({ name, users = [], description }: ProjectUpdateForm
                     permissionService,
                 });
             }
-            dispatch(dialogActions.CLOSE_DIALOG({ id: PROJECT_UPDATE_FORM_NAME }));
-            dispatch(reset(PROJECT_UPDATE_FORM_NAME));
+            dispatch(dialogActions.CLOSE_DIALOG({ id: PROJECT_CREATE_FORM_NAME }));
+            dispatch(reset(PROJECT_CREATE_FORM_NAME));
             dispatch(loadGroupsPanel());
             dispatch(snackbarActions.OPEN_SNACKBAR({
                 message: `${newGroup.name} group has been created`,
@@ -111,7 +122,7 @@ export const createGroup = ({ name, users = [], description }: ProjectUpdateForm
         } catch (e) {
             const error = getCommonResourceServiceError(e);
             if (error === CommonResourceServiceError.UNIQUE_NAME_VIOLATION) {
-                dispatch(stopSubmit(PROJECT_UPDATE_FORM_NAME, { name: 'Group with the same name already exists.' } as FormErrors));
+                dispatch(stopSubmit(PROJECT_CREATE_FORM_NAME, { name: 'Group with the same name already exists.' } as FormErrors));
             }
             return;
         }
index c7d17c51465ddec7f944960983b466449aa3a52f..23eaf7a4a56aaa077083f0f738c37ad5f81ebb6e 100644 (file)
@@ -19,6 +19,7 @@ import { ProjectResource } from 'models/project';
 import { ServiceRepository } from 'services/services';
 import { matchProjectRoute, matchRunProcessRoute } from 'routes/routes';
 import { RouterState } from "react-router-redux";
+import { GroupClass } from "models/group";
 
 export interface ProjectCreateFormDialogData {
     ownerUuid: string;
@@ -52,7 +53,12 @@ export const openProjectCreateDialog = (ownerUuid: string) =>
         } else {
             dispatch(initialize(PROJECT_CREATE_FORM_NAME, { ownerUuid }));
         }
-        dispatch(dialogActions.OPEN_DIALOG({ id: PROJECT_CREATE_FORM_NAME, data: {} }));
+        dispatch(dialogActions.OPEN_DIALOG({
+            id: PROJECT_CREATE_FORM_NAME,
+            data: {
+                sourcePanel: GroupClass.PROJECT,
+            }
+        }));
     };
 
 export const createProject = (project: Partial<ProjectResource>) =>
index 36f66ccf8ed09633895a829117f08cd87295757b..52abfd3fd2085ffb97c3361564ee73d1954421a2 100644 (file)
@@ -38,7 +38,12 @@ export const PROJECT_UPDATE_FORM_SELECTOR = formValueSelector(PROJECT_UPDATE_FOR
 export const openProjectUpdateDialog = (resource: ProjectUpdateFormDialogData) =>
     (dispatch: Dispatch, getState: () => RootState) => {
         dispatch(initialize(PROJECT_UPDATE_FORM_NAME, resource));
-        dispatch(dialogActions.OPEN_DIALOG({ id: PROJECT_UPDATE_FORM_NAME, data: {sourcePanel: GroupClass.PROJECT} }));
+        dispatch(dialogActions.OPEN_DIALOG({
+            id: PROJECT_UPDATE_FORM_NAME,
+            data: {
+                sourcePanel: GroupClass.PROJECT,
+            }
+        }));
     };
 
 export const updateProject = (project: ProjectUpdateFormDialogData) =>
index 34860599516bf4af234912d5f52f2245a6b20969..65da87d3799fd8e7bf3475cbbf0fcf9aaad25faa 100644 (file)
@@ -7,21 +7,32 @@ import { InjectedFormProps } from 'redux-form';
 import { WithDialogProps } from 'store/dialog/with-dialog';
 import { ProjectCreateFormDialogData, PROJECT_CREATE_FORM_NAME } from 'store/projects/project-create-actions';
 import { FormDialog } from 'components/form-dialog/form-dialog';
-import { ProjectNameField, ProjectDescriptionField } from 'views-components/form-fields/project-form-fields';
+import { ProjectNameField, ProjectDescriptionField, UsersField } from 'views-components/form-fields/project-form-fields';
 import { CreateProjectPropertiesForm } from 'views-components/project-properties/create-project-properties-form';
 import { ResourceParentField } from '../form-fields/resource-form-fields';
 import { FormGroup, FormLabel } from '@material-ui/core';
 import { resourcePropertiesList } from 'views-components/resource-properties/resource-properties-list';
+import { GroupClass } from 'models/group';
 
-type DialogProjectProps = WithDialogProps<{}> & InjectedFormProps<ProjectCreateFormDialogData>;
+type DialogProjectProps = WithDialogProps<{sourcePanel: GroupClass}> & InjectedFormProps<ProjectCreateFormDialogData>;
 
-export const DialogProjectCreate = (props: DialogProjectProps) =>
-    <FormDialog
-        dialogTitle='New project'
-        formFields={ProjectAddFields}
-        submitLabel='Create a Project'
+export const DialogProjectCreate = (props: DialogProjectProps) => {
+    let title = 'New Project';
+    let fields = ProjectAddFields;
+    const sourcePanel = props.data.sourcePanel || '';
+
+    if (sourcePanel === GroupClass.ROLE) {
+        title = 'New Group';
+        fields = GroupAddFields;
+    }
+
+    return <FormDialog
+        dialogTitle={title}
+        formFields={fields}
+        submitLabel='Create'
         {...props}
     />;
+};
 
 const CreateProjectPropertiesList = resourcePropertiesList(PROJECT_CREATE_FORM_NAME);
 
@@ -35,3 +46,14 @@ const ProjectAddFields = () => <span>
         <CreateProjectPropertiesList />
     </FormGroup>
 </span>;
+
+const GroupAddFields = () => <span>
+    <ProjectNameField />
+    <UsersField />
+    <ProjectDescriptionField />
+    <FormLabel>Properties</FormLabel>
+    <FormGroup>
+        <CreateProjectPropertiesForm />
+        <CreateProjectPropertiesList />
+    </FormGroup>
+</span>;
index c0ece6755463f5f0e3cd019dfae5ea4b42a77fce..5c30281fa01e9a5923f1ac632f91f59ed07521eb 100644 (file)
@@ -8,13 +8,24 @@ import { withDialog } from "store/dialog/with-dialog";
 import { PROJECT_CREATE_FORM_NAME, ProjectCreateFormDialogData } from 'store/projects/project-create-actions';
 import { DialogProjectCreate } from 'views-components/dialog-create/dialog-project-create';
 import { createProject } from "store/workbench/workbench-actions";
+import { GroupClass } from "models/group";
+import { createGroup } from "store/groups-panel/groups-panel-actions";
 
 export const CreateProjectDialog = compose(
     withDialog(PROJECT_CREATE_FORM_NAME),
     reduxForm<ProjectCreateFormDialogData>({
         form: PROJECT_CREATE_FORM_NAME,
-        onSubmit: (data, dispatch) => {
-            dispatch(createProject(data));
+        onSubmit: (data, dispatch, props) => {
+            switch (props.data.sourcePanel) {
+                case GroupClass.PROJECT:
+                    dispatch(createProject(data));
+                    break;
+                case GroupClass.ROLE:
+                    dispatch(createGroup(data));
+                    break;
+                default:
+                    break;
+            }
         }
     })
 )(DialogProjectCreate);
\ No newline at end of file
index 4ba03f2ffa927ea681f4cdcd97726c572149a3c7..9462090431a8841ab20e28f9c0397d87e1844aa2 100644 (file)
@@ -9,7 +9,6 @@ import { DialogProjectUpdate } from 'views-components/dialog-update/dialog-proje
 import { PROJECT_UPDATE_FORM_NAME, ProjectUpdateFormDialogData } from 'store/projects/project-update-actions';
 import { updateProject, updateGroup } from 'store/workbench/workbench-actions';
 import { GroupClass } from "models/group";
-import { createGroup } from "store/groups-panel/groups-panel-actions";
 
 export const UpdateProjectDialog = compose(
     withDialog(PROJECT_UPDATE_FORM_NAME),
@@ -21,11 +20,7 @@ export const UpdateProjectDialog = compose(
                     dispatch(updateProject(data));
                     break;
                 case GroupClass.ROLE:
-                    if (data.uuid) {
-                        dispatch(updateGroup(data));
-                    } else {
-                        dispatch(createGroup(data));
-                    }
+                    dispatch(updateGroup(data));
                     break;
                 default:
                     break;
index 9737858a3f385ca5552b1e65a077c273e5fb5ccb..bad01815659f5aac6b555edb1b20aeed3a70dce4 100644 (file)
@@ -7,28 +7,25 @@ import { InjectedFormProps } from 'redux-form';
 import { WithDialogProps } from 'store/dialog/with-dialog';
 import { ProjectUpdateFormDialogData, PROJECT_UPDATE_FORM_NAME } from 'store/projects/project-update-actions';
 import { FormDialog } from 'components/form-dialog/form-dialog';
-import { ProjectNameField, ProjectDescriptionField, UsersField } from 'views-components/form-fields/project-form-fields';
+import { ProjectNameField, ProjectDescriptionField } from 'views-components/form-fields/project-form-fields';
 import { GroupClass } from 'models/group';
 import { FormGroup, FormLabel } from '@material-ui/core';
 import { UpdateProjectPropertiesForm } from 'views-components/project-properties/update-project-properties-form';
 import { resourcePropertiesList } from 'views-components/resource-properties/resource-properties-list';
 
-type DialogProjectProps = WithDialogProps<{sourcePanel: GroupClass, create?: boolean}> & InjectedFormProps<ProjectUpdateFormDialogData>;
+type DialogProjectProps = WithDialogProps<{sourcePanel: GroupClass}> & InjectedFormProps<ProjectUpdateFormDialogData>;
 
 export const DialogProjectUpdate = (props: DialogProjectProps) => {
     let title = 'Edit Project';
-    let fields = ProjectEditFields;
     const sourcePanel = props.data.sourcePanel || '';
-    const create = !!props.data.create;
 
     if (sourcePanel === GroupClass.ROLE) {
-        title = create ? 'Create Group' : 'Edit Group';
-        fields = create ? GroupAddFields : ProjectEditFields;
+        title = 'Edit Group';
     }
 
     return <FormDialog
         dialogTitle={title}
-        formFields={fields}
+        formFields={ProjectEditFields}
         submitLabel='Save'
         {...props}
     />;
@@ -46,9 +43,3 @@ const ProjectEditFields = () => <span>
         <UpdateProjectPropertiesList />
     </FormGroup>
 </span>;
-
-const GroupAddFields = () => <span>
-    <ProjectNameField />
-    <UsersField />
-    <ProjectDescriptionField />
-</span>;