[ARVADOS-WORKBENCH2] updated: 1.2.0-675-g3f51c12
Git user
git at public.curoverse.com
Mon Oct 22 15:54:44 EDT 2018
Summary of changes:
src/models/collection.ts | 2 --
.../collection-panel-files-actions.ts | 2 ++
.../project-panel-middleware-service.ts | 30 ++++++--------------
src/store/resources-data/resources-data-actions.ts | 14 +++++++++
src/store/resources-data/resources-data-reducer.ts | 33 ++++++++++++++++++++++
src/store/resources-data/resources-data.ts | 8 ++++++
src/store/resources/resources.ts | 2 +-
src/store/store.ts | 2 ++
src/views-components/data-explorer/renderers.tsx | 3 +-
.../details-panel/collection-details.tsx | 4 +--
.../details-panel/details-data.tsx | 3 +-
.../details-panel/details-panel.tsx | 11 +++++---
src/views/collection-panel/collection-panel.tsx | 16 ++++++-----
13 files changed, 91 insertions(+), 39 deletions(-)
create mode 100644 src/store/resources-data/resources-data-actions.ts
create mode 100644 src/store/resources-data/resources-data-reducer.ts
create mode 100644 src/store/resources-data/resources-data.ts
via 3f51c120dab4eafb820f9c2a5e4f836cc9b04982 (commit)
from d531ed8429325807f54943f33fdb750573b0694e (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 3f51c120dab4eafb820f9c2a5e4f836cc9b04982
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date: Mon Oct 22 21:53:46 2018 +0200
Remove resource extending, add separate resource data store
Feature #14349
Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>
diff --git a/src/models/collection.ts b/src/models/collection.ts
index 735ffa8..f8e38f9 100644
--- a/src/models/collection.ts
+++ b/src/models/collection.ts
@@ -14,8 +14,6 @@ export interface CollectionResource extends TrashableResource {
replicationDesired: number;
replicationConfirmed: number;
replicationConfirmedAt: string;
- fileSize: number;
- fileCount: number;
}
export const getCollectionUrl = (uuid: string) => {
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 99ab682..9a1d645 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
@@ -14,6 +14,7 @@ import { filterCollectionFilesBySelection } from './collection-panel-files-state
import { startSubmit, stopSubmit, reset } from 'redux-form';
import { getDialog } from "~/store/dialog/dialog-reducer";
import { getFileFullPath } from "~/services/collection-service/collection-service-files-response";
+import { resourcesDataActions } from "~/store/resources-data/resources-data-actions";
export const collectionPanelFilesAction = unionize({
SET_COLLECTION_FILES: ofType<CollectionFilesTree>(),
@@ -29,6 +30,7 @@ export const loadCollectionFiles = (uuid: string) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
const files = await services.collectionService.files(uuid);
dispatch(collectionPanelFilesAction.SET_COLLECTION_FILES(files));
+ dispatch(resourcesDataActions.SET_FILES({ uuid, files }));
};
export const removeCollectionFiles = (filePaths: string[]) =>
diff --git a/src/store/project-panel/project-panel-middleware-service.ts b/src/store/project-panel/project-panel-middleware-service.ts
index 27efcd0..0da669a 100644
--- a/src/store/project-panel/project-panel-middleware-service.ts
+++ b/src/store/project-panel/project-panel-middleware-service.ts
@@ -20,18 +20,17 @@ import { updateFavorites } from "../favorites/favorites-actions";
import { PROJECT_PANEL_CURRENT_UUID, projectPanelActions } from './project-panel-action';
import { Dispatch, MiddlewareAPI } from "redux";
import { ProjectResource } from "~/models/project";
-import { resourcesActions, updateResources } from "~/store/resources/resources-actions";
+import { updateResources } from "~/store/resources/resources-actions";
import { getProperty } from "~/store/properties/properties";
import { snackbarActions, SnackbarKind } from '../snackbar/snackbar-actions';
import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions.ts';
import { DataExplorer, getDataExplorer } from '../data-explorer/data-explorer-reducer';
import { ListResults } from '~/services/common-service/common-resource-service';
import { loadContainers } from '../processes/processes-actions';
-import { Resource, ResourceKind } from '~/models/resource';
+import { ResourceKind } from '~/models/resource';
import { getResource } from "~/store/resources/resources";
import { CollectionResource } from "~/models/collection";
-import { getNode, getNodeDescendantsIds, TreeNode } from "~/models/tree";
-import { CollectionDirectory, CollectionFile, CollectionFileType } from "~/models/collection-file";
+import { resourcesDataActions } from "~/store/resources-data/resources-data-actions";
export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService {
constructor(private services: ServiceRepository, id: string) {
@@ -54,7 +53,7 @@ export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService
const resourceUuids = response.items.map(item => item.uuid);
api.dispatch<any>(updateFavorites(resourceUuids));
api.dispatch(updateResources(response.items));
- api.dispatch<any>(updateFilesInfo(resourceUuids));
+ api.dispatch<any>(updateResourceData(resourceUuids));
await api.dispatch<any>(loadMissingProcessesInformation(response.items));
api.dispatch(setItems(response));
} catch (e) {
@@ -87,28 +86,17 @@ export const loadMissingProcessesInformation = (resources: GroupContentsResource
}
};
-export const updateFilesInfo = (resourceUuids: string[]) =>
+export const updateResourceData = (resourceUuids: string[]) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
- const resources = await Promise.all(resourceUuids.map(async uuid => {
+ resourceUuids.map(async uuid => {
const resource = getResource<CollectionResource>(uuid)(getState().resources);
if (resource && resource.kind === ResourceKind.COLLECTION) {
const files = await services.collectionService.files(uuid);
- const flattenFiles: (TreeNode<CollectionFile | CollectionDirectory> | undefined)[] = getNodeDescendantsIds('')(files).map(id => getNode(id)(files));
- let fileSize = 0;
- let fileCount = 0;
- if (flattenFiles) {
- fileCount = flattenFiles.length;
- fileSize = flattenFiles.reduce((acc, f) => {
- return acc + (f && f.value.type === CollectionFileType.FILE ? f.value.size : 0);
- }, 0);
+ if (files) {
+ dispatch(resourcesDataActions.SET_FILES({ uuid, files }));
}
-
- resource.fileCount = fileCount;
- resource.fileSize = fileSize;
}
- return resource;
- }));
- dispatch(resourcesActions.SET_RESOURCES(resources.filter(res => res) as Resource[]));
+ });
};
export const setItems = (listResults: ListResults<GroupContentsResource>) =>
diff --git a/src/store/resources-data/resources-data-actions.ts b/src/store/resources-data/resources-data-actions.ts
new file mode 100644
index 0000000..660699c
--- /dev/null
+++ b/src/store/resources-data/resources-data-actions.ts
@@ -0,0 +1,14 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { unionize } from "src/common/unionize";
+import { ofType, UnionOf } from "unionize";
+import { CollectionDirectory, CollectionFile } from "~/models/collection-file";
+import { Tree } from "~/models/tree";
+
+export const resourcesDataActions = unionize({
+ SET_FILES: ofType<{uuid: string, files: Tree<CollectionFile | CollectionDirectory>}>()
+});
+
+export type ResourcesDataActions = UnionOf<typeof resourcesDataActions>;
diff --git a/src/store/resources-data/resources-data-reducer.ts b/src/store/resources-data/resources-data-reducer.ts
new file mode 100644
index 0000000..07a3a66
--- /dev/null
+++ b/src/store/resources-data/resources-data-reducer.ts
@@ -0,0 +1,33 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ResourcesDataActions, resourcesDataActions } from "~/store/resources-data/resources-data-actions";
+import { getNodeDescendantsIds, TREE_ROOT_ID } from "~/models/tree";
+import { CollectionFileType } from "~/models/collection-file";
+
+export interface ResourceData {
+ fileCount: number;
+ fileSize: number;
+}
+
+export type ResourcesDataState = {
+ [key: string]: ResourceData
+};
+
+export const resourcesDataReducer = (state: ResourcesDataState = {}, action: ResourcesDataActions) =>
+ resourcesDataActions.match(action, {
+ SET_FILES: ({uuid, files}) => {
+ const flattenFiles = getNodeDescendantsIds(TREE_ROOT_ID)(files).map(id => files[id]);
+ const [fileSize, fileCount] = flattenFiles.reduce(([size, cnt], f) =>
+ f && f.value.type === CollectionFileType.FILE
+ ? [size + f.value.size, cnt + 1]
+ : [size, cnt]
+ , [0, 0]);
+ return {
+ ...state,
+ [uuid]: { fileCount, fileSize }
+ };
+ },
+ default: () => state,
+ });
diff --git a/src/store/resources-data/resources-data.ts b/src/store/resources-data/resources-data.ts
new file mode 100644
index 0000000..48c1e2b
--- /dev/null
+++ b/src/store/resources-data/resources-data.ts
@@ -0,0 +1,8 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ResourceData, ResourcesDataState } from "~/store/resources-data/resources-data-reducer";
+
+export const getResourceData = (id: string) =>
+ (state: ResourcesDataState): ResourceData | undefined => state[id];
diff --git a/src/store/resources/resources.ts b/src/store/resources/resources.ts
index 10c82ff..e7153de 100644
--- a/src/store/resources/resources.ts
+++ b/src/store/resources/resources.ts
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0
import { Resource } from "~/models/resource";
-import { ResourceKind } from '../../models/resource';
+import { ResourceKind } from '~/models/resource';
export type ResourcesState = { [key: string]: Resource };
diff --git a/src/store/store.ts b/src/store/store.ts
index 7a0d58f..fa2a5be 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -42,6 +42,7 @@ import { appInfoReducer } from '~/store/app-info/app-info-reducer';
import { searchBarReducer } from './search-bar/search-bar-reducer';
import { SEARCH_RESULTS_PANEL_ID } from '~/store/search-results-panel/search-results-panel-actions';
import { SearchResultsMiddlewareService } from './search-results-panel/search-results-middleware-service';
+import { resourcesDataReducer } from "~/store/resources-data/resources-data-reducer";
const composeEnhancers =
(process.env.NODE_ENV === 'development' &&
@@ -101,6 +102,7 @@ const createRootReducer = (services: ServiceRepository) => combineReducers({
processLogsPanel: processLogsPanelReducer,
properties: propertiesReducer,
resources: resourcesReducer,
+ resourcesData: resourcesDataReducer,
router: routerReducer,
snackbar: snackbarReducer,
treePicker: treePickerReducer,
diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx
index e76600e..6e25508 100644
--- a/src/views-components/data-explorer/renderers.tsx
+++ b/src/views-components/data-explorer/renderers.tsx
@@ -20,6 +20,7 @@ import { WorkflowResource } from '~/models/workflow';
import { ResourceStatus } from '~/views/workflow-panel/workflow-panel-view';
import { getUuidPrefix } from '~/store/workflow-panel/workflow-panel-actions';
import { CollectionResource } from "~/models/collection";
+import { getResourceData } from "~/store/resources-data/resources-data";
export const renderName = (item: { name: string; uuid: string, kind: string }) =>
<Grid container alignItems="center" wrap="nowrap" spacing={16}>
@@ -150,7 +151,7 @@ export const renderFileSize = (fileSize?: number) =>
export const ResourceFileSize = connect(
(state: RootState, props: { uuid: string }) => {
- const resource = getResource<CollectionResource>(props.uuid)(state.resources);
+ const resource = getResourceData(props.uuid)(state.resourcesData);
return { fileSize: resource ? resource.fileSize : 0 };
})((props: { fileSize?: number }) => renderFileSize(props.fileSize));
diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index aec9911..98fa388 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -28,8 +28,8 @@ export class CollectionDetails extends DetailsData<CollectionResource> {
<DetailsAttribute label='Collection UUID' link={this.item.uuid} value={this.item.uuid} />
<DetailsAttribute label='Content address' link={this.item.portableDataHash} value={this.item.portableDataHash} />
{/* Missing attrs */}
- <DetailsAttribute label='Number of files' value={this.item.fileCount} />
- <DetailsAttribute label='Content size' value={formatFileSize(this.item.fileSize)} />
+ <DetailsAttribute label='Number of files' value={this.data && this.data.fileCount} />
+ <DetailsAttribute label='Content size' value={formatFileSize(this.data && this.data.fileSize)} />
</div>;
}
}
diff --git a/src/views-components/details-panel/details-data.tsx b/src/views-components/details-panel/details-data.tsx
index b5ebc36..45afb02 100644
--- a/src/views-components/details-panel/details-data.tsx
+++ b/src/views-components/details-panel/details-data.tsx
@@ -4,9 +4,10 @@
import * as React from 'react';
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) {}
+ constructor(protected item: T, protected data?: ResourceData) {}
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 f007555..5e5ccef 100644
--- a/src/views-components/details-panel/details-panel.tsx
+++ b/src/views-components/details-panel/details-panel.tsx
@@ -22,6 +22,8 @@ import { EmptyDetails } from "./empty-details";
import { DetailsData } from "./details-data";
import { DetailsResource } from "~/models/details";
import { getResource } from '~/store/resources/resources';
+import { ResourceData } from "~/store/resources-data/resources-data-reducer";
+import { getResourceData } from "~/store/resources-data/resources-data";
type CssRules = 'root' | 'container' | 'opened' | 'headerContainer' | 'headerIcon' | 'tabContainer';
@@ -57,13 +59,13 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
},
});
-const getItem = (resource: DetailsResource): DetailsData => {
+const getItem = (resource: DetailsResource, resourceData?: ResourceData): DetailsData => {
const res = resource || { kind: undefined, name: 'Projects' };
switch (res.kind) {
case ResourceKind.PROJECT:
return new ProjectDetails(res);
case ResourceKind.COLLECTION:
- return new CollectionDetails(res);
+ return new CollectionDetails(res, resourceData);
case ResourceKind.PROCESS:
return new ProcessDetails(res);
default:
@@ -71,11 +73,12 @@ const getItem = (resource: DetailsResource): DetailsData => {
}
};
-const mapStateToProps = ({ detailsPanel, resources }: RootState) => {
+const mapStateToProps = ({ detailsPanel, resources, resourcesData }: RootState) => {
const resource = getResource(detailsPanel.resourceUuid)(resources) as DetailsResource;
+ const resourceData = getResourceData(detailsPanel.resourceUuid)(resourcesData);
return {
isOpened: detailsPanel.isOpened,
- item: getItem(resource)
+ item: getItem(resource, resourceData)
};
};
diff --git a/src/views/collection-panel/collection-panel.tsx b/src/views/collection-panel/collection-panel.tsx
index 7defc07..42f7787 100644
--- a/src/views/collection-panel/collection-panel.tsx
+++ b/src/views/collection-panel/collection-panel.tsx
@@ -23,6 +23,8 @@ import { getResource } from '~/store/resources/resources';
import { openContextMenu } from '~/store/context-menu/context-menu-actions';
import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
import { formatFileSize } from "~/common/formatters";
+import { getResourceData } from "~/store/resources-data/resources-data";
+import { ResourceData } from "~/store/resources-data/resources-data-reducer";
type CssRules = 'card' | 'iconHeader' | 'tag' | 'copyIcon' | 'label' | 'value';
@@ -55,6 +57,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
interface CollectionPanelDataProps {
item: CollectionResource;
+ data: ResourceData;
}
type CollectionPanelProps = CollectionPanelDataProps & DispatchProp
@@ -63,14 +66,13 @@ type CollectionPanelProps = CollectionPanelDataProps & DispatchProp
export const CollectionPanel = withStyles(styles)(
connect((state: RootState, props: RouteComponentProps<{ id: string }>) => {
- const collection = getResource(props.match.params.id)(state.resources);
- return {
- item: collection
- };
+ const item = getResource(props.match.params.id)(state.resources);
+ const data = getResourceData(props.match.params.id)(state.resourcesData);
+ return { item, data };
})(
class extends React.Component<CollectionPanelProps> {
render() {
- const { classes, item } = this.props;
+ const { classes, item, data } = this.props;
return item
? <>
<Card className={classes.card}>
@@ -100,9 +102,9 @@ export const CollectionPanel = withStyles(styles)(
</Tooltip>
</DetailsAttribute>
<DetailsAttribute classLabel={classes.label} classValue={classes.value}
- label='Number of files' value={item && item.fileCount} />
+ label='Number of files' value={data && data.fileCount} />
<DetailsAttribute classLabel={classes.label} classValue={classes.value}
- label='Content size' value={item && formatFileSize(item.fileSize)} />
+ label='Content size' value={data && formatFileSize(data.fileSize)} />
<DetailsAttribute classLabel={classes.label} classValue={classes.value}
label='Owner' value={item && item.ownerUuid} />
</Grid>
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list