[ARVADOS-WORKBENCH2] created: 1.3.1-453-g264be0e4
Git user
git at public.curoverse.com
Mon May 13 12:12:59 UTC 2019
at 264be0e4b5adc7bf81181505c446d83628f84bfb (commit)
commit 264be0e4b5adc7bf81181505c446d83628f84bfb
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Fri May 10 12:44:35 2019 +0200
setting-breadcrumbs
Feature #15020
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
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 fcc75340..0e35d93f 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
@@ -20,6 +20,7 @@ import { collectionsContentAddressActions } from './collections-content-address-
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';
export class CollectionsWithSameContentAddressMiddlewareService extends DataExplorerMiddlewareService {
constructor(private services: ServiceRepository, id: string) {
@@ -45,6 +46,7 @@ export class CollectionsWithSameContentAddressMiddlewareService extends DataExpl
}
try {
api.dispatch(progressIndicatorActions.START_WORKING(this.getId()));
+ const userUuid = api.getState().auth.user!.uuid;
const pathname = api.getState().router.location!.pathname;
const contentAddress = pathname.split('/')[2];
const response = await this.services.collectionService.list({
@@ -55,6 +57,7 @@ export class CollectionsWithSameContentAddressMiddlewareService extends DataExpl
.addILike("name", dataExplorer.searchValue)
.getFilters()
});
+ api.dispatch<any>(setBreadcrumbs([{ label: 'Projects', uuid: userUuid }]));
api.dispatch<any>(updateFavorites(response.items.map(item => item.uuid)));
api.dispatch<any>(updatePublicFavorites(response.items.map(item => item.uuid)));
if (response.itemsAvailable === 1) {
commit 9791e4a669e0573f155a9785de550e9cb8520296
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Fri May 10 12:33:47 2019 +0200
fixed-bug-when-navigating-not-rfom-collections
Feature #15020
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
diff --git a/src/components/details-attribute/details-attribute.tsx b/src/components/details-attribute/details-attribute.tsx
index b8955d4e..3586d22d 100644
--- a/src/components/details-attribute/details-attribute.tsx
+++ b/src/components/details-attribute/details-attribute.tsx
@@ -60,7 +60,7 @@ export const DetailsAttribute = withStyles(styles)(
<Typography component="div" className={classes.attribute}>
<Typography component="span" className={classnames([classes.label, classLabel])}>{label}</Typography>
{link && <a href={link} className={classes.link} target='_blank'>{value}</a>}
- {linkInsideCard && <Link to={linkInsideCard} className={classes.link}>{value}</Link>}
+ {linkInsideCard && <Link to={`/collections/${linkInsideCard}`} className={classes.link}>{value}</Link>}
{!link && !linkInsideCard && <Typography
onClick={onValueClick}
component="span"
commit a6ca8c85942e16d50fe32cbba5f5b1e32a480ec5
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Fri May 10 12:22:20 2019 +0200
title-for-data-table
Feature #15020
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx
index 7c1f9045..5f019577 100644
--- a/src/components/data-explorer/data-explorer.tsx
+++ b/src/components/data-explorer/data-explorer.tsx
@@ -14,7 +14,7 @@ import { DataTableFilters } from '~/components/data-table-filters/data-table-fil
import { MoreOptionsIcon } from '~/components/icon/icon';
import { PaperProps } from '@material-ui/core/Paper';
-type CssRules = 'searchBox' | "toolbar" | "footer" | "root" | 'moreOptionsButton';
+type CssRules = 'searchBox' | "toolbar" | "footer" | "root" | 'moreOptionsButton' | 'title';
const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
searchBox: {
@@ -31,6 +31,11 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
},
moreOptionsButton: {
padding: 0
+ },
+ title: {
+ paddingLeft: theme.spacing.unit * 3,
+ paddingTop: theme.spacing.unit * 3,
+ fontSize: '18px'
}
});
@@ -52,6 +57,7 @@ interface DataExplorerDataProps<T> {
hideSearchInput?: boolean;
paperKey?: string;
currentItemUuid: string;
+ title?: string;
}
interface DataExplorerActionProps<T> {
@@ -84,9 +90,10 @@ export const DataExplorer = withStyles(styles)(
rowsPerPage, rowsPerPageOptions, onColumnToggle, searchValue, onSearch,
items, itemsAvailable, onRowClick, onRowDoubleClick, classes,
dataTableDefaultView, hideColumnSelector, actions, paperProps, hideSearchInput,
- paperKey, fetchMode, currentItemUuid
+ paperKey, fetchMode, currentItemUuid, title
} = this.props;
return <Paper className={classes.root} {...paperProps} key={paperKey}>
+ {title ? <div className={classes.title}>Content Address: {title}</div> : null}
{(!hideColumnSelector || !hideSearchInput) && <Toolbar className={classes.toolbar}>
<Grid container justify="space-between" wrap="nowrap" alignItems="center">
<div className={classes.searchBox}>
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 f2c6df34..dfe1b5bf 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
@@ -121,9 +121,15 @@ const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressPanelAc
}
});
+interface CollectionContentAddressDataProps {
+ match: {
+ params: { id: string }
+ };
+}
+
export const CollectionsContentAddressPanel = withStyles(styles)(
connect(null, mapDispatchToProps)(
- class extends React.Component<CollectionContentAddressPanelActionProps & WithStyles<CssRules>> {
+ class extends React.Component<CollectionContentAddressPanelActionProps & CollectionContentAddressDataProps & WithStyles<CssRules>> {
render() {
return <Grid item xs={12}>
{/* <Link to={`/collections/${collectionUuid}`} className={this.props.classes.backLink}>
@@ -136,6 +142,7 @@ export const CollectionsContentAddressPanel = withStyles(styles)(
onRowDoubleClick={this.props.onItemDoubleClick}
onContextMenu={this.props.onContextMenu}
contextMenuColumn={true}
+ title={this.props.match.params.id}
dataTableDefaultView={
<DataTableDefaultView
icon={CollectionIcon}
commit 600473ba57f6a25281d1d2094eab2ad51bfd9a4b
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Fri May 10 11:55:58 2019 +0200
search-for-data-table-and-small-improvements
Feature #15020
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
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 c1893f6d..fcc75340 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
@@ -18,6 +18,8 @@ import { GroupContentsResource, GroupContentsResourcePrefix } from '~/services/g
import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions';
import { collectionsContentAddressActions } from './collections-content-address-panel-actions';
import { navigateTo } from '~/store/navigation/navigation-action';
+import { updateFavorites } from '~/store/favorites/favorites-actions';
+import { updatePublicFavorites } from '~/store/public-favorites/public-favorites-actions';
export class CollectionsWithSameContentAddressMiddlewareService extends DataExplorerMiddlewareService {
constructor(private services: ServiceRepository, id: string) {
@@ -50,8 +52,11 @@ export class CollectionsWithSameContentAddressMiddlewareService extends DataExpl
offset: dataExplorer.page * dataExplorer.rowsPerPage,
filters: new FilterBuilder()
.addEqual('portableDataHash', contentAddress)
+ .addILike("name", dataExplorer.searchValue)
.getFilters()
});
+ api.dispatch<any>(updateFavorites(response.items.map(item => item.uuid)));
+ api.dispatch<any>(updatePublicFavorites(response.items.map(item => item.uuid)));
if (response.itemsAvailable === 1) {
api.dispatch<any>(navigateTo(response.items[0].uuid));
api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
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 5ca392fe..f2c6df34 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
@@ -62,7 +62,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
enum CollectionContentAddressPanelColumnNames {
COLLECTION_WITH_THIS_ADDRESS = "Collection with this address",
- OWNER = "Owner",
+ LOCATION = "Location",
LAST_MODIFIED = "Last modified"
}
@@ -76,7 +76,7 @@ export const collectionContentAddressPanelColumns: DataColumns<string> = [
render: uuid => <ResourceName uuid={uuid} />
},
{
- name: CollectionContentAddressPanelColumnNames.OWNER,
+ name: CollectionContentAddressPanelColumnNames.LOCATION,
selected: true,
configurable: true,
filters: createTree(),
@@ -92,13 +92,13 @@ export const collectionContentAddressPanelColumns: DataColumns<string> = [
}
];
-export interface CollectionContentAddressMainCardActionProps {
+export interface CollectionContentAddressPanelActionProps {
onContextMenu: (event: React.MouseEvent<any>, uuid: string) => void;
onItemClick: (item: string) => void;
onItemDoubleClick: (item: string) => void;
}
-const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressMainCardActionProps => ({
+const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressPanelActionProps => ({
onContextMenu: (event, resourceUuid) => {
const isAdmin = dispatch<any>(getIsAdmin());
const kind = resourceKindToContextMenuKind(resourceUuid, isAdmin);
@@ -123,12 +123,12 @@ const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressMainCar
export const CollectionsContentAddressPanel = withStyles(styles)(
connect(null, mapDispatchToProps)(
- class extends React.Component<CollectionContentAddressMainCardActionProps & WithStyles<CssRules>> {
+ class extends React.Component<CollectionContentAddressPanelActionProps & WithStyles<CssRules>> {
render() {
return <Grid item xs={12}>
- {/* <Link to={`/collections/${this.props.collection.uuid}`} className={this.props.classes.backLink}>
+ {/* <Link to={`/collections/${collectionUuid}`} className={this.props.classes.backLink}>
<BackIcon className={this.props.classes.backIcon} />
- Back test
+ Back
</Link> */}
<DataExplorer
id={COLLECTIONS_CONTENT_ADDRESS_PANEL_ID}
commit 98d1b780b15d9995ec5ef6cae25c0663702ede4f
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Wed May 8 14:14:35 2019 +0200
data-table-columns-change
Feature #15020
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 25852cbf..2363b579 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -94,6 +94,7 @@ import { DataTableFetchMode } from "~/components/data-table/data-table";
import { loadPublicFavoritePanel, publicFavoritePanelActions } from '~/store/public-favorites-panel/public-favorites-action';
import { publicFavoritePanelColumns } from '~/views/public-favorites-panel/public-favorites-panel';
import { loadCollectionsContentAddressPanel, collectionsContentAddressActions } from '~/store/collections-content-address-panel/collections-content-address-panel-actions';
+import { collectionContentAddressPanelColumns } from '~/views/collection-content-address-panel/collection-content-address-panel';
export const WORKBENCH_LOADING_SCREEN = 'workbenchLoadingScreen';
@@ -133,7 +134,7 @@ export const loadWorkbench = () =>
dispatch(linkPanelActions.SET_COLUMNS({ columns: linkPanelColumns }));
dispatch(computeNodesActions.SET_COLUMNS({ columns: computeNodePanelColumns }));
dispatch(apiClientAuthorizationsActions.SET_COLUMNS({ columns: apiClientAuthorizationPanelColumns }));
- dispatch(collectionsContentAddressActions.SET_COLUMNS({ columns: projectPanelColumns }));
+ dispatch(collectionsContentAddressActions.SET_COLUMNS({ columns: collectionContentAddressPanelColumns }));
dispatch<any>(initSidePanelTree());
if (router.location) {
diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx
index 5dc1e02a..52760cb4 100644
--- a/src/views-components/data-explorer/renderers.tsx
+++ b/src/views-components/data-explorer/renderers.tsx
@@ -26,6 +26,7 @@ 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 }) =>
<Grid container alignItems="center" wrap="nowrap" spacing={16}>
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 009e16c7..5ca392fe 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
@@ -10,7 +10,6 @@ import {
import { CollectionIcon } from '~/components/icon/icon';
import { ArvadosTheme } from '~/common/custom-theme';
import { BackIcon } from '~/components/icon/icon';
-import { CollectionResource } from '~/models/collection';
import { DataTableDefaultView } from '~/components/data-table-default-view/data-table-default-view';
import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from '~/store/collections-content-address-panel/collections-content-address-panel-actions';
import { DataExplorer } from "~/views-components/data-explorer/data-explorer";
@@ -19,8 +18,12 @@ import { getIsAdmin } from '~/store/public-favorites/public-favorites-actions';
import { resourceKindToContextMenuKind, openContextMenu } from '~/store/context-menu/context-menu-actions';
import { ResourceKind } from '~/models/resource';
import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
-import { connect, DispatchProp } from 'react-redux';
+import { connect } from 'react-redux';
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';
type CssRules = 'backLink' | 'backIcon' | 'card' | 'title' | 'iconHeader' | 'link';
@@ -57,6 +60,37 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
}
});
+enum CollectionContentAddressPanelColumnNames {
+ COLLECTION_WITH_THIS_ADDRESS = "Collection with this address",
+ OWNER = "Owner",
+ LAST_MODIFIED = "Last modified"
+}
+
+export const collectionContentAddressPanelColumns: DataColumns<string> = [
+ {
+ name: CollectionContentAddressPanelColumnNames.COLLECTION_WITH_THIS_ADDRESS,
+ selected: true,
+ configurable: true,
+ sortDirection: SortDirection.NONE,
+ filters: createTree(),
+ render: uuid => <ResourceName uuid={uuid} />
+ },
+ {
+ name: CollectionContentAddressPanelColumnNames.OWNER,
+ selected: true,
+ configurable: true,
+ filters: createTree(),
+ render: uuid => <ResourceOwner uuid={uuid} />
+ },
+ {
+ name: CollectionContentAddressPanelColumnNames.LAST_MODIFIED,
+ selected: true,
+ configurable: true,
+ sortDirection: SortDirection.DESC,
+ filters: createTree(),
+ render: uuid => <ResourceLastModifiedDate uuid={uuid} />
+ }
+];
export interface CollectionContentAddressMainCardActionProps {
onContextMenu: (event: React.MouseEvent<any>, uuid: string) => void;
commit 59995a3eed71636c7b3be3729a41d8a90ee2486c
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Wed May 8 13:34:07 2019 +0200
navigate-to-collection-when-there-is-only-one-collection-with-given-content-address
Feature #15020
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
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 53c45d57..c1893f6d 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
@@ -17,6 +17,7 @@ import { FavoritePanelColumnNames } from '~/views/favorite-panel/favorite-panel'
import { GroupContentsResource, GroupContentsResourcePrefix } from '~/services/groups-service/groups-service';
import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions';
import { collectionsContentAddressActions } from './collections-content-address-panel-actions';
+import { navigateTo } from '~/store/navigation/navigation-action';
export class CollectionsWithSameContentAddressMiddlewareService extends DataExplorerMiddlewareService {
constructor(private services: ServiceRepository, id: string) {
@@ -51,14 +52,19 @@ export class CollectionsWithSameContentAddressMiddlewareService extends DataExpl
.addEqual('portableDataHash', contentAddress)
.getFilters()
});
- api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
- api.dispatch(resourcesActions.SET_RESOURCES(response.items));
- api.dispatch(collectionsContentAddressActions.SET_ITEMS({
- items: response.items.map((resource: any) => resource.uuid),
- itemsAvailable: response.itemsAvailable,
- page: Math.floor(response.offset / response.limit),
- rowsPerPage: response.limit
- }));
+ if (response.itemsAvailable === 1) {
+ api.dispatch<any>(navigateTo(response.items[0].uuid));
+ api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
+ } else {
+ api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
+ api.dispatch(resourcesActions.SET_RESOURCES(response.items));
+ api.dispatch(collectionsContentAddressActions.SET_ITEMS({
+ items: response.items.map((resource: any) => resource.uuid),
+ itemsAvailable: response.itemsAvailable,
+ page: Math.floor(response.offset / response.limit),
+ rowsPerPage: response.limit
+ }));
+ }
} catch (e) {
api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
api.dispatch(collectionsContentAddressActions.SET_ITEMS({
commit 2d9dcf3d61d410328e081b5b00c7175c7eb1d82b
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Wed May 8 13:27:55 2019 +0200
routing+init-data-explorer
Feature #15020
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
diff --git a/src/components/details-attribute/details-attribute.tsx b/src/components/details-attribute/details-attribute.tsx
index d255d14b..b8955d4e 100644
--- a/src/components/details-attribute/details-attribute.tsx
+++ b/src/components/details-attribute/details-attribute.tsx
@@ -7,6 +7,7 @@ import Typography from '@material-ui/core/Typography';
import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
import { ArvadosTheme } from '~/common/custom-theme';
import * as classnames from "classnames";
+import { Link } from 'react-router-dom';
type CssRules = 'attribute' | 'label' | 'value' | 'lowercaseValue' | 'link';
@@ -49,23 +50,25 @@ interface DetailsAttributeDataProps {
link?: string;
children?: React.ReactNode;
onValueClick?: () => void;
+ linkInsideCard?: string;
}
type DetailsAttributeProps = DetailsAttributeDataProps & WithStyles<CssRules>;
export const DetailsAttribute = withStyles(styles)(
- ({ label, link, value, children, classes, classLabel, classValue, lowercaseValue, onValueClick }: DetailsAttributeProps) =>
+ ({ label, link, value, children, classes, classLabel, classValue, lowercaseValue, onValueClick, linkInsideCard }: DetailsAttributeProps) =>
<Typography component="div" className={classes.attribute}>
<Typography component="span" className={classnames([classes.label, classLabel])}>{label}</Typography>
- { link
- ? <a href={link} className={classes.link} target='_blank'>{value}</a>
- : <Typography
- onClick={onValueClick}
- component="span"
- className={classnames([classes.value, classValue, { [classes.lowercaseValue]: lowercaseValue }])}
- >
- {value}
- {children}
- </Typography> }
+ {link && <a href={link} className={classes.link} target='_blank'>{value}</a>}
+ {linkInsideCard && <Link to={linkInsideCard} className={classes.link}>{value}</Link>}
+ {!link && !linkInsideCard && <Typography
+ onClick={onValueClick}
+ component="span"
+ className={classnames([classes.value, classValue, { [classes.lowercaseValue]: lowercaseValue }])}>
+ {value}
+ {children}
+ </Typography>
+ }
+
</Typography>
);
diff --git a/src/routes/route-change-handlers.ts b/src/routes/route-change-handlers.ts
index 2811f95a..50ba319e 100644
--- a/src/routes/route-change-handlers.ts
+++ b/src/routes/route-change-handlers.ts
@@ -23,7 +23,7 @@ const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
const projectMatch = Routes.matchProjectRoute(pathname);
const collectionMatch = Routes.matchCollectionRoute(pathname);
const favoriteMatch = Routes.matchFavoritesRoute(pathname);
- const publicFavoritesMatch = Routes.matchPublicFavorites(pathname);
+ const publicFavoritesMatch = Routes.matchPublicFavoritesRoute(pathname);
const trashMatch = Routes.matchTrashRoute(pathname);
const processMatch = Routes.matchProcessRoute(pathname);
const processLogMatch = Routes.matchProcessLogRoute(pathname);
@@ -45,6 +45,7 @@ const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
const groupsMatch = Routes.matchGroupsRoute(pathname);
const groupDetailsMatch = Routes.matchGroupDetailsRoute(pathname);
const linksMatch = Routes.matchLinksRoute(pathname);
+ const collectionsContentAddressMatch = Routes.matchCollectionsContentAddressRoute(pathname);
store.dispatch(dialogActions.CLOSE_ALL_DIALOGS());
store.dispatch(contextMenuActions.CLOSE_CONTEXT_MENU());
@@ -102,5 +103,7 @@ const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
store.dispatch(WorkbenchActions.loadGroupDetailsPanel(groupDetailsMatch.params.id));
} else if (linksMatch) {
store.dispatch(WorkbenchActions.loadLinks);
+ } else if (collectionsContentAddressMatch) {
+ store.dispatch(WorkbenchActions.loadCollectionContentAddress);
}
};
\ No newline at end of file
diff --git a/src/routes/routes.ts b/src/routes/routes.ts
index 3fd6670d..dd09d8ec 100644
--- a/src/routes/routes.ts
+++ b/src/routes/routes.ts
@@ -34,7 +34,8 @@ export const Routes = {
GROUPS: '/groups',
GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
LINKS: '/links',
- PUBLIC_FAVORITES: '/public-favorites'
+ PUBLIC_FAVORITES: '/public-favorites',
+ COLLECTIONS_CONTENT_ADDRESS: '/collections/:id',
};
export const getResourceUrl = (uuid: string) => {
@@ -136,5 +137,8 @@ export const matchGroupDetailsRoute = (route: string) =>
export const matchLinksRoute = (route: string) =>
matchPath(route, { path: Routes.LINKS });
-export const matchPublicFavorites = (route: string) =>
+export const matchPublicFavoritesRoute = (route: string) =>
matchPath(route, { path: Routes.PUBLIC_FAVORITES });
+
+export const matchCollectionsContentAddressRoute = (route: string) =>
+ matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });
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
new file mode 100644
index 00000000..53c45d57
--- /dev/null
+++ b/src/store/collections-content-address-panel/collections-content-address-middleware-service.ts
@@ -0,0 +1,86 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ServiceRepository } from '~/services/services';
+import { MiddlewareAPI, Dispatch } from 'redux';
+import { DataExplorerMiddlewareService } from '~/store/data-explorer/data-explorer-middleware-service';
+import { RootState } from '~/store/store';
+import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
+import { getDataExplorer } from '~/store/data-explorer/data-explorer-reducer';
+import { resourcesActions } from '~/store/resources/resources-actions';
+import { FilterBuilder } from '~/services/api/filter-builder';
+import { SortDirection } from '~/components/data-table/data-column';
+import { OrderDirection, OrderBuilder } from '~/services/api/order-builder';
+import { getSortColumn } from "~/store/data-explorer/data-explorer-reducer";
+import { FavoritePanelColumnNames } from '~/views/favorite-panel/favorite-panel';
+import { GroupContentsResource, GroupContentsResourcePrefix } from '~/services/groups-service/groups-service';
+import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions';
+import { collectionsContentAddressActions } from './collections-content-address-panel-actions';
+
+export class CollectionsWithSameContentAddressMiddlewareService extends DataExplorerMiddlewareService {
+ constructor(private services: ServiceRepository, id: string) {
+ super(id);
+ }
+
+ async requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
+ const dataExplorer = getDataExplorer(api.getState().dataExplorer, this.getId());
+ if (!dataExplorer) {
+ api.dispatch(collectionPanelDataExplorerIsNotSet());
+ } else {
+ const sortColumn = getSortColumn(dataExplorer);
+
+ const contentOrder = new OrderBuilder<GroupContentsResource>();
+
+ if (sortColumn && sortColumn.name === FavoritePanelColumnNames.NAME) {
+ const direction = sortColumn.sortDirection === SortDirection.ASC
+ ? OrderDirection.ASC
+ : OrderDirection.DESC;
+
+ contentOrder
+ .addOrder(direction, "name", GroupContentsResourcePrefix.COLLECTION);
+ }
+ try {
+ api.dispatch(progressIndicatorActions.START_WORKING(this.getId()));
+ const pathname = api.getState().router.location!.pathname;
+ const contentAddress = pathname.split('/')[2];
+ const response = await this.services.collectionService.list({
+ limit: dataExplorer.rowsPerPage,
+ offset: dataExplorer.page * dataExplorer.rowsPerPage,
+ filters: new FilterBuilder()
+ .addEqual('portableDataHash', contentAddress)
+ .getFilters()
+ });
+ api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
+ api.dispatch(resourcesActions.SET_RESOURCES(response.items));
+ api.dispatch(collectionsContentAddressActions.SET_ITEMS({
+ items: response.items.map((resource: any) => resource.uuid),
+ itemsAvailable: response.itemsAvailable,
+ page: Math.floor(response.offset / response.limit),
+ rowsPerPage: response.limit
+ }));
+ } catch (e) {
+ api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
+ api.dispatch(collectionsContentAddressActions.SET_ITEMS({
+ items: [],
+ itemsAvailable: 0,
+ page: 0,
+ rowsPerPage: dataExplorer.rowsPerPage
+ }));
+ api.dispatch(couldNotFetchCollections());
+ }
+ }
+ }
+}
+
+const collectionPanelDataExplorerIsNotSet = () =>
+ snackbarActions.OPEN_SNACKBAR({
+ message: 'Collection panel is not ready.',
+ kind: SnackbarKind.ERROR
+ });
+
+const couldNotFetchCollections = () =>
+ snackbarActions.OPEN_SNACKBAR({
+ message: 'Could not fetch collection with this content address.',
+ kind: SnackbarKind.ERROR
+ });
\ No newline at end of file
diff --git a/src/store/collections-content-address-panel/collections-content-address-panel-actions.ts b/src/store/collections-content-address-panel/collections-content-address-panel-actions.ts
new file mode 100644
index 00000000..11f1a8cc
--- /dev/null
+++ b/src/store/collections-content-address-panel/collections-content-address-panel-actions.ts
@@ -0,0 +1,15 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from "redux";
+import { bindDataExplorerActions } from '~/store/data-explorer/data-explorer-action';
+
+export const COLLECTIONS_CONTENT_ADDRESS_PANEL_ID = 'collectionsContentAddressPanel';
+
+export const collectionsContentAddressActions = bindDataExplorerActions(COLLECTIONS_CONTENT_ADDRESS_PANEL_ID);
+
+export const loadCollectionsContentAddressPanel = () =>
+ (dispatch: Dispatch) => {
+ dispatch(collectionsContentAddressActions.REQUEST_ITEMS());
+ };
diff --git a/src/store/navigation/navigation-action.ts b/src/store/navigation/navigation-action.ts
index af7a0c03..d7ad0178 100644
--- a/src/store/navigation/navigation-action.ts
+++ b/src/store/navigation/navigation-action.ts
@@ -98,3 +98,5 @@ export const navigateToGroups = push(Routes.GROUPS);
export const navigateToGroupDetails = compose(push, getGroupUrl);
export const navigateToLinks = push(Routes.LINKS);
+
+export const navigateToCollectionsContentAddress = push(Routes.COLLECTIONS_CONTENT_ADDRESS);
diff --git a/src/store/store.ts b/src/store/store.ts
index 9d7dcdd4..eff2454a 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -62,6 +62,8 @@ import { ApiClientAuthorizationMiddlewareService } from '~/store/api-client-auth
import { PublicFavoritesMiddlewareService } from '~/store/public-favorites-panel/public-favorites-middleware-service';
import { PUBLIC_FAVORITE_PANEL_ID } from '~/store/public-favorites-panel/public-favorites-action';
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';
const composeEnhancers =
(process.env.NODE_ENV === 'development' &&
@@ -115,6 +117,10 @@ export function configureStore(history: History, services: ServiceRepository): R
const publicFavoritesMiddleware = dataExplorerMiddleware(
new PublicFavoritesMiddlewareService(services, PUBLIC_FAVORITE_PANEL_ID)
);
+ const collectionsContentAddress = dataExplorerMiddleware(
+ new CollectionsWithSameContentAddressMiddlewareService(services, COLLECTIONS_CONTENT_ADDRESS_PANEL_ID)
+ );
+
const middlewares: Middleware[] = [
routerMiddleware(history),
thunkMiddleware.withExtraArgument(services),
@@ -130,7 +136,8 @@ export function configureStore(history: History, services: ServiceRepository): R
linkPanelMiddleware,
computeNodeMiddleware,
apiClientAuthorizationMiddlewareService,
- publicFavoritesMiddleware
+ publicFavoritesMiddleware,
+ collectionsContentAddress
];
const enhancer = composeEnhancers(applyMiddleware(...middlewares));
return createStore(rootReducer, enhancer);
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 378bb8de..25852cbf 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -93,6 +93,7 @@ import { groupDetailsPanelColumns } from '~/views/group-details-panel/group-deta
import { DataTableFetchMode } from "~/components/data-table/data-table";
import { loadPublicFavoritePanel, publicFavoritePanelActions } from '~/store/public-favorites-panel/public-favorites-action';
import { publicFavoritePanelColumns } from '~/views/public-favorites-panel/public-favorites-panel';
+import { loadCollectionsContentAddressPanel, collectionsContentAddressActions } from '~/store/collections-content-address-panel/collections-content-address-panel-actions';
export const WORKBENCH_LOADING_SCREEN = 'workbenchLoadingScreen';
@@ -132,6 +133,7 @@ export const loadWorkbench = () =>
dispatch(linkPanelActions.SET_COLUMNS({ columns: linkPanelColumns }));
dispatch(computeNodesActions.SET_COLUMNS({ columns: computeNodePanelColumns }));
dispatch(apiClientAuthorizationsActions.SET_COLUMNS({ columns: apiClientAuthorizationPanelColumns }));
+ dispatch(collectionsContentAddressActions.SET_COLUMNS({ columns: projectPanelColumns }));
dispatch<any>(initSidePanelTree());
if (router.location) {
@@ -153,6 +155,11 @@ export const loadFavorites = () =>
dispatch<any>(setSidePanelBreadcrumbs(SidePanelTreeCategory.FAVORITES));
});
+export const loadCollectionContentAddress = handleFirstTimeLoad(
+ async (dispatch: Dispatch<any>) => {
+ await dispatch(loadCollectionsContentAddressPanel());
+ });
+
export const loadTrash = () =>
handleFirstTimeLoad(
(dispatch: Dispatch) => {
@@ -255,7 +262,7 @@ export const loadCollection = (uuid: string) =>
dispatch(collectionPanelActions.SET_COLLECTION(collection as CollectionResource));
dispatch(updateResources([collection]));
await dispatch(activateSidePanelTreeItem(collection.ownerUuid));
- dispatch(setSidePanelBreadcrumbs(collection.ownerUuid));
+ dispatch(setSidePanelBreadcrumbs(collection.ownerUuid));
dispatch(loadCollectionPanel(collection.uuid));
},
SHARED: collection => {
diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index 01b867b3..b47e9edf 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -25,8 +25,8 @@ export class CollectionDetails extends DetailsData<CollectionResource> {
<DetailsAttribute label='Last modified' value={formatDate(this.item.modifiedAt)} />
<DetailsAttribute label='Created at' value={formatDate(this.item.createdAt)} />
{/* Links but we dont have view */}
- <DetailsAttribute label='Collection UUID' link={this.item.uuid} value={this.item.uuid} />
- <DetailsAttribute label='Content address' link={this.numberOfCollectionsByPDH === 1 ? this.item.uuid : this.item.portableDataHash} value={this.item.portableDataHash} />
+ <DetailsAttribute label='Collection UUID' linkInsideCard={this.item.uuid} value={this.item.uuid} />
+ <DetailsAttribute label='Content address' linkInsideCard={this.numberOfCollectionsByPDH === 1 ? this.item.uuid : this.item.portableDataHash} value={this.item.portableDataHash} />
{/* Missing attrs */}
<DetailsAttribute label='Number of files' value={this.data && this.data.fileCount} />
<DetailsAttribute label='Content size' value={formatFileSize(this.data && this.data.fileSize)} />
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
new file mode 100644
index 00000000..009e16c7
--- /dev/null
+++ b/src/views/collection-content-address-panel/collection-content-address-panel.tsx
@@ -0,0 +1,114 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { Link } from 'react-router-dom';
+import {
+ StyleRulesCallback, WithStyles, withStyles, Grid
+} from '@material-ui/core';
+import { CollectionIcon } from '~/components/icon/icon';
+import { ArvadosTheme } from '~/common/custom-theme';
+import { BackIcon } from '~/components/icon/icon';
+import { CollectionResource } from '~/models/collection';
+import { DataTableDefaultView } from '~/components/data-table-default-view/data-table-default-view';
+import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from '~/store/collections-content-address-panel/collections-content-address-panel-actions';
+import { DataExplorer } from "~/views-components/data-explorer/data-explorer";
+import { Dispatch } from 'redux';
+import { getIsAdmin } from '~/store/public-favorites/public-favorites-actions';
+import { resourceKindToContextMenuKind, openContextMenu } from '~/store/context-menu/context-menu-actions';
+import { ResourceKind } from '~/models/resource';
+import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
+import { connect, DispatchProp } from 'react-redux';
+import { navigateTo } from '~/store/navigation/navigation-action';
+
+type CssRules = 'backLink' | 'backIcon' | 'card' | 'title' | 'iconHeader' | 'link';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ backLink: {
+ fontSize: '1rem',
+ fontWeight: 600,
+ display: 'flex',
+ alignItems: 'center',
+ textDecoration: 'none',
+ padding: theme.spacing.unit,
+ color: theme.palette.grey["700"],
+ },
+ backIcon: {
+ marginRight: theme.spacing.unit
+ },
+ card: {
+ width: '100%'
+ },
+ title: {
+ color: theme.palette.grey["700"]
+ },
+ iconHeader: {
+ fontSize: '1.875rem',
+ color: theme.customs.colors.green700
+ },
+ link: {
+ fontSize: '0.875rem',
+ color: theme.palette.primary.main,
+ textAlign: 'right',
+ '&:hover': {
+ cursor: 'pointer'
+ }
+ }
+});
+
+
+export interface CollectionContentAddressMainCardActionProps {
+ onContextMenu: (event: React.MouseEvent<any>, uuid: string) => void;
+ onItemClick: (item: string) => void;
+ onItemDoubleClick: (item: string) => void;
+}
+
+const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressMainCardActionProps => ({
+ onContextMenu: (event, resourceUuid) => {
+ const isAdmin = dispatch<any>(getIsAdmin());
+ const kind = resourceKindToContextMenuKind(resourceUuid, isAdmin);
+ if (kind) {
+ dispatch<any>(openContextMenu(event, {
+ name: '',
+ uuid: resourceUuid,
+ ownerUuid: '',
+ kind: ResourceKind.NONE,
+ menuKind: kind
+ }));
+ }
+ dispatch<any>(loadDetailsPanel(resourceUuid));
+ },
+ onItemClick: (uuid: string) => {
+ dispatch<any>(loadDetailsPanel(uuid));
+ },
+ onItemDoubleClick: uuid => {
+ dispatch<any>(navigateTo(uuid));
+ }
+});
+
+export const CollectionsContentAddressPanel = withStyles(styles)(
+ connect(null, mapDispatchToProps)(
+ class extends React.Component<CollectionContentAddressMainCardActionProps & WithStyles<CssRules>> {
+ render() {
+ return <Grid item xs={12}>
+ {/* <Link to={`/collections/${this.props.collection.uuid}`} className={this.props.classes.backLink}>
+ <BackIcon className={this.props.classes.backIcon} />
+ Back test
+ </Link> */}
+ <DataExplorer
+ id={COLLECTIONS_CONTENT_ADDRESS_PANEL_ID}
+ onRowClick={this.props.onItemClick}
+ onRowDoubleClick={this.props.onItemDoubleClick}
+ onContextMenu={this.props.onContextMenu}
+ contextMenuColumn={true}
+ dataTableDefaultView={
+ <DataTableDefaultView
+ icon={CollectionIcon}
+ messages={['Collections with this content address not found.']} />
+ } />;
+ </Grid >;
+ }
+ }
+ )
+);
\ No newline at end of file
diff --git a/src/views/favorite-panel/favorite-panel.tsx b/src/views/favorite-panel/favorite-panel.tsx
index 8498b787..e7234009 100644
--- a/src/views/favorite-panel/favorite-panel.tsx
+++ b/src/views/favorite-panel/favorite-panel.tsx
@@ -22,7 +22,6 @@ import {
ResourceType
} from '~/views-components/data-explorer/renderers';
import { FavoriteIcon } from '~/components/icon/icon';
-import { Dispatch } from 'redux';
import { openContextMenu, resourceKindToContextMenuKind } from '~/store/context-menu/context-menu-actions';
import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
import { navigateTo } from '~/store/navigation/navigation-action';
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index a31c7d25..e3668373 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -92,6 +92,7 @@ import { GroupMemberAttributesDialog } from '~/views-components/groups-dialog/me
import { AddGroupMembersDialog } from '~/views-components/dialog-forms/add-group-member-dialog';
import { PartialCopyToCollectionDialog } from '~/views-components/dialog-forms/partial-copy-to-collection-dialog';
import { PublicFavoritePanel } from '~/views/public-favorites-panel/public-favorites-panel';
+import { CollectionsContentAddressPanel } from '~/views/collection-content-address-panel/collection-content-address-panel';
type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content';
@@ -176,6 +177,7 @@ export const WorkbenchPanel =
<Route path={Routes.GROUP_DETAILS} component={GroupDetailsPanel} />
<Route path={Routes.LINKS} component={LinkPanel} />
<Route path={Routes.PUBLIC_FAVORITES} component={PublicFavoritePanel} />
+ <Route path={Routes.COLLECTIONS_CONTENT_ADDRESS} component={CollectionsContentAddressPanel}/>
</Switch>
</Grid>
</Grid>
commit ada23a4054724d0d6be4ee88efb22daecd86001f
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Mon May 6 12:06:59 2019 +0200
check-for-collections-with-same-content-adress
Feature #15020
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
diff --git a/src/store/collection-panel/collection-panel-action.ts b/src/store/collection-panel/collection-panel-action.ts
index cd426471..76a40dcb 100644
--- a/src/store/collection-panel/collection-panel-action.ts
+++ b/src/store/collection-panel/collection-panel-action.ts
@@ -7,7 +7,7 @@ import { loadCollectionFiles } from "./collection-panel-files/collection-panel-f
import { CollectionResource } from '~/models/collection';
import { collectionPanelFilesAction } from "./collection-panel-files/collection-panel-files-actions";
import { createTree } from "~/models/tree";
-import { RootState } from "../store";
+import { RootState } from "~/store/store";
import { ServiceRepository } from "~/services/services";
import { TagProperty } from "~/models/tag";
import { snackbarActions } from "../snackbar/snackbar-actions";
@@ -15,9 +15,12 @@ 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<CollectionResource>(),
+ SET_NUMBER_OF_COLLECTIONS_WITH_SAME_PDH: ofType<number>(),
LOAD_COLLECTION: ofType<{ uuid: string }>(),
LOAD_COLLECTION_SUCCESS: ofType<{ item: CollectionResource }>()
});
@@ -31,6 +34,13 @@ 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]));
dispatch<any>(loadCollectionFiles(collection.uuid));
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 b75de94a..534d70d4 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
@@ -77,8 +77,8 @@ export const openFileRemoveDialog = (filePath: string) =>
? 'Are you sure you want to remove this directory?'
: 'Are you sure you want to remove this file?';
const info = isDirectory
- ? 'Removing files will change content adress.'
- : 'Removing a file will change content adress.';
+ ? 'Removing files will change content address.'
+ : 'Removing a file will change content address.';
dispatch(dialogActions.OPEN_DIALOG({
id: FILE_REMOVE_DIALOG,
@@ -101,7 +101,7 @@ export const openMultipleFilesRemoveDialog = () =>
data: {
title: 'Removing files',
text: 'Are you sure you want to remove selected files?',
- info: 'Removing files will change content adress.',
+ info: 'Removing files will change content address.',
confirmButtonLabel: 'Remove'
}
});
diff --git a/src/store/collection-panel/collection-panel-reducer.ts b/src/store/collection-panel/collection-panel-reducer.ts
index 55829cb5..4207a393 100644
--- a/src/store/collection-panel/collection-panel-reducer.ts
+++ b/src/store/collection-panel/collection-panel-reducer.ts
@@ -7,10 +7,12 @@ import { CollectionResource } from "~/models/collection";
export interface CollectionPanelState {
item: CollectionResource | null;
+ numberOfCollectionsWithSamePDH: number;
}
const initialState = {
- item: null
+ item: null,
+ numberOfCollectionsWithSamePDH: 0
};
export const collectionPanelReducer = (state: CollectionPanelState = initialState, action: CollectionPanelAction) =>
@@ -18,4 +20,5 @@ export const collectionPanelReducer = (state: CollectionPanelState = initialStat
default: () => state,
SET_COLLECTION: (item) => ({ ...state, item }),
LOAD_COLLECTION_SUCCESS: ({ item }) => ({ ...state, item }),
+ SET_NUMBER_OF_COLLECTIONS_WITH_SAME_PDH: (num) => ({ ...state, numberOfCollectionsWithSamePDH: num }),
});
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index adf3fa15..378bb8de 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -68,8 +68,7 @@ import { FilterBuilder } from '~/services/api/filter-builder';
import { GroupContentsResource } from '~/services/groups-service/groups-service';
import { MatchCases, ofType, unionize, UnionOf } from '~/common/unionize';
import { loadRunProcessPanel } from '~/store/run-process-panel/run-process-panel-actions';
-import { loadCollectionFiles } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions';
-import { collectionPanelActions } from "~/store/collection-panel/collection-panel-action";
+import { collectionPanelActions, loadCollectionPanel } from "~/store/collection-panel/collection-panel-action";
import { CollectionResource } from "~/models/collection";
import {
loadSearchResultsPanel,
@@ -256,22 +255,22 @@ export const loadCollection = (uuid: string) =>
dispatch(collectionPanelActions.SET_COLLECTION(collection as CollectionResource));
dispatch(updateResources([collection]));
await dispatch(activateSidePanelTreeItem(collection.ownerUuid));
- dispatch(setSidePanelBreadcrumbs(collection.ownerUuid));
- dispatch(loadCollectionFiles(collection.uuid));
+ dispatch(setSidePanelBreadcrumbs(collection.ownerUuid));
+ dispatch(loadCollectionPanel(collection.uuid));
},
SHARED: collection => {
dispatch(collectionPanelActions.SET_COLLECTION(collection as CollectionResource));
dispatch(updateResources([collection]));
dispatch<any>(setSharedWithMeBreadcrumbs(collection.ownerUuid));
dispatch(activateSidePanelTreeItem(collection.ownerUuid));
- dispatch(loadCollectionFiles(collection.uuid));
+ dispatch(loadCollectionPanel(collection.uuid));
},
TRASHED: collection => {
dispatch(collectionPanelActions.SET_COLLECTION(collection as CollectionResource));
dispatch(updateResources([collection]));
dispatch(setTrashBreadcrumbs(''));
dispatch(activateSidePanelTreeItem(SidePanelTreeCategory.TRASH));
- dispatch(loadCollectionFiles(collection.uuid));
+ dispatch(loadCollectionPanel(collection.uuid));
},
});
diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index 98fa3886..01b867b3 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -26,7 +26,7 @@ export class CollectionDetails extends DetailsData<CollectionResource> {
<DetailsAttribute label='Created at' value={formatDate(this.item.createdAt)} />
{/* Links but we dont have view */}
<DetailsAttribute label='Collection UUID' link={this.item.uuid} value={this.item.uuid} />
- <DetailsAttribute label='Content address' link={this.item.portableDataHash} value={this.item.portableDataHash} />
+ <DetailsAttribute label='Content address' link={this.numberOfCollectionsByPDH === 1 ? this.item.uuid : this.item.portableDataHash} value={this.item.portableDataHash} />
{/* Missing attrs */}
<DetailsAttribute label='Number of files' value={this.data && this.data.fileCount} />
<DetailsAttribute label='Content size' value={formatFileSize(this.data && this.data.fileSize)} />
diff --git a/src/views-components/details-panel/details-data.tsx b/src/views-components/details-panel/details-data.tsx
index 45afb02b..1a67a55d 100644
--- a/src/views-components/details-panel/details-data.tsx
+++ b/src/views-components/details-panel/details-data.tsx
@@ -7,7 +7,7 @@ import { DetailsResource } from "~/models/details";
import { ResourceData } from "~/store/resources-data/resources-data-reducer";
export abstract class DetailsData<T extends DetailsResource = DetailsResource> {
- constructor(protected item: T, protected data?: ResourceData) {}
+ constructor(protected item: T, protected data?: ResourceData, protected numberOfCollectionsByPDH?: number) {}
getTitle(): string {
return this.item.name || 'Projects';
diff --git a/src/views-components/details-panel/details-panel.tsx b/src/views-components/details-panel/details-panel.tsx
index 2a30ae47..5c8ebe74 100644
--- a/src/views-components/details-panel/details-panel.tsx
+++ b/src/views-components/details-panel/details-panel.tsx
@@ -62,13 +62,13 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
const EMPTY_RESOURCE: EmptyResource = { kind: undefined, name: 'Projects' };
-const getItem = (res: DetailsResource, resourceData?: ResourceData): DetailsData => {
+const getItem = (res: DetailsResource, resourceData?: ResourceData, numberOfCollectionsByPDH?: number): DetailsData => {
if ('kind' in res) {
switch (res.kind) {
case ResourceKind.PROJECT:
return new ProjectDetails(res);
case ResourceKind.COLLECTION:
- return new CollectionDetails(res, resourceData);
+ return new CollectionDetails(res, resourceData, numberOfCollectionsByPDH);
case ResourceKind.PROCESS:
return new ProcessDetails(res);
default:
@@ -79,13 +79,14 @@ const getItem = (res: DetailsResource, resourceData?: ResourceData): DetailsData
}
};
-const mapStateToProps = ({ detailsPanel, resources, resourcesData, collectionPanelFiles }: RootState) => {
+const mapStateToProps = ({ detailsPanel, resources, resourcesData, collectionPanelFiles, collectionPanel }: 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)
+ item: getItem(resource || (file && file.value) || EMPTY_RESOURCE, resourceData, numberOfCollectionsByPDH),
};
};
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list