[ARVADOS-WORKBENCH2] updated: 2.3.0-56-gdf919798

Git user git at public.arvados.org
Wed Dec 15 05:36:10 UTC 2021


Summary of changes:
 cypress/integration/group-manage.spec.js           | 50 +++++++++++------
 src/store/groups-panel/groups-panel-actions.ts     | 29 ++++------
 src/store/projects/project-update-actions.ts       |  2 +
 .../dialog-forms/create-group-dialog.tsx           | 63 ----------------------
 .../dialog-forms/update-project-dialog.ts          |  8 ++-
 .../dialog-update/dialog-project-update.tsx        | 31 ++++++++---
 .../form-fields/project-form-fields.tsx            | 16 +++++-
 src/views/workbench/workbench.tsx                  |  2 -
 8 files changed, 92 insertions(+), 109 deletions(-)
 delete mode 100644 src/views-components/dialog-forms/create-group-dialog.tsx

       via  df9197982583c61e6f142d37ca8e01a8277027d3 (commit)
      from  dfac252e5d6639c0bc6f106f1985fcdcd7402376 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit df9197982583c61e6f142d37ca8e01a8277027d3
Author: Stephen Smith <stephen at curii.com>
Date:   Wed Dec 15 00:35:25 2021 -0500

    18123: Use update project dialog for creating groups and remove create group dialog.
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/cypress/integration/group-manage.spec.js b/cypress/integration/group-manage.spec.js
index cae69efb..c98c2201 100644
--- a/cypress/integration/group-manage.spec.js
+++ b/cypress/integration/group-manage.spec.js
@@ -6,6 +6,7 @@ describe('Group manage tests', function() {
     let activeUser;
     let adminUser;
     let otherUser;
+    let userThree;
     const groupName = `Test group (${Math.floor(999999 * Math.random())})`;
 
     before(function() {
@@ -28,6 +29,11 @@ describe('Group manage tests', function() {
                 otherUser = this.otherUser;
             }
         );
+        cy.getUser('userThree', 'User', 'Three', false, true)
+            .as('userThree').then(function() {
+                userThree = this.userThree;
+            }
+        );
     });
 
     beforeEach(function() {
@@ -44,15 +50,18 @@ 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 a group')
+            .should('contain', 'Create Group')
             .within(() => {
                 cy.get('input[name=name]').type(groupName);
-                cy.get('button[type=submit]').click();
+                cy.get('[data-cy=users-field] input').type("three");
             });
+        cy.get('[role=tooltip]').click();
+        cy.get('[data-cy=form-dialog] button[type=submit]').click();
         
         // Check that the group was created
         cy.get('[data-cy=groups-panel-data-explorer]').contains(groupName).click();
-        cy.get('[data-cy=group-members-data-explorer]').contains('Active User');
+        cy.get('[data-cy=group-members-data-explorer]').contains(activeUser.user.full_name);
+        cy.get('[data-cy=group-members-data-explorer]').contains(userThree.user.full_name);
     });
 
     it('adds users to the group', function() {
@@ -68,13 +77,13 @@ describe('Group manage tests', function() {
 
         // Check that both users are present with appropriate permissions
         cy.get('[data-cy=group-members-data-explorer]')
-            .contains('Other User')
+            .contains(otherUser.user.full_name)
             .parents('tr')
             .within(() => {
                 cy.contains('Read');
             });
         cy.get('[data-cy=group-members-data-explorer] tr')
-            .contains('Active User')
+            .contains(activeUser.user.full_name)
             .parents('tr')
             .within(() => {
                 cy.contains('Manage');
@@ -84,7 +93,7 @@ describe('Group manage tests', function() {
     it('changes permission level of a member', function() {
         // Test change permission level
         cy.get('[data-cy=group-members-data-explorer]')
-            .contains('Other User')
+            .contains(otherUser.user.full_name)
             .parents('tr')
             .within(() => {
                 cy.contains('Read')
@@ -97,7 +106,7 @@ describe('Group manage tests', function() {
             .contains('Write')
             .click();
         cy.get('[data-cy=group-members-data-explorer]')
-            .contains('Other User')
+            .contains(otherUser.user.full_name)
             .parents('tr')
             .within(() => {
                 cy.contains('Write');
@@ -113,12 +122,12 @@ describe('Group manage tests', function() {
         // Check that other user is hidden
         cy.get('[data-cy=group-details-permissions-tab]').click();
         cy.get('[data-cy=group-permissions-data-explorer]')
-            .should('not.contain', 'Other User')
+            .should('not.contain', otherUser.user.full_name)
         cy.get('[data-cy=group-details-members-tab]').click();
 
         // Test unhide
         cy.get('[data-cy=group-members-data-explorer]')
-            .contains('Other User')
+            .contains(otherUser.user.full_name)
             .parents('tr')
             .within(() => {
                 cy.get('[data-cy=user-visible-checkbox]').click();
@@ -126,7 +135,7 @@ describe('Group manage tests', function() {
         // Check that other user is visible
         cy.get('[data-cy=group-details-permissions-tab]').click();
         cy.get('[data-cy=group-permissions-data-explorer]')
-            .contains('Other User')
+            .contains(otherUser.user.full_name)
             .parents('tr')
             .within(() => {
                 cy.contains('Read');
@@ -134,7 +143,7 @@ describe('Group manage tests', function() {
         // Test re-hide
         cy.get('[data-cy=group-details-members-tab]').click();
         cy.get('[data-cy=group-members-data-explorer]')
-            .contains('Other User')
+            .contains(otherUser.user.full_name)
             .parents('tr')
             .within(() => {
                 cy.get('[data-cy=user-visible-checkbox]').click();
@@ -142,7 +151,7 @@ describe('Group manage tests', function() {
         // Check that other user is hidden
         cy.get('[data-cy=group-details-permissions-tab]').click();
         cy.get('[data-cy=group-permissions-data-explorer]')
-            .should('not.contain', 'Other User')
+            .should('not.contain', otherUser.user.full_name)
     });
 
     it('displays resources shared with the group', function() {
@@ -183,14 +192,25 @@ describe('Group manage tests', function() {
 
         // Remove other user
         cy.get('[data-cy=group-members-data-explorer]')
-            .contains('Other User')
+            .contains(otherUser.user.full_name)
+            .parents('tr')
+            .within(() => {
+                cy.get('[data-cy=resource-delete-button]').click();
+            });
+        cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
+        cy.get('[data-cy=group-members-data-explorer]')
+            .should('not.contain', otherUser.user.full_name);
+
+        // Remove user three
+        cy.get('[data-cy=group-members-data-explorer]')
+            .contains(userThree.user.full_name)
             .parents('tr')
             .within(() => {
                 cy.get('[data-cy=resource-delete-button]').click();
             });
         cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
         cy.get('[data-cy=group-members-data-explorer]')
-            .should('not.contain', 'Other User');
+            .should('not.contain', userThree.user.full_name);
     });
 
     it('renames the group', function() {
@@ -207,7 +227,7 @@ describe('Group manage tests', function() {
 
         // Rename the group
         cy.get('[data-cy=form-dialog]')
-            .should('contain', 'Edit Project')
+            .should('contain', 'Edit Group')
             .within(() => {
                 cy.get('input[name=name]').clear().type(groupName + ' (renamed)');
                 cy.get('button[type=submit]').click();
diff --git a/src/store/groups-panel/groups-panel-actions.ts b/src/store/groups-panel/groups-panel-actions.ts
index 6d17db19..be4e5d72 100644
--- a/src/store/groups-panel/groups-panel-actions.ts
+++ b/src/store/groups-panel/groups-panel-actions.ts
@@ -20,12 +20,6 @@ import { ProjectUpdateFormDialogData, PROJECT_UPDATE_FORM_NAME } from 'store/pro
 
 export const GROUPS_PANEL_ID = "groupsPanel";
 
-// Create group dialog
-export const CREATE_GROUP_DIALOG = "createGroupDialog";
-export const CREATE_GROUP_FORM = "createGroupForm";
-export const CREATE_GROUP_NAME_FIELD_NAME = 'name';
-export const CREATE_GROUP_USERS_FIELD_NAME = 'users';
-
 export const GROUP_ATTRIBUTES_DIALOG = 'groupAttributesDialog';
 export const GROUP_REMOVE_DIALOG = 'groupRemoveDialog';
 
@@ -34,9 +28,9 @@ export const GroupsPanelActions = bindDataExplorerActions(GROUPS_PANEL_ID);
 export const loadGroupsPanel = () => GroupsPanelActions.REQUEST_ITEMS();
 
 export const openCreateGroupDialog = () =>
-    (dispatch: Dispatch) => {
-        dispatch(dialogActions.OPEN_DIALOG({ id: CREATE_GROUP_DIALOG, data: {} }));
-        dispatch(reset(CREATE_GROUP_FORM));
+    (dispatch: Dispatch, getState: () => RootState) => {
+        dispatch(initialize(PROJECT_UPDATE_FORM_NAME, {}));
+        dispatch(dialogActions.OPEN_DIALOG({ id: PROJECT_UPDATE_FORM_NAME, data: {sourcePanel: GroupClass.ROLE, showUsersField: true} }));
     };
 
 export const openGroupAttributes = (uuid: string) =>
@@ -94,16 +88,11 @@ export const updateGroup = (project: ProjectUpdateFormDialogData) =>
         }
     };
 
-export interface CreateGroupFormData {
-    [CREATE_GROUP_NAME_FIELD_NAME]: string;
-    [CREATE_GROUP_USERS_FIELD_NAME]?: Participant[];
-}
-
-export const createGroup = ({ name, users = [] }: CreateGroupFormData) =>
+export const createGroup = ({ name, users = [], description }: ProjectUpdateFormDialogData) =>
     async (dispatch: Dispatch, _: {}, { groupsService, permissionService }: ServiceRepository) => {
-        dispatch(startSubmit(CREATE_GROUP_FORM));
+        dispatch(startSubmit(PROJECT_UPDATE_FORM_NAME));
         try {
-            const newGroup = await groupsService.create({ name, groupClass: GroupClass.ROLE });
+            const newGroup = await groupsService.create({ name, description, groupClass: GroupClass.ROLE });
             for (const user of users) {
                 await addGroupMember({
                     user,
@@ -112,8 +101,8 @@ export const createGroup = ({ name, users = [] }: CreateGroupFormData) =>
                     permissionService,
                 });
             }
-            dispatch(dialogActions.CLOSE_DIALOG({ id: CREATE_GROUP_DIALOG }));
-            dispatch(reset(CREATE_GROUP_FORM));
+            dispatch(dialogActions.CLOSE_DIALOG({ id: PROJECT_UPDATE_FORM_NAME }));
+            dispatch(reset(PROJECT_UPDATE_FORM_NAME));
             dispatch(loadGroupsPanel());
             dispatch(snackbarActions.OPEN_SNACKBAR({
                 message: `${newGroup.name} group has been created`,
@@ -123,7 +112,7 @@ export const createGroup = ({ name, users = [] }: CreateGroupFormData) =>
         } catch (e) {
             const error = getCommonResourceServiceError(e);
             if (error === CommonResourceServiceError.UNIQUE_NAME_VIOLATION) {
-                dispatch(stopSubmit(CREATE_GROUP_FORM, { name: 'Group with the same name already exists.' } as FormErrors));
+                dispatch(stopSubmit(PROJECT_UPDATE_FORM_NAME, { name: 'Group with the same name already exists.' } as FormErrors));
             }
             return;
         }
diff --git a/src/store/projects/project-update-actions.ts b/src/store/projects/project-update-actions.ts
index 45065b62..ba176753 100644
--- a/src/store/projects/project-update-actions.ts
+++ b/src/store/projects/project-update-actions.ts
@@ -10,10 +10,12 @@ import { getCommonResourceServiceError, CommonResourceServiceError } from "servi
 import { ServiceRepository } from "services/services";
 import { projectPanelActions } from 'store/project-panel/project-panel-action';
 import { GroupClass } from "models/group";
+import { Participant } from "views-components/sharing-dialog/participant-select";
 
 export interface ProjectUpdateFormDialogData {
     uuid: string;
     name: string;
+    users?: Participant[];
     description?: string;
 }
 
diff --git a/src/views-components/dialog-forms/create-group-dialog.tsx b/src/views-components/dialog-forms/create-group-dialog.tsx
deleted file mode 100644
index fceea262..00000000
--- a/src/views-components/dialog-forms/create-group-dialog.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import React from 'react';
-import { compose } from "redux";
-import { reduxForm, InjectedFormProps, Field, WrappedFieldArrayProps, FieldArray } from 'redux-form';
-import { withDialog, WithDialogProps } from "store/dialog/with-dialog";
-import { FormDialog } from 'components/form-dialog/form-dialog';
-import { CREATE_GROUP_DIALOG, CREATE_GROUP_FORM, createGroup, CreateGroupFormData, CREATE_GROUP_NAME_FIELD_NAME, CREATE_GROUP_USERS_FIELD_NAME } from 'store/groups-panel/groups-panel-actions';
-import { TextField } from 'components/text-field/text-field';
-import { maxLength } from 'validators/max-length';
-import { require } from 'validators/require';
-import { ParticipantSelect, Participant } from 'views-components/sharing-dialog/participant-select';
-
-export const CreateGroupDialog = compose(
-    withDialog(CREATE_GROUP_DIALOG),
-    reduxForm<CreateGroupFormData>({
-        form: CREATE_GROUP_FORM,
-        onSubmit: (data, dispatch) => {
-            dispatch(createGroup(data));
-        }
-    })
-)(
-    (props: CreateGroupDialogComponentProps) =>
-        <FormDialog
-            dialogTitle='Create a group'
-            formFields={CreateGroupFormFields}
-            submitLabel='Create'
-            {...props}
-        />
-);
-
-type CreateGroupDialogComponentProps = WithDialogProps<{}> & InjectedFormProps<CreateGroupFormData>;
-
-const CreateGroupFormFields = () =>
-    <>
-        <GroupNameField />
-        <UsersField />
-    </>;
-
-const GroupNameField = () =>
-    <Field
-        name={CREATE_GROUP_NAME_FIELD_NAME}
-        component={TextField as any}
-        validate={GROUP_NAME_VALIDATION}
-        label="Name"
-        autoFocus={true} />;
-
-const GROUP_NAME_VALIDATION = [require, maxLength(255)];
-
-const UsersField = () =>
-    <FieldArray
-        name={CREATE_GROUP_USERS_FIELD_NAME}
-        component={UsersSelect as any} />;
-
-const UsersSelect = ({ fields }: WrappedFieldArrayProps<Participant>) =>
-    <ParticipantSelect
-        onlyPeople
-        label='Enter email adresses '
-        items={fields.getAll() || []}
-        onSelect={fields.push}
-        onDelete={fields.remove} />;
diff --git a/src/views-components/dialog-forms/update-project-dialog.ts b/src/views-components/dialog-forms/update-project-dialog.ts
index 119e9256..4ba03f2f 100644
--- a/src/views-components/dialog-forms/update-project-dialog.ts
+++ b/src/views-components/dialog-forms/update-project-dialog.ts
@@ -9,19 +9,23 @@ 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),
     reduxForm<ProjectUpdateFormDialogData>({
         form: PROJECT_UPDATE_FORM_NAME,
         onSubmit: (data, dispatch, props) => {
-            console.log(props);
             switch (props.data.sourcePanel) {
                 case GroupClass.PROJECT:
                     dispatch(updateProject(data));
                     break;
                 case GroupClass.ROLE:
-                    dispatch(updateGroup(data));
+                    if (data.uuid) {
+                        dispatch(updateGroup(data));
+                    } else {
+                        dispatch(createGroup(data));
+                    }
                     break;
                 default:
                     break;
diff --git a/src/views-components/dialog-update/dialog-project-update.tsx b/src/views-components/dialog-update/dialog-project-update.tsx
index ac14e5dc..64f75433 100644
--- a/src/views-components/dialog-update/dialog-project-update.tsx
+++ b/src/views-components/dialog-update/dialog-project-update.tsx
@@ -7,19 +7,38 @@ import { InjectedFormProps } from 'redux-form';
 import { WithDialogProps } from 'store/dialog/with-dialog';
 import { ProjectUpdateFormDialogData } from 'store/projects/project-update-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 { GroupClass } from 'models/group';
 
-type DialogProjectProps = WithDialogProps<{}> & InjectedFormProps<ProjectUpdateFormDialogData>;
+type DialogProjectProps = WithDialogProps<{sourcePanel: GroupClass, showUsersField?: boolean}> & InjectedFormProps<ProjectUpdateFormDialogData>;
 
-export const DialogProjectUpdate = (props: DialogProjectProps) =>
-    <FormDialog
-        dialogTitle='Edit Project'
-        formFields={ProjectEditFields}
+export const DialogProjectUpdate = (props: DialogProjectProps) => {
+    let title = 'Edit Project';
+    let fields = ProjectEditFields;
+    const sourcePanel = props.data.sourcePanel || '';
+    const showUsersField = !!props.data.showUsersField;
+
+    if (sourcePanel === GroupClass.ROLE) {
+        title = showUsersField ? 'Create Group' : 'Edit Group';
+        fields = showUsersField ? GroupAddFields : ProjectEditFields;
+    }
+
+    return <FormDialog
+        dialogTitle={title}
+        formFields={fields}
         submitLabel='Save'
         {...props}
     />;
+};
 
+// Also used as "Group Edit Fields"
 const ProjectEditFields = () => <span>
     <ProjectNameField />
     <ProjectDescriptionField />
 </span>;
+
+const GroupAddFields = () => <span>
+    <ProjectNameField />
+    <UsersField />
+    <ProjectDescriptionField />
+</span>;
diff --git a/src/views-components/form-fields/project-form-fields.tsx b/src/views-components/form-fields/project-form-fields.tsx
index 34d7cef7..48348bab 100644
--- a/src/views-components/form-fields/project-form-fields.tsx
+++ b/src/views-components/form-fields/project-form-fields.tsx
@@ -3,11 +3,12 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import React from "react";
-import { Field, Validator } from "redux-form";
+import { Field, FieldArray, Validator, WrappedFieldArrayProps } from "redux-form";
 import { TextField, RichEditorTextField } from "components/text-field/text-field";
 import { PROJECT_NAME_VALIDATION, PROJECT_NAME_VALIDATION_ALLOW_SLASH } from "validators/validators";
 import { connect } from "react-redux";
 import { RootState } from "store/store";
+import { Participant, ParticipantSelect } from "views-components/sharing-dialog/participant-select";
 
 interface ProjectNameFieldProps {
     validate: Validator[];
@@ -42,3 +43,16 @@ export const ProjectDescriptionField = () =>
         name='description'
         component={RichEditorTextField as any}
         label="Description - optional" />;
+
+export const UsersField = () =>
+        <span data-cy='users-field'><FieldArray
+            name="users"
+            component={UsersSelect as any} /></span>;
+
+export const UsersSelect = ({ fields }: WrappedFieldArrayProps<Participant>) =>
+        <ParticipantSelect
+            onlyPeople
+            label='Enter email adresses '
+            items={fields.getAll() || []}
+            onSelect={fields.push}
+            onDelete={fields.remove} />;
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index c756a7d6..64caa6ca 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -82,7 +82,6 @@ import { HelpApiClientAuthorizationDialog } from 'views-components/api-client-au
 import { UserManageDialog } from 'views-components/user-dialog/manage-dialog';
 import { SetupShellAccountDialog } from 'views-components/dialog-forms/setup-shell-account-dialog';
 import { GroupsPanel } from 'views/groups-panel/groups-panel';
-import { CreateGroupDialog } from 'views-components/dialog-forms/create-group-dialog';
 import { RemoveGroupDialog } from 'views-components/groups-dialog/remove-dialog';
 import { GroupAttributesDialog } from 'views-components/groups-dialog/attributes-dialog';
 import { GroupDetailsPanel } from 'views/group-details-panel/group-details-panel';
@@ -221,7 +220,6 @@ export const WorkbenchPanel =
             <CopyCollectionDialog />
             <CopyProcessDialog />
             <CreateCollectionDialog />
-            <CreateGroupDialog />
             <CreateProjectDialog />
             <CreateRepositoryDialog />
             <CreateSshKeyDialog />

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list