From 5d2cc407a7649ca7807b78369f2f08351202cc77 Mon Sep 17 00:00:00 2001 From: Pawel Kowalczyk Date: Wed, 15 May 2019 14:57:03 +0200 Subject: [PATCH] owner-names-and-updated-navigating-on-data-explorer-name Feature #15020 Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk --- .../collection-panel-action.ts | 8 ---- .../collection-panel-reducer.ts | 7 +--- ...ions-content-address-middleware-service.ts | 37 +++++++++++++++++++ src/store/owner-name/owner-name-actions.ts | 16 ++++++++ src/store/owner-name/owner-name-reducer.ts | 11 ++++++ src/store/store.ts | 2 + .../data-explorer/renderers.tsx | 17 ++++++--- .../details-panel/collection-details.tsx | 3 +- .../details-panel/details-panel.tsx | 5 +-- .../collection-content-address-panel.tsx | 4 +- 10 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 src/store/owner-name/owner-name-actions.ts create mode 100644 src/store/owner-name/owner-name-reducer.ts diff --git a/src/store/collection-panel/collection-panel-action.ts b/src/store/collection-panel/collection-panel-action.ts index 76a40dcb..b1dd8389 100644 --- a/src/store/collection-panel/collection-panel-action.ts +++ b/src/store/collection-panel/collection-panel-action.ts @@ -15,12 +15,10 @@ import { resourcesActions } from "~/store/resources/resources-actions"; import { unionize, ofType, UnionOf } from '~/common/unionize'; import { SnackbarKind } from '~/store/snackbar/snackbar-actions'; import { navigateTo } from '~/store/navigation/navigation-action'; -import { FilterBuilder } from "~/services/api/filter-builder"; import { loadDetailsPanel } from '~/store/details-panel/details-panel-action'; export const collectionPanelActions = unionize({ SET_COLLECTION: ofType(), - SET_NUMBER_OF_COLLECTIONS_WITH_SAME_PDH: ofType(), LOAD_COLLECTION: ofType<{ uuid: string }>(), LOAD_COLLECTION_SUCCESS: ofType<{ item: CollectionResource }>() }); @@ -34,12 +32,6 @@ export const loadCollectionPanel = (uuid: string) => dispatch(collectionPanelActions.LOAD_COLLECTION({ uuid })); dispatch(collectionPanelFilesAction.SET_COLLECTION_FILES({ files: createTree() })); const collection = await services.collectionService.get(uuid); - const collectionsByPDH = await services.collectionService.list({ - filters: new FilterBuilder() - .addEqual('portableDataHash', collection.portableDataHash) - .getFilters() - }); - dispatch(collectionPanelActions.SET_NUMBER_OF_COLLECTIONS_WITH_SAME_PDH(collectionsByPDH.itemsAvailable)); dispatch(loadDetailsPanel(collection.uuid)); dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: collection })); dispatch(resourcesActions.SET_RESOURCES([collection])); diff --git a/src/store/collection-panel/collection-panel-reducer.ts b/src/store/collection-panel/collection-panel-reducer.ts index 4207a393..f09b0198 100644 --- a/src/store/collection-panel/collection-panel-reducer.ts +++ b/src/store/collection-panel/collection-panel-reducer.ts @@ -7,18 +7,15 @@ import { CollectionResource } from "~/models/collection"; export interface CollectionPanelState { item: CollectionResource | null; - numberOfCollectionsWithSamePDH: number; } const initialState = { - item: null, - numberOfCollectionsWithSamePDH: 0 + item: null }; export const collectionPanelReducer = (state: CollectionPanelState = initialState, action: CollectionPanelAction) => collectionPanelActions.match(action, { default: () => state, SET_COLLECTION: (item) => ({ ...state, item }), - LOAD_COLLECTION_SUCCESS: ({ item }) => ({ ...state, item }), - SET_NUMBER_OF_COLLECTIONS_WITH_SAME_PDH: (num) => ({ ...state, numberOfCollectionsWithSamePDH: num }), + LOAD_COLLECTION_SUCCESS: ({ item }) => ({ ...state, item }) }); diff --git a/src/store/collections-content-address-panel/collections-content-address-middleware-service.ts b/src/store/collections-content-address-panel/collections-content-address-middleware-service.ts index 0e35d93f..642e7b82 100644 --- a/src/store/collections-content-address-panel/collections-content-address-middleware-service.ts +++ b/src/store/collections-content-address-panel/collections-content-address-middleware-service.ts @@ -21,6 +21,8 @@ import { navigateTo } from '~/store/navigation/navigation-action'; import { updateFavorites } from '~/store/favorites/favorites-actions'; import { updatePublicFavorites } from '~/store/public-favorites/public-favorites-actions'; import { setBreadcrumbs } from '../breadcrumbs/breadcrumbs-actions'; +import { ResourceKind, extractUuidKind } from '~/models/resource'; +import { ownerNameActions } from '~/store/owner-name/owner-name-actions'; export class CollectionsWithSameContentAddressMiddlewareService extends DataExplorerMiddlewareService { constructor(private services: ServiceRepository, id: string) { @@ -57,6 +59,41 @@ export class CollectionsWithSameContentAddressMiddlewareService extends DataExpl .addILike("name", dataExplorer.searchValue) .getFilters() }); + const userUuids = response.items.map(it => { + if (extractUuidKind(it.ownerUuid) === ResourceKind.USER) { + return it.ownerUuid; + } else { + return ''; + } + } + ); + const groupUuids = response.items.map(it => { + if (extractUuidKind(it.ownerUuid) === ResourceKind.GROUP) { + return it.ownerUuid; + } else { + return ''; + } + }); + const responseUsers = await this.services.userService.list({ + limit: dataExplorer.rowsPerPage, + offset: dataExplorer.page * dataExplorer.rowsPerPage, + filters: new FilterBuilder() + .addIn('uuid', userUuids) + .getFilters() + }); + const responseGroups = await this.services.groupsService.list({ + limit: dataExplorer.rowsPerPage, + offset: dataExplorer.page * dataExplorer.rowsPerPage, + filters: new FilterBuilder() + .addIn('uuid', groupUuids) + .getFilters() + }); + responseUsers.items.map(it=>{ + api.dispatch(ownerNameActions.SET_OWNER_NAME({name: it.uuid === userUuid ? 'User: Me' : `User: ${it.firstName} ${it.lastName}`, uuid: it.uuid})); + }); + responseGroups.items.map(it=>{ + api.dispatch(ownerNameActions.SET_OWNER_NAME({name: `Project: ${it.name}`, uuid: it.uuid})); + }); api.dispatch(setBreadcrumbs([{ label: 'Projects', uuid: userUuid }])); api.dispatch(updateFavorites(response.items.map(item => item.uuid))); api.dispatch(updatePublicFavorites(response.items.map(item => item.uuid))); diff --git a/src/store/owner-name/owner-name-actions.ts b/src/store/owner-name/owner-name-actions.ts new file mode 100644 index 00000000..6c2784a1 --- /dev/null +++ b/src/store/owner-name/owner-name-actions.ts @@ -0,0 +1,16 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { unionize, ofType, UnionOf } from '~/common/unionize'; + +export const ownerNameActions = unionize({ + SET_OWNER_NAME: ofType() +}); + +interface OwnerNameState { + name: string; + uuid: string; +} + +export type OwnerNameAction = UnionOf; diff --git a/src/store/owner-name/owner-name-reducer.ts b/src/store/owner-name/owner-name-reducer.ts new file mode 100644 index 00000000..58df209f --- /dev/null +++ b/src/store/owner-name/owner-name-reducer.ts @@ -0,0 +1,11 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { ownerNameActions, OwnerNameAction } from './owner-name-actions'; + +export const ownerNameReducer = (state = [], action: OwnerNameAction) => + ownerNameActions.match(action, { + SET_OWNER_NAME: data => [...state, { uuid: data.uuid, name: data.name }], + default: () => state, + }); \ No newline at end of file diff --git a/src/store/store.ts b/src/store/store.ts index eff2454a..ff9a495e 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -64,6 +64,7 @@ import { PUBLIC_FAVORITE_PANEL_ID } from '~/store/public-favorites-panel/public- import { publicFavoritesReducer } from '~/store/public-favorites/public-favorites-reducer'; 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'; const composeEnhancers = (process.env.NODE_ENV === 'development' && @@ -153,6 +154,7 @@ const createRootReducer = (services: ServiceRepository) => combineReducers({ detailsPanel: detailsPanelReducer, dialog: dialogReducer, favorites: favoritesReducer, + ownerName: ownerNameReducer, publicFavorites: publicFavoritesReducer, form: formReducer, processLogsPanel: processLogsPanelReducer, diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx index 52760cb4..bf504f2b 100644 --- a/src/views-components/data-explorer/renderers.tsx +++ b/src/views-components/data-explorer/renderers.tsx @@ -26,15 +26,14 @@ import { toggleIsActive, toggleIsAdmin } from '~/store/users/users-actions'; import { LinkResource } from '~/models/link'; import { navigateTo } from '~/store/navigation/navigation-action'; import { withResourceData } from '~/views-components/data-explorer/with-resources'; -import { extractUuidKind } from '~/models/resource'; -const renderName = (item: { name: string; uuid: string, kind: string }) => +const renderName = (dispatch: Dispatch, item: { name: string; uuid: string, kind: string }) => {renderIcon(item.kind)} - + dispatch(navigateTo(item.uuid))}> {item.name} @@ -50,7 +49,7 @@ export const ResourceName = connect( (state: RootState, props: { uuid: string }) => { const resource = getResource(props.uuid)(state.resources); return resource || { name: '', uuid: '', kind: '' }; - })(renderName); + })((resource: { name: string; uuid: string, kind: string } & DispatchProp) => renderName(resource.dispatch, resource)); const renderIcon = (kind: string) => { switch (kind) { @@ -402,7 +401,7 @@ export const ResourceFileSize = connect( })((props: { fileSize?: number }) => renderFileSize(props.fileSize)); const renderOwner = (owner: string) => - + {owner} ; @@ -412,6 +411,14 @@ export const ResourceOwner = connect( return { owner: resource ? resource.ownerUuid : '' }; })((props: { owner: string }) => renderOwner(props.owner)); +export const ResourceOwnerName = connect( + (state: RootState, props: { uuid: string }) => { + const resource = getResource(props.uuid)(state.resources); + const ownerNameState = state.ownerName; + const ownerName = ownerNameState.find(it => it.uuid === resource!.ownerUuid); + return { owner: ownerName ? ownerName!.name : resource!.ownerUuid }; + })((props: { owner: string }) => renderOwner(props.owner)); + const renderType = (type: string) => {resourceLabel(type)} diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx index b47e9edf..ec5bdabd 100644 --- a/src/views-components/details-panel/collection-details.tsx +++ b/src/views-components/details-panel/collection-details.tsx @@ -24,9 +24,8 @@ export class CollectionDetails extends DetailsData { - {/* Links but we dont have view */} - + {/* Missing attrs */} diff --git a/src/views-components/details-panel/details-panel.tsx b/src/views-components/details-panel/details-panel.tsx index 5c8ebe74..be255cb7 100644 --- a/src/views-components/details-panel/details-panel.tsx +++ b/src/views-components/details-panel/details-panel.tsx @@ -79,14 +79,13 @@ const getItem = (res: DetailsResource, resourceData?: ResourceData, numberOfColl } }; -const mapStateToProps = ({ detailsPanel, resources, resourcesData, collectionPanelFiles, collectionPanel }: RootState) => { +const mapStateToProps = ({ detailsPanel, resources, resourcesData, collectionPanelFiles }: RootState) => { const resource = getResource(detailsPanel.resourceUuid)(resources) as DetailsResource | undefined; const file = getNode(detailsPanel.resourceUuid)(collectionPanelFiles); const resourceData = getResourceData(detailsPanel.resourceUuid)(resourcesData); - const numberOfCollectionsByPDH = collectionPanel.numberOfCollectionsWithSamePDH; return { isOpened: detailsPanel.isOpened, - item: getItem(resource || (file && file.value) || EMPTY_RESOURCE, resourceData, numberOfCollectionsByPDH), + item: getItem(resource || (file && file.value) || EMPTY_RESOURCE, resourceData), }; }; diff --git a/src/views/collection-content-address-panel/collection-content-address-panel.tsx b/src/views/collection-content-address-panel/collection-content-address-panel.tsx index 425588f1..89b23f7c 100644 --- a/src/views/collection-content-address-panel/collection-content-address-panel.tsx +++ b/src/views/collection-content-address-panel/collection-content-address-panel.tsx @@ -20,7 +20,7 @@ import { navigateTo } from '~/store/navigation/navigation-action'; import { DataColumns } from '~/components/data-table/data-table'; import { SortDirection } from '~/components/data-table/data-column'; import { createTree } from '~/models/tree'; -import { ResourceName, ResourceOwner, ResourceLastModifiedDate } from '~/views-components/data-explorer/renderers'; +import { ResourceName, ResourceOwnerName, ResourceLastModifiedDate } from '~/views-components/data-explorer/renderers'; type CssRules = 'backLink' | 'backIcon' | 'card' | 'title' | 'iconHeader' | 'link'; @@ -77,7 +77,7 @@ export const collectionContentAddressPanelColumns: DataColumns = [ selected: true, configurable: true, filters: createTree(), - render: uuid => + render: uuid => }, { name: CollectionContentAddressPanelColumnNames.LAST_MODIFIED, -- 2.30.2