16439: Enables the +NEW button only when the user's view is writable.
authorLucas Di Pentima <lucas@di-pentima.com.ar>
Mon, 1 Jun 2020 21:30:19 +0000 (18:30 -0300)
committerLucas Di Pentima <lucas@di-pentima.com.ar>
Mon, 1 Jun 2020 21:33:56 +0000 (18:33 -0300)
Also, makes the SidePanelButton component to not depend on a state property
set by a something rendered later, because that makes the button being
re-renderered at least twice on every location change, instead try to get the
current item id from the location url.

Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas@di-pentima.com.ar>

src/views-components/side-panel-button/side-panel-button.tsx

index 0f79759078d1ca2009a69643c2a7ab7681d467ca..4e2e90f16b4be5c31a4d26897d4edd9325cd3de1 100644 (file)
@@ -5,8 +5,6 @@
 import * as React from 'react';
 import { connect, DispatchProp } from 'react-redux';
 import { RootState } from '~/store/store';
-import { getProperty } from '~/store/properties/properties';
-import { PROJECT_PANEL_CURRENT_UUID } from '~/store/project-panel/project-panel-action';
 import { ArvadosTheme } from '~/common/custom-theme';
 import { PopoverOrigin } from '@material-ui/core/Popover';
 import { StyleRulesCallback, WithStyles, withStyles, Toolbar, Grid, Button, MenuItem, Menu } from '@material-ui/core';
@@ -15,6 +13,10 @@ import { openProjectCreateDialog } from '~/store/projects/project-create-actions
 import { openCollectionCreateDialog } from '~/store/collections/collection-create-actions';
 import { navigateToRunProcess } from '~/store/navigation/navigation-action';
 import { runProcessPanelActions } from '~/store/run-process-panel/run-process-panel-actions';
+import { getUserUuid } from '~/common/getuser';
+import { matchProjectRoute } from '~/routes/routes';
+import { GroupResource } from '~/models/group';
+import { ResourcesState, getResource } from '~/store/resources/resources';
 
 type CssRules = 'button' | 'menuItem' | 'icon';
 
@@ -36,6 +38,8 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
 interface SidePanelDataProps {
     location: any;
     currentItemId: string;
+    resources: ResourcesState;
+    currentUserUUID: string | undefined;
 }
 
 interface SidePanelState {
@@ -51,8 +55,12 @@ const transformOrigin: PopoverOrigin = {
 
 export const SidePanelButton = withStyles(styles)(
     connect((state: RootState) => ({
-        currentItemId: getProperty(PROJECT_PANEL_CURRENT_UUID)(state.properties),
-        location: state.router.location
+        currentItemId: state.router.location
+            ? state.router.location.pathname.split('/').slice(-1)[0]
+            : null,
+        location: state.router.location,
+        resources: state.resources,
+        currentUserUUID: getUserUuid(state),
     }))(
         class extends React.Component<SidePanelProps> {
 
@@ -61,12 +69,24 @@ export const SidePanelButton = withStyles(styles)(
             };
 
             render() {
-                const { classes } = this.props;
+                const { classes, location, resources, currentUserUUID, currentItemId } = this.props;
                 const { anchorEl } = this.state;
+                let enabled = false;
+                if (currentItemId === currentUserUUID) {
+                    enabled = true;
+                } else if (matchProjectRoute(location ? location.pathname : '')) {
+                    const currentProject = getResource<GroupResource>(currentItemId)(resources);
+                    if (currentProject &&
+                        currentProject.writableBy.indexOf(currentUserUUID || '') >= 0 &&
+                        !currentProject.isTrashed) {
+                        enabled = true;
+                    }
+                }
                 return <Toolbar>
                     <Grid container>
                         <Grid container item xs alignItems="center" justify="flex-start">
-                            <Button variant="contained" color="primary" size="small" className={classes.button}
+                            <Button variant="contained" disabled={!enabled}
+                                color="primary" size="small" className={classes.button}
                                 aria-owns={anchorEl ? 'aside-menu-list' : undefined}
                                 aria-haspopup="true"
                                 onClick={this.handleOpen}>
@@ -104,7 +124,7 @@ export const SidePanelButton = withStyles(styles)(
                 this.props.dispatch(runProcessPanelActions.RESET_RUN_PROCESS_PANEL());
                 this.props.dispatch(runProcessPanelActions.SET_PROCESS_PATHNAME(location.pathname));
                 this.props.dispatch(runProcessPanelActions.SET_PROCESS_OWNER_UUID(this.props.currentItemId));
-                
+
                 this.props.dispatch<any>(navigateToRunProcess);
             }