[ARVADOS-WORKBENCH2] updated: 2.1.0-97-g7b8e48c2

Git user git at public.arvados.org
Wed Nov 18 23:16:14 UTC 2020


Summary of changes:
 .../collection-panel/collection-panel-action.ts    | 57 ++++++++++++----------
 .../collection-panel-files-actions.ts              | 50 ++++++++++---------
 src/store/collections/collection-move-actions.ts   |  3 +-
 src/store/collections/collection-update-actions.ts | 34 +++++++++----
 src/store/details-panel/details-panel-action.ts    | 12 +++--
 src/store/workbench/workbench-actions.ts           | 19 --------
 src/views-components/data-explorer/renderers.tsx   |  4 +-
 .../details-panel/collection-details.tsx           | 51 +++++++++++--------
 .../details-panel/details-panel.tsx                | 23 +++++++--
 .../dialog-forms/update-collection-dialog.ts       |  3 +-
 src/views/collection-panel/collection-panel.tsx    | 16 +++---
 11 files changed, 152 insertions(+), 120 deletions(-)

       via  7b8e48c2f9130d799a42c81440bc8b4e04224d4e (commit)
       via  83931f3e2ec3652900ed733f8a35f8be018d39d7 (commit)
       via  0e3fc3157269a28e533333397cc20ec95ff093df (commit)
       via  3426a94b3d8c56ae1d63da004e8c30de75e5881d (commit)
       via  e83d929135335433aca0e47b5892c7c60ffa394f (commit)
       via  4b6b871dfa9aefaf1e9ca31e38d33a71a422064d (commit)
       via  0cd27bb15628e8a94741b96396b12048fc3f31b3 (commit)
       via  d5e2ff533dc37c1d8ee1fc320ef5319c7514427d (commit)
      from  b7f96fb678f9b48c3762e0c1ab29157b11bda869 (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 7b8e48c2f9130d799a42c81440bc8b4e04224d4e
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Wed Nov 18 18:46:21 2020 -0300

    13494: Makes several operations asynchronous.
    
    Details panel's collection version browser refresh, property addition and
    removal, file renaming and removal are now asynchronous.
    Also, the details panel gets reloaded when this collection operations take
    place.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/store/collection-panel/collection-panel-action.ts b/src/store/collection-panel/collection-panel-action.ts
index 851ba84d..58407b90 100644
--- a/src/store/collection-panel/collection-panel-action.ts
+++ b/src/store/collection-panel/collection-panel-action.ts
@@ -44,27 +44,32 @@ export const loadCollectionPanel = (uuid: string) =>
     };
 
 export const createCollectionTag = (data: TagProperty) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const item = getState().collectionPanel.item;
         if (!item) { return; }
 
         const properties = Object.assign({}, item.properties);
-        try {
-            const key = data.keyID || data.key;
-            const value = data.valueID || data.value;
-            const updatedCollection = await services.collectionService.update(
-                item.uuid, {
-                    properties: addProperty(properties, key, value)
-                }
-            );
+        const key = data.keyID || data.key;
+        const value = data.valueID || data.value;
+        services.collectionService.update(
+            item.uuid, {
+                properties: addProperty(properties, key, value)
+            }
+        ).then(updatedCollection => {
             dispatch(collectionPanelActions.SET_COLLECTION(updatedCollection));
             dispatch(resourcesActions.SET_RESOURCES([updatedCollection]));
-            dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Tag has been successfully added.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
+            dispatch(snackbarActions.OPEN_SNACKBAR({
+                message: "Tag has been successfully added.",
+                hideDuration: 2000,
+                kind: SnackbarKind.SUCCESS }));
+            dispatch<any>(loadDetailsPanel(updatedCollection.uuid));
             return updatedCollection;
-        } catch (e) {
-            dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.errors[0], hideDuration: 2000, kind: SnackbarKind.ERROR }));
-            return;
-        }
+        }).catch (e =>
+            dispatch(snackbarActions.OPEN_SNACKBAR({
+                message: e.errors[0],
+                hideDuration: 2000,
+                kind: SnackbarKind.ERROR }))
+        );
     };
 
 export const navigateToProcess = (uuid: string) =>
@@ -78,23 +83,25 @@ export const navigateToProcess = (uuid: string) =>
     };
 
 export const deleteCollectionTag = (key: string, value: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const item = getState().collectionPanel.item;
         if (!item) { return; }
 
         const properties = Object.assign({}, item.properties);
-        try {
-            const updatedCollection = await services.collectionService.update(
-                item.uuid, {
-                    properties: deleteProperty(properties, key, value)
-                }
-            );
+        services.collectionService.update(
+            item.uuid, {
+                properties: deleteProperty(properties, key, value)
+            }
+        ).then(updatedCollection => {
             dispatch(collectionPanelActions.SET_COLLECTION(updatedCollection));
             dispatch(resourcesActions.SET_RESOURCES([updatedCollection]));
             dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Tag has been successfully deleted.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
+            dispatch<any>(loadDetailsPanel(updatedCollection.uuid));
             return updatedCollection;
-        } catch (e) {
-            dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.errors[0], hideDuration: 2000, kind: SnackbarKind.ERROR }));
-            return;
-        }
+        }).catch (e => {
+            dispatch(snackbarActions.OPEN_SNACKBAR({
+                message: e.errors[0],
+                hideDuration: 2000,
+                kind: SnackbarKind.ERROR }));
+        });
     };
diff --git a/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts b/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts
index 7b2b2557..1d2a40b2 100644
--- a/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts
+++ b/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts
@@ -15,6 +15,7 @@ import { startSubmit, stopSubmit, initialize, FormErrors } from 'redux-form';
 import { getDialog } from "~/store/dialog/dialog-reducer";
 import { getFileFullPath, sortFilesTree } from "~/services/collection-service/collection-service-files-response";
 import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
+import { loadDetailsPanel } from "~/store/details-panel/details-panel-action";
 
 export const collectionPanelFilesAction = unionize({
     SET_COLLECTION_FILES: ofType<CollectionFilesTree>(),
@@ -31,39 +32,44 @@ export const COLLECTION_PANEL_LOAD_FILES = 'collectionPanelLoadFiles';
 export const COLLECTION_PANEL_LOAD_FILES_THRESHOLD = 40000;
 
 export const loadCollectionFiles = (uuid: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         dispatch(progressIndicatorActions.START_WORKING(COLLECTION_PANEL_LOAD_FILES));
-        const files = await services.collectionService.files(uuid);
-
-        // Given the array of directories and files, create the appropriate tree nodes,
-        // sort them, and add the complete url to each.
-        const tree = createCollectionFilesTree(files);
-        const sorted = sortFilesTree(tree);
-        const mapped = mapTreeValues(services.collectionService.extendFileURL)(sorted);
-        dispatch(collectionPanelFilesAction.SET_COLLECTION_FILES(mapped));
-        dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PANEL_LOAD_FILES));
+        services.collectionService.files(uuid).then(files => {
+            // Given the array of directories and files, create the appropriate tree nodes,
+            // sort them, and add the complete url to each.
+            const tree = createCollectionFilesTree(files);
+            const sorted = sortFilesTree(tree);
+            const mapped = mapTreeValues(services.collectionService.extendFileURL)(sorted);
+            dispatch(collectionPanelFilesAction.SET_COLLECTION_FILES(mapped));
+            dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PANEL_LOAD_FILES));
+        }).catch(e => {
+            dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PANEL_LOAD_FILES));
+            dispatch(snackbarActions.OPEN_SNACKBAR({
+                message: `Error getting file list: ${e.errors[0]}`,
+                hideDuration: 2000,
+                kind: SnackbarKind.ERROR }));
+        });
     };
 
 export const removeCollectionFiles = (filePaths: string[]) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const currentCollection = getState().collectionPanel.item;
         if (currentCollection) {
-            dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removing...' }));
-            try {
-                await services.collectionService.deleteFiles(currentCollection.uuid, filePaths);
+            services.collectionService.deleteFiles(currentCollection.uuid, filePaths).then(() => {
                 dispatch<any>(loadCollectionFiles(currentCollection.uuid));
                 dispatch(snackbarActions.OPEN_SNACKBAR({
                     message: 'Removed.',
                     hideDuration: 2000,
                     kind: SnackbarKind.SUCCESS
                 }));
-            } catch (e) {
+                dispatch<any>(loadDetailsPanel(currentCollection.uuid));
+            }).catch(e =>
                 dispatch(snackbarActions.OPEN_SNACKBAR({
                     message: 'Could not remove file.',
                     hideDuration: 2000,
                     kind: SnackbarKind.ERROR
-                }));
-            }
+                }))
+            );
         }
     };
 
@@ -131,7 +137,7 @@ export const openRenameFileDialog = (data: RenameFileDialogData) =>
     };
 
 export const renameFile = (newFullPath: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const dialog = getDialog<RenameFileDialogData>(getState().dialog, RENAME_FILE_DIALOG);
         const currentCollection = getState().collectionPanel.item;
         if (dialog && currentCollection) {
@@ -140,17 +146,17 @@ export const renameFile = (newFullPath: string) =>
                 dispatch(startSubmit(RENAME_FILE_DIALOG));
                 const oldPath = getFileFullPath(file);
                 const newPath = newFullPath;
-                try {
-                    await services.collectionService.moveFile(currentCollection.uuid, oldPath, newPath);
+                services.collectionService.moveFile(currentCollection.uuid, oldPath, newPath).then(() => {
                     dispatch<any>(loadCollectionFiles(currentCollection.uuid));
                     dispatch(dialogActions.CLOSE_DIALOG({ id: RENAME_FILE_DIALOG }));
                     dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'File name changed.', hideDuration: 2000 }));
-                } catch (e) {
+                    dispatch<any>(loadDetailsPanel(currentCollection.uuid));
+                }).catch (e => {
                     const errors: FormErrors<RenameFileDialogData, string> = {
                         path: `Could not rename the file: ${e.responseText}`
                     };
                     dispatch(stopSubmit(RENAME_FILE_DIALOG, errors));
-                }
+                });
             }
         }
     };
diff --git a/src/store/details-panel/details-panel-action.ts b/src/store/details-panel/details-panel-action.ts
index 69b69d3b..91ca9cba 100644
--- a/src/store/details-panel/details-panel-action.ts
+++ b/src/store/details-panel/details-panel-action.ts
@@ -61,15 +61,19 @@ export const openProjectPropertiesDialog = () =>
     };
 
 export const refreshCollectionVersionsList = (uuid: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const versions = await services.collectionService.list({
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+        services.collectionService.list({
             filters: new FilterBuilder()
                 .addEqual('current_version_uuid', uuid)
                 .getFilters(),
             includeOldVersions: true,
             order: new OrderBuilder<CollectionResource>().addDesc("version").getOrder()
-        });
-        dispatch(resourcesActions.SET_RESOURCES(versions.items));
+        }).then(versions => dispatch(resourcesActions.SET_RESOURCES(versions.items))
+        ).catch(e => snackbarActions.OPEN_SNACKBAR({
+            message: `Couldn't retrieve versions: ${e.errors[0]}`,
+            hideDuration: 2000,
+            kind: SnackbarKind.ERROR })
+        );
     };
 
 export const deleteProjectProperty = (key: string, value: string) =>

commit 83931f3e2ec3652900ed733f8a35f8be018d39d7
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Wed Nov 18 18:43:45 2020 -0300

    13494: Simplifies collection update action calling.
    
    Also makes action asynchronous, and refresh details panel after the update
    operation is done.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/store/collections/collection-update-actions.ts b/src/store/collections/collection-update-actions.ts
index f8fac398..2faaa215 100644
--- a/src/store/collections/collection-update-actions.ts
+++ b/src/store/collections/collection-update-actions.ts
@@ -11,6 +11,10 @@ import { getCommonResourceServiceError, CommonResourceServiceError } from "~/ser
 import { ServiceRepository } from "~/services/services";
 import { CollectionResource } from '~/models/collection';
 import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
+import { snackbarActions, SnackbarKind } from "../snackbar/snackbar-actions";
+import { updateResources } from "../resources/resources-actions";
+import { reloadProjectMatchingUuid } from "../workbench/workbench-actions";
+import { loadDetailsPanel } from "../details-panel/details-panel-action";
 
 export interface CollectionUpdateFormDialogData {
     uuid: string;
@@ -27,26 +31,38 @@ export const openCollectionUpdateDialog = (resource: CollectionUpdateFormDialogD
     };
 
 export const updateCollection = (collection: CollectionUpdateFormDialogData) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const uuid = collection.uuid || '';
         dispatch(startSubmit(COLLECTION_UPDATE_FORM_NAME));
         dispatch(progressIndicatorActions.START_WORKING(COLLECTION_UPDATE_FORM_NAME));
-        try {
-            const updatedCollection = await services.collectionService.update(uuid, { name: collection.name, description: collection.description });
+
+        services.collectionService.update(uuid, {
+            name: collection.name,
+            description: collection.description }
+        ).then(updatedCollection => {
             dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: updatedCollection as CollectionResource }));
             dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_UPDATE_FORM_NAME }));
             dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_UPDATE_FORM_NAME));
-            return updatedCollection;
-        } catch (e) {
+            dispatch(snackbarActions.OPEN_SNACKBAR({
+                message: "Collection has been successfully updated.",
+                hideDuration: 2000,
+                kind: SnackbarKind.SUCCESS
+            }));
+            dispatch<any>(updateResources([updatedCollection]));
+            dispatch<any>(reloadProjectMatchingUuid([updatedCollection.ownerUuid]));
+            dispatch<any>(loadDetailsPanel(updatedCollection.uuid));
+        }).catch (e => {
             dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_UPDATE_FORM_NAME));
             const error = getCommonResourceServiceError(e);
             if (error === CommonResourceServiceError.UNIQUE_NAME_VIOLATION) {
                 dispatch(stopSubmit(COLLECTION_UPDATE_FORM_NAME, { name: 'Collection with the same name already exists.' } as FormErrors));
             } else {
-                // Unknown error, handling left to caller.
                 dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_UPDATE_FORM_NAME }));
-                throw(e);
+                dispatch(snackbarActions.OPEN_SNACKBAR({
+                    message: e.errors.join(''),
+                    hideDuration: 2000,
+                    kind: SnackbarKind.ERROR }));
+                }
             }
-        }
-        return;
+        );
     };
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 0416d815..09aad2bd 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -42,7 +42,6 @@ import * as projectMoveActions from '~/store/projects/project-move-actions';
 import * as projectUpdateActions from '~/store/projects/project-update-actions';
 import * as collectionCreateActions from '~/store/collections/collection-create-actions';
 import * as collectionCopyActions from '~/store/collections/collection-copy-actions';
-import * as collectionUpdateActions from '~/store/collections/collection-update-actions';
 import * as collectionMoveActions from '~/store/collections/collection-move-actions';
 import * as processesActions from '~/store/processes/processes-actions';
 import * as processMoveActions from '~/store/processes/process-move-actions';
@@ -323,24 +322,6 @@ export const createCollection = (data: collectionCreateActions.CollectionCreateF
         }
     };
 
-export const updateCollection = (data: collectionUpdateActions.CollectionUpdateFormDialogData) =>
-    async (dispatch: Dispatch) => {
-        try {
-            const collection = await dispatch<any>(collectionUpdateActions.updateCollection(data));
-            if (collection) {
-                dispatch(snackbarActions.OPEN_SNACKBAR({
-                    message: "Collection has been successfully updated.",
-                    hideDuration: 2000,
-                    kind: SnackbarKind.SUCCESS
-                }));
-                dispatch<any>(updateResources([collection]));
-                dispatch<any>(reloadProjectMatchingUuid([collection.ownerUuid]));
-            }
-        } catch (e) {
-            dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.errors.join(''), hideDuration: 2000, kind: SnackbarKind.ERROR }));
-        }
-    };
-
 export const copyCollection = (data: CopyFormDialogData) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         try {
diff --git a/src/views-components/dialog-forms/update-collection-dialog.ts b/src/views-components/dialog-forms/update-collection-dialog.ts
index 021a335b..b2fe96b8 100644
--- a/src/views-components/dialog-forms/update-collection-dialog.ts
+++ b/src/views-components/dialog-forms/update-collection-dialog.ts
@@ -6,8 +6,7 @@ import { compose } from "redux";
 import { reduxForm } from 'redux-form';
 import { withDialog } from "~/store/dialog/with-dialog";
 import { DialogCollectionUpdate } from '~/views-components/dialog-update/dialog-collection-update';
-import { COLLECTION_UPDATE_FORM_NAME, CollectionUpdateFormDialogData } from '~/store/collections/collection-update-actions';
-import { updateCollection } from "~/store/workbench/workbench-actions";
+import { COLLECTION_UPDATE_FORM_NAME, CollectionUpdateFormDialogData, updateCollection } from '~/store/collections/collection-update-actions';
 
 export const UpdateCollectionDialog = compose(
     withDialog(COLLECTION_UPDATE_FORM_NAME),

commit 0e3fc3157269a28e533333397cc20ec95ff093df
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Wed Nov 18 18:41:43 2020 -0300

    13494: Avoids doing unnecessary API requests on collection's move action.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/store/collections/collection-move-actions.ts b/src/store/collections/collection-move-actions.ts
index 6ccd0caa..a64a7a1d 100644
--- a/src/store/collections/collection-move-actions.ts
+++ b/src/store/collections/collection-move-actions.ts
@@ -30,8 +30,7 @@ export const moveCollection = (resource: MoveToFormDialogData) =>
         dispatch(startSubmit(COLLECTION_MOVE_FORM_NAME));
         try {
             dispatch(progressIndicatorActions.START_WORKING(COLLECTION_MOVE_FORM_NAME));
-            await services.collectionService.update(resource.uuid, { ownerUuid: resource.ownerUuid });
-            const collection = await services.collectionService.get(resource.uuid);
+            const collection = await services.collectionService.update(resource.uuid, { ownerUuid: resource.ownerUuid });
             dispatch(projectPanelActions.REQUEST_ITEMS());
             dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_MOVE_FORM_NAME }));
             dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_MOVE_FORM_NAME));

commit 3426a94b3d8c56ae1d63da004e8c30de75e5881d
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Wed Nov 18 18:39:58 2020 -0300

    13494: Fixes multi-value property removal.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/views/collection-panel/collection-panel.tsx b/src/views/collection-panel/collection-panel.tsx
index f1c9073d..0a4cf3c7 100644
--- a/src/views/collection-panel/collection-panel.tsx
+++ b/src/views/collection-panel/collection-panel.tsx
@@ -205,7 +205,7 @@ export const CollectionPanel = withStyles(styles)(
                                                         getPropertyChip(
                                                             k, v,
                                                             isWritable
-                                                                ? this.handleDelete(k, item.properties[k])
+                                                                ? this.handleDelete(k, v)
                                                                 : undefined,
                                                             classes.tag))
                                                     : getPropertyChip(

commit e83d929135335433aca0e47b5892c7c60ffa394f
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Wed Nov 18 15:21:23 2020 -0300

    13494: Adds version number on collection's status renderer.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx
index 138c76ef..6d95196d 100644
--- a/src/views-components/data-explorer/renderers.tsx
+++ b/src/views-components/data-explorer/renderers.tsx
@@ -457,8 +457,8 @@ export const CollectionStatus = connect((state: RootState, props: { uuid: string
         return { collection: getResource<CollectionResource>(props.uuid)(state.resources) };
     })((props: { collection: CollectionResource }) =>
         (props.collection.uuid !== props.collection.currentVersionUuid)
-        ? <Typography>old version</Typography>
-        : <Typography>current</Typography>
+        ? <Typography>version {props.collection.version}</Typography>
+        : <Typography>head version</Typography>
     );
 
 export const ProcessStatus = compose(

commit 4b6b871dfa9aefaf1e9ca31e38d33a71a422064d
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Wed Nov 18 12:19:35 2020 -0300

    13494: Enhances collection versions browser's layout.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index 51b09b4f..500b0506 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -15,15 +15,15 @@ import { formatDate, formatFileSize } from '~/common/formatters';
 import { Dispatch } from 'redux';
 import { navigateTo } from '~/store/navigation/navigation-action';
 
-export type CssRules = 'versionBrowserHeader' | 'selectedVersion';
+export type CssRules = 'versionBrowserHeader' | 'versionBrowserItem';
 
 const styles: StyleRulesCallback<CssRules> = theme => ({
     versionBrowserHeader: {
         textAlign: 'center',
-        fontWeight: 'bold'
+        fontWeight: 'bold',
     },
-    selectedVersion: {
-        fontWeight: 'bold'
+    versionBrowserItem: {
+        textAlign: 'center',
     }
 });
 
@@ -85,38 +85,47 @@ const CollectionVersionBrowser = withStyles(styles)(
     connect(mapStateToProps, mapDispatchToProps)(
         ({ currentCollection, versions, showVersion, classes }: CollectionVersionBrowserProps & CollectionVersionBrowserDispatchProps & WithStyles<CssRules>) => {
             return <>
-                <Grid container justify="space-between">
-                    <Typography variant="caption" className={classes.versionBrowserHeader}>
-                        Version
-                    </Typography>
-                    <Typography variant="caption" className={classes.versionBrowserHeader}>
-                        Size
-                    </Typography>
-                    <Typography variant="caption" className={classes.versionBrowserHeader}>
-                        Date
-                    </Typography>
-                </Grid>
+                <Grid container>
+                    <Grid item xs={2}>
+                        <Typography variant="caption" className={classes.versionBrowserHeader}>
+                            Nr
+                        </Typography>
+                    </Grid>
+                    <Grid item xs={4}>
+                        <Typography variant="caption" className={classes.versionBrowserHeader}>
+                            Size
+                        </Typography>
+                    </Grid>
+                    <Grid item xs={6}>
+                        <Typography variant="caption" className={classes.versionBrowserHeader}>
+                            Date
+                        </Typography>
+                    </Grid>
                 { versions.map(item => {
                     const isSelectedVersion = !!(currentCollection && currentCollection.uuid === item.uuid);
                     return (
-                        <ListItem button
-                            className={isSelectedVersion ? 'selectedVersion' : ''}
+                        <ListItem button style={{padding: '4px'}}
                             key={item.version}
                             onClick={e => showVersion(item)}
                             selected={isSelectedVersion}>
-                            <Grid container justify="space-between">
-                                <Typography variant="caption">
+                            <Grid item xs={2}>
+                                <Typography variant="caption" className={classes.versionBrowserItem}>
                                     {item.version}
                                 </Typography>
-                                <Typography variant="caption">
+                            </Grid>
+                            <Grid item xs={4}>
+                                <Typography variant="caption" className={classes.versionBrowserItem}>
                                     {formatFileSize(item.fileSizeTotal)}
                                 </Typography>
-                                <Typography variant="caption">
+                            </Grid>
+                            <Grid item xs={6}>
+                                <Typography variant="caption" className={classes.versionBrowserItem}>
                                     {formatDate(item.modifiedAt)}
                                 </Typography>
                             </Grid>
                         </ListItem>
                     );
                 })}
+                </Grid>
             </>;
         }));
\ No newline at end of file

commit 0cd27bb15628e8a94741b96396b12048fc3f31b3
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Wed Nov 18 11:30:48 2020 -0300

    13494: Avoids unnecessary details panel re-renders.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/views-components/details-panel/details-panel.tsx b/src/views-components/details-panel/details-panel.tsx
index fbe9ccc6..da067c15 100644
--- a/src/views-components/details-panel/details-panel.tsx
+++ b/src/views-components/details-panel/details-panel.tsx
@@ -79,11 +79,13 @@ const getItem = (res: DetailsResource): DetailsData => {
 
 const mapStateToProps = ({ detailsPanel, resources, collectionPanelFiles }: RootState) => {
     const resource = getResource(detailsPanel.resourceUuid)(resources) as DetailsResource | undefined;
-    const file = getNode(detailsPanel.resourceUuid)(collectionPanelFiles);
+    const file = resource
+        ? undefined
+        : getNode(detailsPanel.resourceUuid)(collectionPanelFiles);
     return {
         isOpened: detailsPanel.isOpened,
         tabNr: detailsPanel.tabNr,
-        item: getItem(resource || (file && file.value) || EMPTY_RESOURCE),
+        res: resource || (file && file.value) || EMPTY_RESOURCE,
     };
 };
 
@@ -101,7 +103,7 @@ export interface DetailsPanelDataProps {
     setActiveTab: (tabNr: number) => void;
     isOpened: boolean;
     tabNr: number;
-    item: DetailsData;
+    res: DetailsResource;
 }
 
 type DetailsPanelProps = DetailsPanelDataProps & WithStyles<CssRules>;
@@ -109,6 +111,16 @@ type DetailsPanelProps = DetailsPanelDataProps & WithStyles<CssRules>;
 export const DetailsPanel = withStyles(styles)(
     connect(mapStateToProps, mapDispatchToProps)(
         class extends React.Component<DetailsPanelProps> {
+            shouldComponentUpdate(nextProps: DetailsPanelProps) {
+                if ('etag' in nextProps.res && 'etag' in this.props.res &&
+                    nextProps.res.etag === this.props.res.etag &&
+                    nextProps.isOpened === this.props.isOpened &&
+                    nextProps.tabNr === this.props.tabNr) {
+                    return false;
+                }
+                return true;
+            }
+
             handleChange = (event: any, value: number) => {
                 this.props.setActiveTab(value);
             }
@@ -124,14 +136,15 @@ export const DetailsPanel = withStyles(styles)(
                             in={isOpened}
                             timeout={SLIDE_TIMEOUT}
                             unmountOnExit>
-                            {this.renderContent()}
+                            {isOpened ? this.renderContent() : <div />}
                         </Transition>
                     </Grid>
                 );
             }
 
             renderContent() {
-                const { classes, onCloseDrawer, item, tabNr } = this.props;
+                const { classes, onCloseDrawer, res, tabNr } = this.props;
+                const item = getItem(res);
                 return <Grid
                     container
                     direction="column"

commit d5e2ff533dc37c1d8ee1fc320ef5319c7514427d
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Tue Nov 17 12:25:42 2020 -0300

    13494: Maintains 'Head version' data on the collection panel.
    
    This is to avoid the rest of the information changing places on the panel.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/views/collection-panel/collection-panel.tsx b/src/views/collection-panel/collection-panel.tsx
index 0799c5cc..f1c9073d 100644
--- a/src/views/collection-panel/collection-panel.tsx
+++ b/src/views/collection-panel/collection-panel.tsx
@@ -304,14 +304,12 @@ export const CollectionDetailsAttributes = (props: { item: CollectionResource, t
             <DetailsAttribute classLabel={classes.label} classValue={classes.value}
                 label='Owner' linkToUuid={item.ownerUuid} />
         </Grid>
-
-        {isOldVersion &&
-            <Grid item xs={12} md={mdSize}>
-                <DetailsAttribute classLabel={classes.label} classValue={classes.value}
-                    label='Head version'
-                    linkToUuid={item.currentVersionUuid} />
-            </Grid>
-        }
+        <Grid item xs={12} md={mdSize}>
+            <DetailsAttribute classLabel={classes.label} classValue={classes.value}
+                label='Head version'
+                value={isOldVersion ? undefined : 'this one'}
+                linkToUuid={isOldVersion ? item.currentVersionUuid : undefined} />
+        </Grid>
         <Grid item xs={12} md={mdSize}>
             <DetailsAttribute
                 classLabel={classes.label} classValue={classes.value}

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list