17205: Created new renderer for owner name
authorDaniel Kutyła <daniel.kutyla@contractors.roche.com>
Tue, 2 Feb 2021 22:33:48 +0000 (23:33 +0100)
committerDaniel Kutyła <daniel.kutyla@contractors.roche.com>
Tue, 2 Feb 2021 22:33:48 +0000 (23:33 +0100)
Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła <daniel.kutyla@contractors.roche.com>

src/store/owner-name-uuid-enhancer/owner-name-uuid-enhancer-actions.ts [deleted file]
src/store/owner-name-uuid-enhancer/owner-name-uuid-enhancer-reducer.ts [deleted file]
src/store/resources/resources-actions.ts
src/store/store.ts
src/views-components/data-explorer/renderers.tsx
src/views-components/details-panel/process-details.tsx
src/views-components/details-panel/project-details.tsx
src/views-components/owner-name-uuid-enhancer/owner-name-uuid-enhancer.test.tsx [deleted file]
src/views-components/owner-name-uuid-enhancer/owner-name-uuid-enhancer.tsx [deleted file]
src/views/collection-panel/collection-panel.tsx

diff --git a/src/store/owner-name-uuid-enhancer/owner-name-uuid-enhancer-actions.ts b/src/store/owner-name-uuid-enhancer/owner-name-uuid-enhancer-actions.ts
deleted file mode 100644 (file)
index cb95c12..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { Dispatch } from 'redux';
-import { unionize, ofType, UnionOf } from '~/common/unionize';
-import { extractUuidObjectType, ResourceObjectType } from '~/models/resource';
-import { ServiceRepository } from '~/services/services';
-import { RootState } from '../store';
-
-export type OwnerNameUuidEnhancerAction = UnionOf<typeof ownerNameUuidEnhancerActions>;
-
-export interface OwnerNameState {
-    name: string;
-    uuid: string;
-}
-
-export const ownerNameUuidEnhancerActions = unionize({
-    SET_OWNER_NAME_BY_UUID: ofType<OwnerNameState>()
-});
-
-export const fetchOwnerNameByUuid = (uuid: string) =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const objectType = extractUuidObjectType(uuid);
-
-        switch (objectType) {
-            case ResourceObjectType.USER:
-                services.userService.get(uuid, false)
-                    .then((data) =>
-                        dispatch(
-                            ownerNameUuidEnhancerActions.SET_OWNER_NAME_BY_UUID({
-                                uuid,
-                                name: (data as any).fullName,
-                            })
-                        )
-                    );
-                break;
-            case ResourceObjectType.GROUP:
-                services.groupsService.get(uuid, false)
-                    .then((data) =>
-                        dispatch(
-                            ownerNameUuidEnhancerActions.SET_OWNER_NAME_BY_UUID({
-                                uuid,
-                                name: (data as any).name,
-                            })
-                        )
-                    );
-                break;
-            default:
-                break;
-        }
-    };
\ No newline at end of file
diff --git a/src/store/owner-name-uuid-enhancer/owner-name-uuid-enhancer-reducer.ts b/src/store/owner-name-uuid-enhancer/owner-name-uuid-enhancer-reducer.ts
deleted file mode 100644 (file)
index 3970792..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { ownerNameUuidEnhancerActions, OwnerNameUuidEnhancerAction, OwnerNameState } from './owner-name-uuid-enhancer-actions';
-
-export const ownerNameUuidEnhancerReducer = (state = {}, action: OwnerNameUuidEnhancerAction) =>
-    ownerNameUuidEnhancerActions.match(action, {
-        SET_OWNER_NAME_BY_UUID: (data: OwnerNameState) => ({...state, [data.uuid]: data.name }),
-        default: () => state,
-    });
\ No newline at end of file
index 1de2feff8b9f8d42111090f132f7dfba4a624a0c..5465db62aef508d3a00ca42eb007a52878562ffa 100644 (file)
@@ -18,13 +18,13 @@ export type ResourcesAction = UnionOf<typeof resourcesActions>;
 
 export const updateResources = (resources: Resource[]) => resourcesActions.SET_RESOURCES(resources);
 
-export const loadResource = (uuid: string) =>
+export const loadResource = (uuid: string, showErrors?: boolean) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         try {
             const kind = extractUuidKind(uuid);
             const service = getResourceService(kind)(services);
             if (service) {
-                const resource = await service.get(uuid);
+                const resource = await service.get(uuid, showErrors);
                 dispatch<any>(updateResources([resource]));
                 return resource;
             }
index 929ca616193287929b30c9020eb313a0caae26c0..517368aa43badea0d26c3bd6dbb54701257e0572 100644 (file)
@@ -66,7 +66,6 @@ import { linkAccountPanelReducer } from './link-account-panel/link-account-panel
 import { CollectionsWithSameContentAddressMiddlewareService } from '~/store/collections-content-address-panel/collections-content-address-middleware-service';
 import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from '~/store/collections-content-address-panel/collections-content-address-panel-actions';
 import { ownerNameReducer } from '~/store/owner-name/owner-name-reducer';
-import { ownerNameUuidEnhancerReducer } from './owner-name-uuid-enhancer/owner-name-uuid-enhancer-reducer';
 import { SubprocessMiddlewareService } from '~/store/subprocess-panel/subprocess-panel-middleware-service';
 import { SUBPROCESS_PANEL_ID } from '~/store/subprocess-panel/subprocess-panel-actions';
 import { ALL_PROCESSES_PANEL_ID } from './all-processes-panel/all-processes-panel-action';
@@ -179,7 +178,6 @@ const createRootReducer = (services: ServiceRepository) => combineReducers({
     dialog: dialogReducer,
     favorites: favoritesReducer,
     ownerName: ownerNameReducer,
-    ownerNameUuidEnhancer: ownerNameUuidEnhancerReducer,
     publicFavorites: publicFavoritesReducer,
     form: formReducer,
     processLogsPanel: processLogsPanelReducer,
index 6d95196d3ed1ce8eb79fa8600d8cc4c618f56c92..7d870bc1058472e165360cda2dc1fdb65e5c3276 100644 (file)
@@ -27,6 +27,7 @@ import { navigateTo } from '~/store/navigation/navigation-action';
 import { withResourceData } from '~/views-components/data-explorer/with-resources';
 import { CollectionResource } from '~/models/collection';
 import { IllegalNamingWarning } from '~/components/warning/warning';
+import { loadResource } from '~/store/resources/resources-actions';
 
 const renderName = (dispatch: Dispatch, item: GroupContentsResource) =>
     <Grid container alignItems="center" wrap="nowrap" spacing={16}>
@@ -434,6 +435,35 @@ export const ResourceOwnerName = connect(
         return { owner: ownerName ? ownerName!.name : resource!.ownerUuid };
     })((props: { owner: string }) => renderOwner(props.owner));
 
+export const ResourceOwnerWithName =
+    compose(
+        connect(
+            (state: RootState, props: { uuid: string }) => {
+                let ownerName = '';
+                const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
+
+                if (resource) {
+                    ownerName = (resource as any).fullName || resource.name;
+                }
+
+                return { uuid: props.uuid, ownerName };
+            }),
+        withStyles({}, { withTheme: true }))
+        ((props: { uuid: string, ownerName: string, dispatch: Dispatch, theme: ArvadosTheme }) => {
+            const { uuid, ownerName, dispatch, theme } = props;
+
+            if (ownerName === '') {
+                dispatch<any>(loadResource(uuid, false));
+                return <Typography style={{ color: theme.palette.primary.main }} inline noWrap>
+                    {uuid}
+                </Typography>;
+            }
+
+            return <Typography style={{ color: theme.palette.primary.main }} inline noWrap>
+                {uuid} ({ownerName})
+            </Typography>;
+        });
+
 const renderType = (type: string) =>
     <Typography noWrap>
         {resourceLabel(type)}
@@ -446,20 +476,20 @@ export const ResourceType = connect(
     })((props: { type: string }) => renderType(props.type));
 
 export const ResourceStatus = connect((state: RootState, props: { uuid: string }) => {
-        return { resource: getResource<GroupContentsResource>(props.uuid)(state.resources) };
-    })((props: { resource: GroupContentsResource }) =>
-        (props.resource && props.resource.kind === ResourceKind.COLLECTION)
+    return { resource: getResource<GroupContentsResource>(props.uuid)(state.resources) };
+})((props: { resource: GroupContentsResource }) =>
+    (props.resource && props.resource.kind === ResourceKind.COLLECTION)
         ? <CollectionStatus uuid={props.resource.uuid} />
         : <ProcessStatus uuid={props.resource.uuid} />
-    );
+);
 
 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)
+    return { collection: getResource<CollectionResource>(props.uuid)(state.resources) };
+})((props: { collection: CollectionResource }) =>
+    (props.collection.uuid !== props.collection.currentVersionUuid)
         ? <Typography>version {props.collection.version}</Typography>
         : <Typography>head version</Typography>
-    );
+);
 
 export const ProcessStatus = compose(
     connect((state: RootState, props: { uuid: string }) => {
@@ -478,7 +508,7 @@ export const ProcessStatus = compose(
 export const ProcessStartDate = connect(
     (state: RootState, props: { uuid: string }) => {
         const process = getProcess(props.uuid)(state.resources);
-        return { date: ( process && process.container ) ? process.container.startedAt : '' };
+        return { date: (process && process.container) ? process.container.startedAt : '' };
     })((props: { date: string }) => renderDate(props.date));
 
 export const renderRunTime = (time: number) =>
index a065d91e4e37f8c96de9fd33d14417444ca515fd..0867f92d2d38a68074e2a3aa739bd318771dd5ae 100644 (file)
@@ -10,7 +10,7 @@ import { ResourceKind } from '~/models/resource';
 import { resourceLabel } from '~/common/labels';
 import { DetailsData } from "./details-data";
 import { DetailsAttribute } from "~/components/details-attribute/details-attribute";
-import OwnerNameUuidEnhancer from '../owner-name-uuid-enhancer/owner-name-uuid-enhancer';
+import { ResourceOwnerWithName } from '../data-explorer/renderers';
 
 export class ProcessDetails extends DetailsData<ProcessResource> {
 
@@ -22,7 +22,7 @@ export class ProcessDetails extends DetailsData<ProcessResource> {
         return <div>
             <DetailsAttribute label='Type' value={resourceLabel(ResourceKind.PROCESS)} />
             <DetailsAttribute label='Owner' linkToUuid={this.item.ownerUuid} value={this.item.ownerUuid}
-                uuidEnhancer={(uuid: string) => <OwnerNameUuidEnhancer uuid={uuid} />} />
+                uuidEnhancer={(uuid: string) => <ResourceOwnerWithName uuid={uuid} />} />
 
             <DetailsAttribute label='Status' value={this.item.state} />
             <DetailsAttribute label='Last modified' value={formatDate(this.item.modifiedAt)} />
index eb613bf2f727a3d5762322d60f71e313374d0650..34a372c9b692bc85fcfe71bc4c77185c7beec6f7 100644 (file)
@@ -17,7 +17,7 @@ import { withStyles, StyleRulesCallback, WithStyles } from '@material-ui/core';
 import { ArvadosTheme } from '~/common/custom-theme';
 import { Dispatch } from 'redux';
 import { getPropertyChip } from '../resource-properties-form/property-chip';
-import OwnerNameUuidEnhancer from '../owner-name-uuid-enhancer/owner-name-uuid-enhancer';
+import { ResourceOwnerWithName } from '../data-explorer/renderers';
 
 export class ProjectDetails extends DetailsData<ProjectResource> {
     getIcon(className?: string) {
@@ -61,7 +61,7 @@ const ProjectDetailsComponent = connect(null, mapDispatchToProps)(
         ({ classes, project, onClick }: ProjectDetailsComponentProps) => <div>
             <DetailsAttribute label='Type' value={resourceLabel(ResourceKind.PROJECT)} />
             <DetailsAttribute label='Owner' linkToUuid={project.ownerUuid}
-                uuidEnhancer={(uuid: string) => <OwnerNameUuidEnhancer uuid={uuid} />} lowercaseValue={true} />
+                uuidEnhancer={(uuid: string) => <ResourceOwnerWithName uuid={uuid} />} lowercaseValue={true} />
             <DetailsAttribute label='Last modified' value={formatDate(project.modifiedAt)} />
             <DetailsAttribute label='Created at' value={formatDate(project.createdAt)} />
             <DetailsAttribute label='Project UUID' linkToUuid={project.uuid} value={project.uuid} />
diff --git a/src/views-components/owner-name-uuid-enhancer/owner-name-uuid-enhancer.test.tsx b/src/views-components/owner-name-uuid-enhancer/owner-name-uuid-enhancer.test.tsx
deleted file mode 100644 (file)
index 1df5faf..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import * as React from 'react';
-import { mount, configure } from 'enzyme';
-import * as Adapter from "enzyme-adapter-react-16";
-import { OwnerNameUuidEnhancer, OwnerNameUuidEnhancerProps } from './owner-name-uuid-enhancer';
-
-configure({ adapter: new Adapter() });
-
-describe('NotFoundPanelRoot', () => {
-    let props: OwnerNameUuidEnhancerProps;
-
-    beforeEach(() => {
-        props = {
-            ownerNamesMap: {},
-            fetchOwner: () => {},
-            uuid: 'zzzz-tpzed-xxxxxxxxxxxxxxx',
-        };
-    });
-
-    it('should render uuid without name', () => {
-        // when
-        const wrapper = mount(<OwnerNameUuidEnhancer {...props} />);
-
-        // then
-        expect(wrapper.html()).toBe('<span>zzzz-tpzed-xxxxxxxxxxxxxxx</span>');
-    });
-
-    it('should render uuid with name', () => {
-        // given
-        const fullName = 'John Doe';
-
-        // setup
-        props.ownerNamesMap = {
-            [props.uuid]: fullName
-        };
-
-        // when
-        const wrapper = mount(<OwnerNameUuidEnhancer {...props} />);
-
-        // then
-        expect(wrapper.html()).toBe('<span>zzzz-tpzed-xxxxxxxxxxxxxxx (John Doe)</span>');
-    });
-});
\ No newline at end of file
diff --git a/src/views-components/owner-name-uuid-enhancer/owner-name-uuid-enhancer.tsx b/src/views-components/owner-name-uuid-enhancer/owner-name-uuid-enhancer.tsx
deleted file mode 100644 (file)
index b4431fa..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import * as React from 'react';
-import { Dispatch } from 'redux';
-import { RootState } from '~/store/store';
-import { connect } from 'react-redux';
-import { fetchOwnerNameByUuid } from '~/store/owner-name-uuid-enhancer/owner-name-uuid-enhancer-actions';
-
-export interface OwnerNameUuidEnhancerOwnProps {
-    uuid: string;
-}
-
-export interface OwnerNameUuidEnhancerRootDataProps {
-    ownerNamesMap: any;
-}
-
-export interface OwnerNameUuidEnhancerDispatchProps {
-    fetchOwner: Function;
-}
-
-export type OwnerNameUuidEnhancerProps = OwnerNameUuidEnhancerOwnProps & OwnerNameUuidEnhancerRootDataProps & OwnerNameUuidEnhancerDispatchProps;
-
-export const OwnerNameUuidEnhancer = ({ uuid, ownerNamesMap, fetchOwner }: OwnerNameUuidEnhancerProps) => {
-    React.useEffect(() => {
-        if (!ownerNamesMap[uuid]) {
-            fetchOwner(uuid);
-        }
-    }, [uuid, ownerNamesMap, fetchOwner]);
-
-    return <span>{uuid}{ownerNamesMap[uuid] ? ` (${ownerNamesMap[uuid]})` : ''}</span>;
-};
-
-const mapStateToProps = (state: RootState): OwnerNameUuidEnhancerRootDataProps => {
-    return {
-        ownerNamesMap: state.ownerNameUuidEnhancer,
-    };
-};
-
-const mapDispatchToProps = (dispatch: Dispatch): OwnerNameUuidEnhancerDispatchProps => ({
-    fetchOwner: (uuid: string) => dispatch<any>(fetchOwnerNameByUuid(uuid))
-});
-
-export default connect<OwnerNameUuidEnhancerRootDataProps, OwnerNameUuidEnhancerDispatchProps, OwnerNameUuidEnhancerOwnProps>(mapStateToProps, mapDispatchToProps)
-    (OwnerNameUuidEnhancer);
index e75073ae3463e308bea83416465a9f5ecfd77259..32e37d46f05e528b0fb06ca50f4698abc582184c 100644 (file)
@@ -30,9 +30,9 @@ import { UserResource } from '~/models/user';
 import { getUserUuid } from '~/common/getuser';
 import { getProgressIndicator } from '~/store/progress-indicator/progress-indicator-reducer';
 import { COLLECTION_PANEL_LOAD_FILES, loadCollectionFiles, COLLECTION_PANEL_LOAD_FILES_THRESHOLD } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions';
-import OwnerNameUuidEnhancer from '../../views-components/owner-name-uuid-enhancer/owner-name-uuid-enhancer';
 import { Link } from 'react-router-dom';
 import { Link as ButtonLink } from '@material-ui/core';
+import { ResourceOwnerWithName } from '~/views-components/data-explorer/renderers';
 
 type CssRules = 'root'
     | 'button'
@@ -299,7 +299,7 @@ export const CollectionDetailsAttributes = (props: { item: CollectionResource, t
         <Grid item xs={12} md={mdSize}>
             <DetailsAttribute classLabel={classes.label} classValue={classes.value}
                 label='Owner' linkToUuid={item.ownerUuid}
-                uuidEnhancer={(uuid: string) => <OwnerNameUuidEnhancer uuid={uuid} />} />
+                uuidEnhancer={(uuid: string) => <ResourceOwnerWithName uuid={uuid} />} />
         </Grid>
         <Grid item xs={12} md={mdSize}>
             <DetailsAttribute classLabel={classes.label} classValue={classes.value}