[ARVADOS-WORKBENCH2] updated: 2.3.0-128-gf024fc6c

Git user git at public.arvados.org
Tue Jan 4 16:20:07 UTC 2022


Summary of changes:
 cypress/integration/collection.spec.js             | 26 +++---
 src/store/details-panel/details-panel-action.ts    | 11 +--
 .../create-collection-properties-form.tsx          |  1 -
 .../update-collection-properties-form.tsx          |  1 -
 .../details-panel/collection-details.tsx           | 62 ++++++++++++--
 .../details-panel/project-details.tsx              | 31 ++++---
 .../dialog-create/dialog-collection-create.tsx     | 46 +++++++----
 .../dialog-create/dialog-project-create.tsx        | 69 ++++++++++------
 .../dialog-update/dialog-collection-update.tsx     | 36 ++++++---
 .../dialog-update/dialog-project-update.tsx        | 40 ++++++---
 .../create-project-properties-form.tsx             |  1 -
 .../update-project-properties-form.tsx             |  1 -
 .../resource-properties-dialog-form.tsx            | 20 -----
 .../resource-properties-dialog.tsx                 | 94 ----------------------
 src/views/collection-panel/collection-panel.tsx    | 26 ++----
 src/views/workbench/workbench.tsx                  |  2 -
 16 files changed, 217 insertions(+), 250 deletions(-)
 delete mode 100644 src/views-components/resource-properties-dialog/resource-properties-dialog-form.tsx
 delete mode 100644 src/views-components/resource-properties-dialog/resource-properties-dialog.tsx

       via  f024fc6c50ad0473674ebb6e30ab227b98c5b661 (commit)
       via  5a5f30dbbfa1df4fd3dfade4cb5deab2a4ded56c (commit)
       via  670d92f78e9af2390b93e5d984f5fabf59a16071 (commit)
      from  f6396d366359d62ec22ca7a0efd4bf22a395f933 (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 f024fc6c50ad0473674ebb6e30ab227b98c5b661
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date:   Tue Jan 4 13:19:51 2022 -0300

    18219: Fixes tests.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>

diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index 32c1320b..51933887 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -120,7 +120,7 @@ describe('Collection panel tests', function () {
             });
     });
 
-    it('uses the property editor (from details panel) with vocabulary terms', function () {
+    it('uses the editor (from details panel) with vocabulary terms', function () {
         cy.createCollection(adminUser.token, {
             name: `Test collection ${Math.floor(Math.random() * 999999)}`,
             owner_uuid: activeUser.user.uuid,
@@ -139,7 +139,7 @@ describe('Collection panel tests', function () {
                 cy.get('[data-cy=details-panel]').within(() => {
                     cy.get('[data-cy=details-panel-edit-btn]').click();
                 });
-                cy.get('[data-cy=resource-properties-dialog').contains('Edit properties');
+                cy.get('[data-cy=form-dialog').contains('Edit Collection');
 
                 // Key: Color (IDTAGCOLORS) - Value: Magenta (IDVALCOLORS3)
                 cy.get('[data-cy=resource-properties-form]').within(() => {
@@ -152,14 +152,8 @@ describe('Collection panel tests', function () {
                     cy.root().submit();
                 });
                 // Confirm proper vocabulary labels are displayed on the UI.
-                cy.get('[data-cy=resource-properties-dialog]')
+                cy.get('[data-cy=form-dialog]')
                     .should('contain', 'Color: Magenta');
-                // Confirm proper vocabulary IDs were saved on the backend.
-                cy.doRequest('GET', `/arvados/v1/collections/${this.testCollection.uuid}`)
-                    .its('body').as('collection')
-                    .then(function () {
-                        expect(this.collection.properties.IDTAGCOLORS).to.equal('IDVALCOLORS3');
-                    });
 
                 // Case-insensitive on-blur auto-selection test
                 // Key: Size (IDTAGSIZES) - Value: Small (IDVALSIZES2)
@@ -176,19 +170,21 @@ describe('Collection panel tests', function () {
                     cy.root().submit();
                 });
                 // Confirm proper vocabulary labels are displayed on the UI.
-                cy.get('[data-cy=resource-properties-dialog]')
+                cy.get('[data-cy=form-dialog]')
                     .should('contain', 'Size: S');
+
+                cy.get('[data-cy=form-dialog]').contains('Save').click();
+                cy.get('[data-cy=form-dialog]').should('not.exist');
+
                 // Confirm proper vocabulary IDs were saved on the backend.
                 cy.doRequest('GET', `/arvados/v1/collections/${this.testCollection.uuid}`)
                     .its('body').as('collection')
                     .then(function () {
+                        expect(this.collection.properties.IDTAGCOLORS).to.equal('IDVALCOLORS3');
                         expect(this.collection.properties.IDTAGSIZES).to.equal('IDVALSIZES2');
                     });
 
-                // Close property editor & confirm properties display on the UI.
-                cy.get('[data-cy=resource-properties-dialog]').within(() => {
-                    cy.get('[data-cy=close-dialog-btn]').click();
-                });
+                // Confirm properties display on the UI.
                 cy.get('[data-cy=collection-info-panel')
                     .should('contain', this.testCollection.name)
                     .and('contain', 'Color: Magenta')
diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index 7f35ca65..f2b599e7 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -98,8 +98,8 @@ const CollectionInfo = withStyles(styles)(
     connect(ciMapStateToProps, ciMapDispatchToProps)(
         ({ currentCollection, editCollection, classes }: CollectionInfoProps) =>
             currentCollection !== undefined
-                ? <div data-cy='details-panel-edit-btn'>
-                    <Button onClick={() => editCollection(currentCollection)}>
+                ? <div>
+                    <Button data-cy='details-panel-edit-btn' onClick={() => editCollection(currentCollection)}>
                         <RenameIcon className={classes.editIcon} /> Edit
                     </Button>
                     <CollectionDetailsAttributes twoCol={false} item={currentCollection} />

commit 5a5f30dbbfa1df4fd3dfade4cb5deab2a4ded56c
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date:   Tue Jan 4 11:56:02 2022 -0300

    18219: Improves edit & create dialogs adding some separation between fields.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>

diff --git a/src/views-components/collection-properties/create-collection-properties-form.tsx b/src/views-components/collection-properties/create-collection-properties-form.tsx
index ab389ddc..3f19e158 100644
--- a/src/views-components/collection-properties/create-collection-properties-form.tsx
+++ b/src/views-components/collection-properties/create-collection-properties-form.tsx
@@ -18,7 +18,6 @@ const Form = withStyles(
     ({ spacing }) => (
         { container:
             {
-                paddingTop: spacing.unit,
                 margin: 0,
             }
         })
diff --git a/src/views-components/collection-properties/update-collection-properties-form.tsx b/src/views-components/collection-properties/update-collection-properties-form.tsx
index 940e318c..9092c7cc 100644
--- a/src/views-components/collection-properties/update-collection-properties-form.tsx
+++ b/src/views-components/collection-properties/update-collection-properties-form.tsx
@@ -18,7 +18,6 @@ const Form = withStyles(
     ({ spacing }) => (
         { container:
             {
-                paddingTop: spacing.unit,
                 margin: 0,
             }
         })
diff --git a/src/views-components/dialog-create/dialog-collection-create.tsx b/src/views-components/dialog-create/dialog-collection-create.tsx
index 163eb983..17a24e48 100644
--- a/src/views-components/dialog-create/dialog-collection-create.tsx
+++ b/src/views-components/dialog-create/dialog-collection-create.tsx
@@ -15,34 +15,46 @@ import {
 import { FileUploaderField } from '../file-uploader/file-uploader';
 import { ResourceParentField } from '../form-fields/resource-form-fields';
 import { CreateCollectionPropertiesForm } from 'views-components/collection-properties/create-collection-properties-form';
-import { FormGroup, FormLabel } from '@material-ui/core';
+import { FormGroup, FormLabel, StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
 import { resourcePropertiesList } from 'views-components/resource-properties/resource-properties-list';
 
+type CssRules = 'propertiesForm';
+
+const styles: StyleRulesCallback<CssRules> = theme => ({
+    propertiesForm: {
+        marginTop: theme.spacing.unit * 2,
+        marginBottom: theme.spacing.unit * 2,
+    },
+});
+
 type DialogCollectionProps = WithDialogProps<{}> & InjectedFormProps<CollectionCreateFormDialogData>;
 
 export const DialogCollectionCreate = (props: DialogCollectionProps) =>
     <FormDialog
         dialogTitle='New collection'
-        formFields={CollectionAddFields}
+        formFields={CollectionAddFields as any}
         submitLabel='Create a Collection'
         {...props}
     />;
 
 const CreateCollectionPropertiesList = resourcePropertiesList(COLLECTION_CREATE_FORM_NAME);
 
-const CollectionAddFields = () => <span>
-    <ResourceParentField />
-    <CollectionNameField />
-    <CollectionDescriptionField />
-    <FormLabel>Properties</FormLabel>
-    <FormGroup>
-        <CreateCollectionPropertiesForm />
-        <CreateCollectionPropertiesList />
-    </FormGroup>
-    <CollectionStorageClassesField defaultClasses={['default']} />
-    <Field
-        name='files'
-        label='Files'
-        component={FileUploaderField} />
-</span>;
+const CollectionAddFields = withStyles(styles)(
+    ({ classes }: WithStyles<CssRules>) => <span>
+        <ResourceParentField />
+        <CollectionNameField />
+        <CollectionDescriptionField />
+        <div className={classes.propertiesForm}>
+            <FormLabel>Properties</FormLabel>
+            <FormGroup>
+                <CreateCollectionPropertiesForm />
+                <CreateCollectionPropertiesList />
+            </FormGroup>
+        </div>
+        <CollectionStorageClassesField defaultClasses={['default']} />
+        <Field
+            name='files'
+            label='Files'
+            component={FileUploaderField} />
+    </span>);
 
diff --git a/src/views-components/dialog-create/dialog-project-create.tsx b/src/views-components/dialog-create/dialog-project-create.tsx
index 65da87d3..d85a304e 100644
--- a/src/views-components/dialog-create/dialog-project-create.tsx
+++ b/src/views-components/dialog-create/dialog-project-create.tsx
@@ -10,10 +10,23 @@ import { FormDialog } from 'components/form-dialog/form-dialog';
 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 { FormGroup, FormLabel, StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
 import { resourcePropertiesList } from 'views-components/resource-properties/resource-properties-list';
 import { GroupClass } from 'models/group';
 
+type CssRules = 'propertiesForm' | 'description';
+
+const styles: StyleRulesCallback<CssRules> = theme => ({
+    propertiesForm: {
+        marginTop: theme.spacing.unit * 2,
+        marginBottom: theme.spacing.unit * 2,
+    },
+    description: {
+        marginTop: theme.spacing.unit * 2,
+        marginBottom: theme.spacing.unit * 2,
+    },
+});
+
 type DialogProjectProps = WithDialogProps<{sourcePanel: GroupClass}> & InjectedFormProps<ProjectCreateFormDialogData>;
 
 export const DialogProjectCreate = (props: DialogProjectProps) => {
@@ -28,7 +41,7 @@ export const DialogProjectCreate = (props: DialogProjectProps) => {
 
     return <FormDialog
         dialogTitle={title}
-        formFields={fields}
+        formFields={fields as any}
         submitLabel='Create'
         {...props}
     />;
@@ -36,24 +49,34 @@ export const DialogProjectCreate = (props: DialogProjectProps) => {
 
 const CreateProjectPropertiesList = resourcePropertiesList(PROJECT_CREATE_FORM_NAME);
 
-const ProjectAddFields = () => <span>
-    <ResourceParentField />
-    <ProjectNameField />
-    <ProjectDescriptionField />
-    <FormLabel>Properties</FormLabel>
-    <FormGroup>
-        <CreateProjectPropertiesForm />
-        <CreateProjectPropertiesList />
-    </FormGroup>
-</span>;
-
-const GroupAddFields = () => <span>
-    <ProjectNameField />
-    <UsersField />
-    <ProjectDescriptionField />
-    <FormLabel>Properties</FormLabel>
-    <FormGroup>
-        <CreateProjectPropertiesForm />
-        <CreateProjectPropertiesList />
-    </FormGroup>
-</span>;
+const ProjectAddFields = withStyles(styles)(
+    ({ classes }: WithStyles<CssRules>) => <span>
+        <ResourceParentField />
+        <ProjectNameField />
+        <div className={classes.description}>
+            <ProjectDescriptionField />
+        </div>
+        <div className={classes.propertiesForm}>
+            <FormLabel>Properties</FormLabel>
+            <FormGroup>
+                <CreateProjectPropertiesForm />
+                <CreateProjectPropertiesList />
+            </FormGroup>
+        </div>
+    </span>);
+
+const GroupAddFields = withStyles(styles)(
+    ({ classes }: WithStyles<CssRules>) => <span>
+        <ProjectNameField />
+        <UsersField />
+        <div className={classes.description}>
+            <ProjectDescriptionField />
+        </div>
+        <div className={classes.propertiesForm}>
+            <FormLabel>Properties</FormLabel>
+            <FormGroup>
+                <CreateProjectPropertiesForm />
+                <CreateProjectPropertiesList />
+            </FormGroup>
+        </div>
+    </span>);
diff --git a/src/views-components/dialog-update/dialog-collection-update.tsx b/src/views-components/dialog-update/dialog-collection-update.tsx
index 852dab1a..d77d10ff 100644
--- a/src/views-components/dialog-update/dialog-collection-update.tsx
+++ b/src/views-components/dialog-update/dialog-collection-update.tsx
@@ -13,28 +13,40 @@ import {
     CollectionStorageClassesField
 } from 'views-components/form-fields/collection-form-fields';
 import { UpdateCollectionPropertiesForm } from 'views-components/collection-properties/update-collection-properties-form';
-import { FormGroup, FormLabel } from '@material-ui/core';
+import { FormGroup, FormLabel, StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core';
 import { resourcePropertiesList } from 'views-components/resource-properties/resource-properties-list';
 
+type CssRules = 'propertiesForm';
+
+const styles: StyleRulesCallback<CssRules> = theme => ({
+    propertiesForm: {
+        marginTop: theme.spacing.unit * 2,
+        marginBottom: theme.spacing.unit * 2,
+    },
+});
+
 type DialogCollectionProps = WithDialogProps<{}> & InjectedFormProps<CollectionUpdateFormDialogData>;
 
 export const DialogCollectionUpdate = (props: DialogCollectionProps) =>
     <FormDialog
         dialogTitle='Edit Collection'
-        formFields={CollectionEditFields}
+        formFields={CollectionEditFields as any}
         submitLabel='Save'
         {...props}
     />;
 
 const UpdateCollectionPropertiesList = resourcePropertiesList(COLLECTION_UPDATE_FORM_NAME);
 
-const CollectionEditFields = () => <span>
-    <CollectionNameField />
-    <CollectionDescriptionField />
-    <FormLabel>Properties</FormLabel>
-    <FormGroup>
-        <UpdateCollectionPropertiesForm />
-        <UpdateCollectionPropertiesList />
-    </FormGroup>
-    <CollectionStorageClassesField />
-</span>;
+const CollectionEditFields = withStyles(styles)(
+    ({ classes }: WithStyles<CssRules>) => <span>
+        <CollectionNameField />
+        <CollectionDescriptionField />
+        <div className={classes.propertiesForm}>
+            <FormLabel>Properties</FormLabel>
+            <FormGroup>
+                <UpdateCollectionPropertiesForm />
+                <UpdateCollectionPropertiesList />
+            </FormGroup>
+        </div>
+        <CollectionStorageClassesField />
+    </span>);
diff --git a/src/views-components/dialog-update/dialog-project-update.tsx b/src/views-components/dialog-update/dialog-project-update.tsx
index bad01815..a6ac65b1 100644
--- a/src/views-components/dialog-update/dialog-project-update.tsx
+++ b/src/views-components/dialog-update/dialog-project-update.tsx
@@ -9,10 +9,23 @@ import { ProjectUpdateFormDialogData, PROJECT_UPDATE_FORM_NAME } from 'store/pro
 import { FormDialog } from 'components/form-dialog/form-dialog';
 import { ProjectNameField, ProjectDescriptionField } from 'views-components/form-fields/project-form-fields';
 import { GroupClass } from 'models/group';
-import { FormGroup, FormLabel } from '@material-ui/core';
+import { FormGroup, FormLabel, StyleRulesCallback, WithStyles, withStyles } 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 CssRules = 'propertiesForm' | 'description';
+
+const styles: StyleRulesCallback<CssRules> = theme => ({
+    propertiesForm: {
+        marginTop: theme.spacing.unit * 2,
+        marginBottom: theme.spacing.unit * 2,
+    },
+    description: {
+        marginTop: theme.spacing.unit * 2,
+        marginBottom: theme.spacing.unit * 2,
+    },
+});
+
 type DialogProjectProps = WithDialogProps<{sourcePanel: GroupClass}> & InjectedFormProps<ProjectUpdateFormDialogData>;
 
 export const DialogProjectUpdate = (props: DialogProjectProps) => {
@@ -25,7 +38,7 @@ export const DialogProjectUpdate = (props: DialogProjectProps) => {
 
     return <FormDialog
         dialogTitle={title}
-        formFields={ProjectEditFields}
+        formFields={ProjectEditFields as any}
         submitLabel='Save'
         {...props}
     />;
@@ -34,12 +47,17 @@ export const DialogProjectUpdate = (props: DialogProjectProps) => {
 const UpdateProjectPropertiesList = resourcePropertiesList(PROJECT_UPDATE_FORM_NAME);
 
 // Also used as "Group Edit Fields"
-const ProjectEditFields = () => <span>
-    <ProjectNameField />
-    <ProjectDescriptionField />
-    <FormLabel>Properties</FormLabel>
-    <FormGroup>
-        <UpdateProjectPropertiesForm />
-        <UpdateProjectPropertiesList />
-    </FormGroup>
-</span>;
+const ProjectEditFields = withStyles(styles)(
+    ({ classes }: WithStyles<CssRules>) => <span>
+        <ProjectNameField />
+        <div className={classes.description}>
+            <ProjectDescriptionField />
+        </div>
+        <div className={classes.propertiesForm}>
+            <FormLabel>Properties</FormLabel>
+            <FormGroup>
+                <UpdateProjectPropertiesForm />
+                <UpdateProjectPropertiesList />
+            </FormGroup>
+        </div>
+    </span>);
diff --git a/src/views-components/project-properties/create-project-properties-form.tsx b/src/views-components/project-properties/create-project-properties-form.tsx
index aa9965b5..8c26523e 100644
--- a/src/views-components/project-properties/create-project-properties-form.tsx
+++ b/src/views-components/project-properties/create-project-properties-form.tsx
@@ -18,7 +18,6 @@ const Form = withStyles(
     ({ spacing }) => (
         { container:
             {
-                paddingTop: spacing.unit,
                 margin: 0,
             }
         })
diff --git a/src/views-components/project-properties/update-project-properties-form.tsx b/src/views-components/project-properties/update-project-properties-form.tsx
index e6151229..0b5554bc 100644
--- a/src/views-components/project-properties/update-project-properties-form.tsx
+++ b/src/views-components/project-properties/update-project-properties-form.tsx
@@ -18,7 +18,6 @@ const Form = withStyles(
     ({ spacing }) => (
         { container:
             {
-                paddingTop: spacing.unit,
                 margin: 0,
             }
         })

commit 670d92f78e9af2390b93e5d984f5fabf59a16071
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date:   Tue Jan 4 10:58:18 2022 -0300

    18219: Replaces edit props dialog with full editor on details panel.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>

diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index ce711be9..32c1320b 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -137,7 +137,7 @@ describe('Collection panel tests', function () {
                 cy.get('[data-cy=additional-info-icon]').click();
 
                 cy.get('[data-cy=details-panel]').within(() => {
-                    cy.get('[data-cy=property-editor-btn]').click();
+                    cy.get('[data-cy=details-panel-edit-btn]').click();
                 });
                 cy.get('[data-cy=resource-properties-dialog').contains('Edit properties');
 
diff --git a/src/store/details-panel/details-panel-action.ts b/src/store/details-panel/details-panel-action.ts
index 90ca0f4f..b708ad62 100644
--- a/src/store/details-panel/details-panel-action.ts
+++ b/src/store/details-panel/details-panel-action.ts
@@ -5,11 +5,10 @@
 import { unionize, ofType, UnionOf } from 'common/unionize';
 import { RootState } from 'store/store';
 import { Dispatch } from 'redux';
-import { dialogActions } from 'store/dialog/dialog-actions';
 import { getResource } from 'store/resources/resources';
 import { ServiceRepository } from 'services/services';
 import { resourcesActions } from 'store/resources/resources-actions';
-import {snackbarActions, SnackbarKind} from 'store/snackbar/snackbar-actions';
+import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
 import { FilterBuilder } from 'services/api/filter-builder';
 import { OrderBuilder } from 'services/api/order-builder';
 import { CollectionResource } from 'models/collection';
@@ -25,9 +24,6 @@ export const detailsPanelActions = unionize({
 
 export type DetailsPanelAction = UnionOf<typeof detailsPanelActions>;
 
-export const RESOURCE_PROPERTIES_FORM_NAME = 'resourcePropertiesFormName';
-export const RESOURCE_PROPERTIES_DIALOG_NAME = 'resourcePropertiesDialogName';
-
 export const loadDetailsPanel = (uuid: string) =>
     (dispatch: Dispatch, getState: () => RootState) => {
         if (getState().detailsPanel.isOpened) {
@@ -51,11 +47,6 @@ export const openDetailsPanel = (uuid?: string, tabNr: number = 0) =>
         }
     };
 
-export const openResourcePropertiesDialog = () =>
-    (dispatch: Dispatch) => {
-        dispatch<any>(dialogActions.OPEN_DIALOG({ id: RESOURCE_PROPERTIES_DIALOG_NAME, data: { } }));
-    };
-
 export const refreshCollectionVersionsList = (uuid: string) =>
     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         services.collectionService.list({
diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index dcd2ee48..7f35ca65 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -3,21 +3,22 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import React from 'react';
-import { CollectionIcon } from 'components/icon/icon';
+import { CollectionIcon, RenameIcon } from 'components/icon/icon';
 import { CollectionResource } from 'models/collection';
 import { DetailsData } from "./details-data";
 import { CollectionDetailsAttributes } from 'views/collection-panel/collection-panel';
 import { RootState } from 'store/store';
 import { filterResources, getResource } from 'store/resources/resources';
 import { connect } from 'react-redux';
-import { Grid, ListItem, StyleRulesCallback, Typography, withStyles, WithStyles } from '@material-ui/core';
+import { Button, Grid, ListItem, StyleRulesCallback, Typography, withStyles, WithStyles } from '@material-ui/core';
 import { formatDate, formatFileSize } from 'common/formatters';
 import { UserNameFromID } from '../data-explorer/renderers';
 import { Dispatch } from 'redux';
 import { navigateTo } from 'store/navigation/navigation-action';
 import { openContextMenu, resourceUuidToContextMenuKind } from 'store/context-menu/context-menu-actions';
+import { openCollectionUpdateDialog } from 'store/collections/collection-update-actions';
 
-export type CssRules = 'versionBrowserHeader' | 'versionBrowserItem' | 'versionBrowserField';
+export type CssRules = 'versionBrowserHeader' | 'versionBrowserItem' | 'versionBrowserField' | 'editIcon';
 
 const styles: StyleRulesCallback<CssRules> = theme => ({
     versionBrowserHeader: {
@@ -29,7 +30,11 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
     },
     versionBrowserField: {
         textAlign: 'center',
-    }
+    },
+    editIcon: {
+        paddingRight: theme.spacing.unit/2,
+        fontSize: '1.125rem',
+    },
 });
 
 export class CollectionDetails extends DetailsData<CollectionResource> {
@@ -54,7 +59,7 @@ export class CollectionDetails extends DetailsData<CollectionResource> {
     }
 
     private getCollectionInfo() {
-        return <CollectionDetailsAttributes twoCol={false} item={this.item} />;
+        return <CollectionInfo />;
     }
 
     private getVersionBrowser() {
@@ -62,6 +67,47 @@ export class CollectionDetails extends DetailsData<CollectionResource> {
     }
 }
 
+interface CollectionInfoDataProps {
+    currentCollection: CollectionResource | undefined;
+}
+
+interface CollectionInfoDispatchProps {
+    editCollection: (collection: CollectionResource | undefined) => void;
+}
+
+const ciMapStateToProps = (state: RootState): CollectionInfoDataProps => {
+    return {
+        currentCollection: getResource<CollectionResource>(state.detailsPanel.resourceUuid)(state.resources),
+    };
+};
+
+const ciMapDispatchToProps = (dispatch: Dispatch): CollectionInfoDispatchProps => ({
+    editCollection: (collection: CollectionResource) =>
+        dispatch<any>(openCollectionUpdateDialog({
+            uuid: collection.uuid,
+            name: collection.name,
+            description: collection.description,
+            properties: collection.properties,
+            storageClassesDesired: collection.storageClassesDesired,
+        })),
+});
+
+type CollectionInfoProps = CollectionInfoDataProps & CollectionInfoDispatchProps & WithStyles<CssRules>;
+
+const CollectionInfo = withStyles(styles)(
+    connect(ciMapStateToProps, ciMapDispatchToProps)(
+        ({ currentCollection, editCollection, classes }: CollectionInfoProps) =>
+            currentCollection !== undefined
+                ? <div data-cy='details-panel-edit-btn'>
+                    <Button onClick={() => editCollection(currentCollection)}>
+                        <RenameIcon className={classes.editIcon} /> Edit
+                    </Button>
+                    <CollectionDetailsAttributes twoCol={false} item={currentCollection} />
+                </div>
+                : <div />
+    )
+);
+
 interface CollectionVersionBrowserProps {
     currentCollection: CollectionResource | undefined;
     versions: CollectionResource[];
@@ -72,7 +118,7 @@ interface CollectionVersionBrowserDispatchProps {
     handleContextMenu: (event: React.MouseEvent<HTMLElement>, collection: CollectionResource) => void;
 }
 
-const mapStateToProps = (state: RootState): CollectionVersionBrowserProps => {
+const vbMapStateToProps = (state: RootState): CollectionVersionBrowserProps => {
     const currentCollection = getResource<CollectionResource>(state.detailsPanel.resourceUuid)(state.resources);
     const versions = (currentCollection
         && filterResources(rsc =>
@@ -82,7 +128,7 @@ const mapStateToProps = (state: RootState): CollectionVersionBrowserProps => {
     return { currentCollection, versions };
 };
 
-const mapDispatchToProps = () =>
+const vbMapDispatchToProps = () =>
     (dispatch: Dispatch): CollectionVersionBrowserDispatchProps => ({
         showVersion: (collection) => dispatch<any>(navigateTo(collection.uuid)),
         handleContextMenu: (event: React.MouseEvent<HTMLElement>, collection: CollectionResource) => {
@@ -103,7 +149,7 @@ const mapDispatchToProps = () =>
     });
 
 const CollectionVersionBrowser = withStyles(styles)(
-    connect(mapStateToProps, mapDispatchToProps)(
+    connect(vbMapStateToProps, vbMapDispatchToProps)(
         ({ currentCollection, versions, showVersion, handleContextMenu, classes }: CollectionVersionBrowserProps & CollectionVersionBrowserDispatchProps & WithStyles<CssRules>) => {
             return <div data-cy="collection-version-browser">
                 <Grid container>
diff --git a/src/views-components/details-panel/project-details.tsx b/src/views-components/details-panel/project-details.tsx
index 82e3e754..c3c3d68e 100644
--- a/src/views-components/details-panel/project-details.tsx
+++ b/src/views-components/details-panel/project-details.tsx
@@ -4,7 +4,6 @@
 
 import React from 'react';
 import { connect } from 'react-redux';
-import { openResourcePropertiesDialog } from 'store/details-panel/details-panel-action';
 import { ProjectIcon, RenameIcon, FilterGroupIcon } from 'components/icon/icon';
 import { ProjectResource } from 'models/project';
 import { formatDate } from 'common/formatters';
@@ -13,12 +12,13 @@ import { resourceLabel } from 'common/labels';
 import { DetailsData } from "./details-data";
 import { DetailsAttribute } from "components/details-attribute/details-attribute";
 import { RichTextEditorLink } from 'components/rich-text-editor-link/rich-text-editor-link';
-import { withStyles, StyleRulesCallback, WithStyles } from '@material-ui/core';
+import { withStyles, StyleRulesCallback, WithStyles, Button } from '@material-ui/core';
 import { ArvadosTheme } from 'common/custom-theme';
 import { Dispatch } from 'redux';
 import { getPropertyChip } from '../resource-properties-form/property-chip';
 import { ResourceOwnerWithName } from '../data-explorer/renderers';
 import { GroupClass } from "models/group";
+import { openProjectUpdateDialog, ProjectUpdateFormDialogData } from 'store/projects/project-update-actions';
 
 export class ProjectDetails extends DetailsData<ProjectResource> {
     getIcon(className?: string) {
@@ -41,8 +41,8 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         marginBottom: theme.spacing.unit
     },
     editIcon: {
+        paddingRight: theme.spacing.unit/2,
         fontSize: '1.125rem',
-        cursor: 'pointer'
     }
 });
 
@@ -51,11 +51,12 @@ interface ProjectDetailsComponentDataProps {
 }
 
 interface ProjectDetailsComponentActionProps {
-    onClick: () => void;
+    onClick: (prj: ProjectUpdateFormDialogData) => () => void;
 }
 
 const mapDispatchToProps = (dispatch: Dispatch) => ({
-    onClick: () => dispatch<any>(openResourcePropertiesDialog()),
+    onClick: (prj: ProjectUpdateFormDialogData) =>
+        () => dispatch<any>(openProjectUpdateDialog(prj)),
 });
 
 type ProjectDetailsComponentProps = ProjectDetailsComponentDataProps & ProjectDetailsComponentActionProps & WithStyles<CssRules>;
@@ -63,6 +64,17 @@ type ProjectDetailsComponentProps = ProjectDetailsComponentDataProps & ProjectDe
 const ProjectDetailsComponent = connect(null, mapDispatchToProps)(
     withStyles(styles)(
         ({ classes, project, onClick }: ProjectDetailsComponentProps) => <div>
+            {project.groupClass !== GroupClass.FILTER ?
+                    <Button onClick={onClick({
+                        uuid: project.uuid,
+                        name: project.name,
+                        description: project.description,
+                        properties: project.properties,
+                    })}>
+                        <RenameIcon className={classes.editIcon} /> Edit
+                    </Button>
+                    : ''
+                }
             <DetailsAttribute label='Type' value={project.groupClass === GroupClass.FILTER ? 'Filter group' : resourceLabel(ResourceKind.PROJECT)} />
             <DetailsAttribute label='Owner' linkToUuid={project.ownerUuid}
                 uuidEnhancer={(uuid: string) => <ResourceOwnerWithName uuid={uuid} />} />
@@ -78,14 +90,7 @@ const ProjectDetailsComponent = connect(null, mapDispatchToProps)(
                     : '---'
                 }
             </DetailsAttribute>
-            <DetailsAttribute label='Properties'>
-                {project.groupClass !== GroupClass.FILTER ?
-                    <div onClick={onClick}>
-                        <RenameIcon className={classes.editIcon} />
-                    </div>
-                    : ''
-                }
-            </DetailsAttribute>
+            <DetailsAttribute label='Properties' />
             {
                 Object.keys(project.properties).map(k =>
                     Array.isArray(project.properties[k])
diff --git a/src/views-components/resource-properties-dialog/resource-properties-dialog-form.tsx b/src/views-components/resource-properties-dialog/resource-properties-dialog-form.tsx
deleted file mode 100644
index cfb999cc..00000000
--- a/src/views-components/resource-properties-dialog/resource-properties-dialog-form.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { reduxForm, reset } from 'redux-form';
-import { RESOURCE_PROPERTIES_FORM_NAME } from 'store/details-panel/details-panel-action';
-import { ResourcePropertiesForm, ResourcePropertiesFormData } from 'views-components/resource-properties-form/resource-properties-form';
-import { withStyles } from '@material-ui/core';
-import { Dispatch } from 'redux';
-import { createResourceProperty } from 'store/resources/resources-actions';
-
-const Form = withStyles(({ spacing }) => ({ container: { marginBottom: spacing.unit * 2 } }))(ResourcePropertiesForm);
-
-export const ResourcePropertiesDialogForm = reduxForm<ResourcePropertiesFormData, {uuid: string}>({
-    form: RESOURCE_PROPERTIES_FORM_NAME,
-    onSubmit: (data, dispatch: Dispatch) => {
-        dispatch<any>(createResourceProperty(data));
-        dispatch(reset(RESOURCE_PROPERTIES_FORM_NAME));
-    }
-})(Form);
diff --git a/src/views-components/resource-properties-dialog/resource-properties-dialog.tsx b/src/views-components/resource-properties-dialog/resource-properties-dialog.tsx
deleted file mode 100644
index 2502f50a..00000000
--- a/src/views-components/resource-properties-dialog/resource-properties-dialog.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import React from "react";
-import { Dispatch } from "redux";
-import { connect } from "react-redux";
-import { RootState } from 'store/store';
-import { withDialog, WithDialogProps } from "store/dialog/with-dialog";
-import { RESOURCE_PROPERTIES_DIALOG_NAME } from 'store/details-panel/details-panel-action';
-import {
-    Dialog,
-    DialogTitle,
-    DialogContent,
-    DialogActions,
-    Button,
-    withStyles,
-    StyleRulesCallback,
-    WithStyles
-} from '@material-ui/core';
-import { ArvadosTheme } from 'common/custom-theme';
-import { ResourcePropertiesDialogForm } from 'views-components/resource-properties-dialog/resource-properties-dialog-form';
-import { getResource } from 'store/resources/resources';
-import { getPropertyChip } from "../resource-properties-form/property-chip";
-import { deleteResourceProperty } from "store/resources/resources-actions";
-import { ResourceWithProperties } from "models/resource";
-
-type CssRules = 'tag';
-
-const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
-    tag: {
-        marginRight: theme.spacing.unit,
-        marginBottom: theme.spacing.unit
-    }
-});
-
-interface ResourcePropertiesDialogDataProps {
-    resource: ResourceWithProperties;
-}
-
-interface ResourcePropertiesDialogActionProps {
-    handleDelete: (uuid: string, key: string, value: string) => void;
-}
-
-const mapStateToProps = ({ detailsPanel, resources, properties }: RootState): ResourcePropertiesDialogDataProps => ({
-    resource: getResource(detailsPanel.resourceUuid)(resources) as ResourceWithProperties,
-});
-
-const mapDispatchToProps = (dispatch: Dispatch): ResourcePropertiesDialogActionProps => ({
-    handleDelete: (uuid: string, key: string, value: string) => () => dispatch<any>(deleteResourceProperty(uuid, key, value)),
-});
-
-type ResourcePropertiesDialogProps = ResourcePropertiesDialogDataProps & ResourcePropertiesDialogActionProps & WithDialogProps<{}> & WithStyles<CssRules>;
-
-export const ResourcePropertiesDialog = connect(mapStateToProps, mapDispatchToProps)(
-    withStyles(styles)(
-        withDialog(RESOURCE_PROPERTIES_DIALOG_NAME)(
-            ({ classes, open, closeDialog, handleDelete, resource }: ResourcePropertiesDialogProps) =>
-                <Dialog open={open}
-                    onClose={closeDialog}
-                    fullWidth
-                    maxWidth='sm'>
-                    <div data-cy='resource-properties-dialog'>
-                    <DialogTitle>Edit properties</DialogTitle>
-                    <DialogContent>
-                        <ResourcePropertiesDialogForm uuid={resource ? resource.uuid : ''} />
-                        {resource && resource.properties &&
-                            Object.keys(resource.properties).map(k =>
-                                Array.isArray(resource.properties[k])
-                                    ? resource.properties[k].map((v: string) =>
-                                        getPropertyChip(
-                                            k, v,
-                                            handleDelete(resource.uuid, k, v),
-                                            classes.tag))
-                                    : getPropertyChip(
-                                        k, resource.properties[k],
-                                        handleDelete(resource.uuid, k, resource.properties[k]),
-                                        classes.tag)
-                            )
-                        }
-                    </DialogContent>
-                    <DialogActions>
-                        <Button
-                            data-cy='close-dialog-btn'
-                            variant='text'
-                            color='primary'
-                            onClick={closeDialog}>
-                            Close
-                    </Button>
-                    </DialogActions>
-                    </div>
-                </Dialog>
-            )
-    ));
diff --git a/src/views/collection-panel/collection-panel.tsx b/src/views/collection-panel/collection-panel.tsx
index 851008c0..2c7a8f2c 100644
--- a/src/views/collection-panel/collection-panel.tsx
+++ b/src/views/collection-panel/collection-panel.tsx
@@ -3,7 +3,6 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import React from 'react';
-import { Dispatch } from 'redux';
 import {
     StyleRulesCallback,
     WithStyles,
@@ -18,7 +17,7 @@ import { connect, DispatchProp } from "react-redux";
 import { RouteComponentProps } from 'react-router';
 import { ArvadosTheme } from 'common/custom-theme';
 import { RootState } from 'store/store';
-import { MoreOptionsIcon, CollectionIcon, ReadOnlyIcon, CollectionOldVersionIcon, RenameIcon } from 'components/icon/icon';
+import { MoreOptionsIcon, CollectionIcon, ReadOnlyIcon, CollectionOldVersionIcon } from 'components/icon/icon';
 import { DetailsAttribute } from 'components/details-attribute/details-attribute';
 import { CollectionResource, getCollectionUrl } from 'models/collection';
 import { CollectionPanelFiles } from 'views-components/collection-panel-files/collection-panel-files';
@@ -26,7 +25,7 @@ import { navigateToProcess, collectionPanelActions } from 'store/collection-pane
 import { getResource } from 'store/resources/resources';
 import { openContextMenu, resourceUuidToContextMenuKind } from 'store/context-menu/context-menu-actions';
 import { formatDate, formatFileSize } from "common/formatters";
-import { openDetailsPanel, openResourcePropertiesDialog } from 'store/details-panel/details-panel-action';
+import { openDetailsPanel } from 'store/details-panel/details-panel-action';
 import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
 import { getPropertyChip } from 'views-components/resource-properties-form/property-chip';
 import { IllegalNamingWarning } from 'components/warning/warning';
@@ -261,10 +260,6 @@ export const CollectionPanel = withStyles(styles)(
     )
 );
 
-interface CollectionDetailsActionProps {
-    onClick: () => void;
-}
-
 interface CollectionDetailsProps {
     item: CollectionResource;
     classes?: any;
@@ -272,12 +267,7 @@ interface CollectionDetailsProps {
     showVersionBrowser?: () => void;
 }
 
-const mapDispatchToProps = (dispatch: Dispatch) => ({
-    onClick: () => dispatch<any>(openResourcePropertiesDialog()),
-});
-
-export const CollectionDetailsAttributes = connect(null, mapDispatchToProps)(
-(props: CollectionDetailsProps & CollectionDetailsActionProps) => {
+export const CollectionDetailsAttributes = (props: CollectionDetailsProps) => {
     const item = props.item;
     const classes = props.classes || { label: '', value: '', button: '', tag: '' };
     const isOldVersion = item && item.currentVersionUuid !== item.uuid;
@@ -345,13 +335,7 @@ export const CollectionDetailsAttributes = connect(null, mapDispatchToProps)(
         </Grid>
         <Grid item xs={12} md={mdSize}>
             <DetailsAttribute classLabel={classes.label} classValue={classes.value}
-                label='Properties'>
-                { !props.twoCol
-                    ? <div data-cy='property-editor-btn' onClick={props.onClick}>
-                        <RenameIcon className={classes.editIcon} />
-                    </div>
-                    : '' }
-            </DetailsAttribute>
+                label='Properties' />
             { Object.keys(item.properties).length > 0
                 ? Object.keys(item.properties).map(k =>
                         Array.isArray(item.properties[k])
@@ -361,4 +345,4 @@ export const CollectionDetailsAttributes = connect(null, mapDispatchToProps)(
                 : <div className={classes.value}>No properties</div> }
         </Grid>
     </Grid>;
-});
+};
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index ea24c872..e7bb048f 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -54,7 +54,6 @@ import { AdvancedTabDialog } from 'views-components/advanced-tab-dialog/advanced
 import { ProcessInputDialog } from 'views-components/process-input-dialog/process-input-dialog';
 import { VirtualMachineUserPanel } from 'views/virtual-machine-panel/virtual-machine-user-panel';
 import { VirtualMachineAdminPanel } from 'views/virtual-machine-panel/virtual-machine-admin-panel';
-import { ResourcePropertiesDialog } from 'views-components/resource-properties-dialog/resource-properties-dialog';
 import { RepositoriesPanel } from 'views/repositories-panel/repositories-panel';
 import { KeepServicePanel } from 'views/keep-service-panel/keep-service-panel';
 import { ApiClientAuthorizationPanel } from 'views/api-client-authorization-panel/api-client-authorization-panel';
@@ -242,7 +241,6 @@ export const WorkbenchPanel =
             <PartialCopyToCollectionDialog />
             <ProcessCommandDialog />
             <ProcessInputDialog />
-            <ResourcePropertiesDialog />
             <RestoreCollectionVersionDialog />
             <RemoveApiClientAuthorizationDialog />
             <RemoveGroupDialog />

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list