[ARVADOS-WORKBENCH2] created: 1.1.4-99-g9e4b788

Git user git at public.curoverse.com
Mon Jun 18 18:28:29 EDT 2018


        at  9e4b7889a99ff2f76d8029aef3a85c4620178ba3 (commit)


commit 9e4b7889a99ff2f76d8029aef3a85c4620178ba3
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Tue Jun 19 00:28:20 2018 +0200

    Added collection service, reorganized components structure
    
    Feature #13632
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --git a/src/components/data-table/column-selector/column-selector.test.tsx b/src/components/column-selector/column-selector.test.tsx
similarity index 97%
rename from src/components/data-table/column-selector/column-selector.test.tsx
rename to src/components/column-selector/column-selector.test.tsx
index 26c16a1..b6c544f 100644
--- a/src/components/data-table/column-selector/column-selector.test.tsx
+++ b/src/components/column-selector/column-selector.test.tsx
@@ -6,7 +6,7 @@ import * as React from "react";
 import { mount, configure } from "enzyme";
 import * as Adapter from "enzyme-adapter-react-16";
 import ColumnSelector, { ColumnSelectorProps, ColumnSelectorTrigger } from "./column-selector";
-import { DataColumn } from "../data-column";
+import { DataColumn } from "../data-table/data-column";
 import { ListItem, Checkbox } from "@material-ui/core";
 
 configure({ adapter: new Adapter() });
@@ -76,4 +76,4 @@ describe("<ColumnSelector />", () => {
         columnsConfigurator.find(ListItem).simulate("click");
         expect(onColumnToggle).toHaveBeenCalledWith(columns[0]);
     });
-});
\ No newline at end of file
+});
diff --git a/src/components/data-table/column-selector/column-selector.tsx b/src/components/column-selector/column-selector.tsx
similarity index 94%
rename from src/components/data-table/column-selector/column-selector.tsx
rename to src/components/column-selector/column-selector.tsx
index 87d3e8d..e2286b0 100644
--- a/src/components/data-table/column-selector/column-selector.tsx
+++ b/src/components/column-selector/column-selector.tsx
@@ -5,8 +5,8 @@
 import * as React from 'react';
 import { WithStyles, StyleRulesCallback, Theme, withStyles, IconButton, Paper, List, Checkbox, ListItemText, ListItem } from '@material-ui/core';
 import MenuIcon from "@material-ui/icons/Menu";
-import { DataColumn, isColumnConfigurable } from '../data-column';
-import Popover from "../../popover/popover";
+import { DataColumn, isColumnConfigurable } from '../data-table/data-column';
+import Popover from "../popover/popover";
 import { IconButtonProps } from '@material-ui/core/IconButton';
 
 export interface ColumnSelectorProps {
diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx
index e7ce03a..bc5df0d 100644
--- a/src/components/data-table/data-table.tsx
+++ b/src/components/data-table/data-table.tsx
@@ -6,9 +6,11 @@ import * as React from 'react';
 import { Table, TableBody, TableRow, TableCell, TableHead, StyleRulesCallback, Theme, WithStyles, withStyles, Typography } from '@material-ui/core';
 import { DataColumn } from './data-column';
 
+export type DataColumns<T> = Array<DataColumn<T>>;
+
 export interface DataTableProps<T> {
     items: T[];
-    columns: Array<DataColumn<T>>;
+    columns: DataColumns<T>;
     onItemClick?: (item: T) => void;
 }
 
@@ -46,7 +48,7 @@ class DataTable<T> extends React.Component<DataTableProps<T> & WithStyles<CssRul
                                 </TableRow>
                             )}
                     </TableBody>
-                </Table> : <Typography 
+                </Table> : <Typography
                     className={classes.noItemsInfo}
                     variant="body2"
                     gutterBottom>
diff --git a/src/components/data-table/index.ts b/src/components/data-table/index.ts
deleted file mode 100644
index f35754b..0000000
--- a/src/components/data-table/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-export * from "./data-column";
-export * from "./column-selector/column-selector";
-export { default as ColumnSelector } from "./column-selector/column-selector";
-export * from "./data-table";
-export { default as DataTable } from "./data-table";
\ No newline at end of file
diff --git a/src/components/main-app-bar/dropdown-menu/dropdown-menu.test.tsx b/src/components/dropdown-menu/dropdown-menu.test.tsx
similarity index 100%
rename from src/components/main-app-bar/dropdown-menu/dropdown-menu.test.tsx
rename to src/components/dropdown-menu/dropdown-menu.test.tsx
diff --git a/src/components/main-app-bar/dropdown-menu/dropdown-menu.tsx b/src/components/dropdown-menu/dropdown-menu.tsx
similarity index 100%
rename from src/components/main-app-bar/dropdown-menu/dropdown-menu.tsx
rename to src/components/dropdown-menu/dropdown-menu.tsx
diff --git a/src/components/main-app-bar/search-bar/search-bar.test.tsx b/src/components/search-bar/search-bar.test.tsx
similarity index 100%
rename from src/components/main-app-bar/search-bar/search-bar.test.tsx
rename to src/components/search-bar/search-bar.test.tsx
diff --git a/src/components/main-app-bar/search-bar/search-bar.tsx b/src/components/search-bar/search-bar.tsx
similarity index 100%
rename from src/components/main-app-bar/search-bar/search-bar.tsx
rename to src/components/search-bar/search-bar.tsx
diff --git a/src/index.tsx b/src/index.tsx
index ca92c38..9e1f103 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -6,13 +6,13 @@ import * as React from 'react';
 import * as ReactDOM from 'react-dom';
 import { Provider } from "react-redux";
 import Workbench from './views/workbench/workbench';
-import ProjectList from './components/project-list/project-list';
+import ProjectList from './views-components/project-list/project-list';
 import './index.css';
 import { Route } from "react-router";
 import createBrowserHistory from "history/createBrowserHistory";
 import configureStore from "./store/store";
 import { ConnectedRouter } from "react-router-redux";
-import ApiToken from "./components/api-token/api-token";
+import ApiToken from "./views-components/api-token/api-token";
 import authActions from "./store/auth/auth-action";
 import { authService, projectService } from "./services/services";
 
diff --git a/src/components/data-explorer/index.ts b/src/models/collection.ts
similarity index 52%
rename from src/components/data-explorer/index.ts
rename to src/models/collection.ts
index bde402d..316b1fa 100644
--- a/src/components/data-explorer/index.ts
+++ b/src/models/collection.ts
@@ -2,5 +2,7 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-export { default as DataExplorer } from "./data-explorer";
-export * from "./data-item";
\ No newline at end of file
+import { Resource } from "./resource";
+
+export interface Collection extends Resource {
+}
diff --git a/src/models/project.ts b/src/models/project.ts
index 830621b..7d29de8 100644
--- a/src/models/project.ts
+++ b/src/models/project.ts
@@ -2,12 +2,7 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-export interface Project {
-    name: string;
-    createdAt: string;
-    modifiedAt: string;
-    uuid: string;
-    ownerUuid: string;
-    href: string;
-    kind: string;
+import { Resource } from "./resource";
+
+export interface Project extends Resource {
 }
diff --git a/src/models/project.ts b/src/models/resource.ts
similarity index 53%
copy from src/models/project.ts
copy to src/models/resource.ts
index 830621b..39b4e91 100644
--- a/src/models/project.ts
+++ b/src/models/resource.ts
@@ -1,8 +1,4 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-export interface Project {
+export interface Resource {
     name: string;
     createdAt: string;
     modifiedAt: string;
diff --git a/src/services/collection-service/collection-service.ts b/src/services/collection-service/collection-service.ts
new file mode 100644
index 0000000..77ea7ea
--- /dev/null
+++ b/src/services/collection-service/collection-service.ts
@@ -0,0 +1,59 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { serverApi } from "../../common/api/server-api";
+import { Dispatch } from "redux";
+import actions from "../../store/collection/collection-action";
+import UrlBuilder from "../../common/api/url-builder";
+import FilterBuilder, { FilterField } from "../../common/api/filter-builder";
+import { ArvadosResource } from "../response";
+import { Collection } from "../../models/collection";
+
+interface CollectionResource extends ArvadosResource {
+    name: string;
+    description: string;
+    properties: any;
+    portable_data_hash: string;
+    manifest_text: string;
+    replication_desired: number;
+    replication_confirmed: number;
+    replication_confirmed_at: string;
+    trash_at: string;
+    delete_at: string;
+    is_trashed: boolean;
+}
+
+interface CollectionsResponse {
+    offset: number;
+    limit: number;
+    items: CollectionResource[];
+}
+
+export default class CollectionService {
+    public getCollectionList = (parentUuid?: string) => (dispatch: Dispatch): Promise<Collection[]> => {
+        dispatch(actions.COLLECTIONS_REQUEST());
+        if (parentUuid) {
+            const fb = new FilterBuilder();
+            fb.addLike(FilterField.OWNER_UUID, parentUuid);
+            return serverApi.get<CollectionsResponse>('/collections', { params: {
+                filters: fb.get()
+            }}).then(resp => {
+                const collections = resp.data.items.map(g => ({
+                    name: g.name,
+                    createdAt: g.created_at,
+                    modifiedAt: g.modified_at,
+                    href: g.href,
+                    uuid: g.uuid,
+                    ownerUuid: g.owner_uuid,
+                    kind: g.kind
+                } as Collection));
+                dispatch(actions.COLLECTIONS_SUCCESS({collections}));
+                return collections;
+            });
+        } else {
+            dispatch(actions.COLLECTIONS_SUCCESS({collections: []}));
+            return Promise.resolve([]);
+        }
+    }
+}
diff --git a/src/services/project-service/project-service.ts b/src/services/project-service/project-service.ts
index 119cfec..8070a38 100644
--- a/src/services/project-service/project-service.ts
+++ b/src/services/project-service/project-service.ts
@@ -8,28 +8,22 @@ import actions from "../../store/project/project-action";
 import { Project } from "../../models/project";
 import UrlBuilder from "../../common/api/url-builder";
 import FilterBuilder, { FilterField } from "../../common/api/filter-builder";
+import { ArvadosResource } from "../response";
+
+interface GroupResource extends ArvadosResource {
+    name: string;
+    group_class: string;
+    description: string;
+    writable_by: string[];
+    delete_at: string;
+    trash_at: string;
+    is_trashed: boolean;
+}
 
 interface GroupsResponse {
     offset: number;
     limit: number;
-    items: Array<{
-        href: string;
-        kind: string;
-        etag: string;
-        uuid: string;
-        owner_uuid: string;
-        created_at: string;
-        modified_by_client_uuid: string;
-        modified_by_user_uuid: string;
-        modified_at: string;
-        name: string;
-        group_class: string;
-        description: string;
-        writable_by: string[];
-        delete_at: string;
-        trash_at: string;
-        is_trashed: boolean;
-    }>;
+    items: GroupResource[];
 }
 
 export default class ProjectService {
@@ -40,8 +34,8 @@ export default class ProjectService {
             fb.addLike(FilterField.OWNER_UUID, parentUuid);
             return serverApi.get<GroupsResponse>('/groups', { params: {
                 filters: fb.get()
-            }}).then(groups => {
-                const projects = groups.data.items.map(g => ({
+            }}).then(resp => {
+                const projects = resp.data.items.map(g => ({
                     name: g.name,
                     createdAt: g.created_at,
                     modifiedAt: g.modified_at,
diff --git a/src/services/response.ts b/src/services/response.ts
new file mode 100644
index 0000000..a71282b
--- /dev/null
+++ b/src/services/response.ts
@@ -0,0 +1,11 @@
+export interface ArvadosResource {
+    uuid: string;
+    owner_uuid: string;
+    created_at: string;
+    modified_by_client_uuid: string;
+    modified_by_user_uuid: string;
+    modified_at: string;
+    href: string;
+    kind: string;
+    etag: string;
+}
diff --git a/src/store/collection/collection-action.ts b/src/store/collection/collection-action.ts
new file mode 100644
index 0000000..5f1d60f
--- /dev/null
+++ b/src/store/collection/collection-action.ts
@@ -0,0 +1,19 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Collection } from "../../models/collection";
+import { default as unionize, ofType, UnionOf } from "unionize";
+
+const actions = unionize({
+    CREATE_COLLECTION: ofType<Collection>(),
+    REMOVE_COLLECTION: ofType<string>(),
+    COLLECTIONS_REQUEST: ofType<any>(),
+    COLLECTIONS_SUCCESS: ofType<{ collections: Collection[] }>(),
+}, {
+    tag: 'type',
+    value: 'payload'
+});
+
+export type CollectionAction = UnionOf<typeof actions>;
+export default actions;
diff --git a/src/store/collection/collection-reducer.test.ts b/src/store/collection/collection-reducer.test.ts
new file mode 100644
index 0000000..c04217c
--- /dev/null
+++ b/src/store/collection/collection-reducer.test.ts
@@ -0,0 +1,56 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import collectionsReducer from "./collection-reducer";
+import actions from "./collection-action";
+
+describe('collection-reducer', () => {
+    it('should add new collection to the list', () => {
+        const initialState = undefined;
+        const collection = {
+            name: 'test',
+            href: 'href',
+            createdAt: '2018-01-01',
+            modifiedAt: '2018-01-01',
+            ownerUuid: 'owner-test123',
+            uuid: 'test123',
+            kind: ""
+        };
+
+        const state = collectionsReducer(initialState, actions.CREATE_COLLECTION(collection));
+        expect(state).toEqual([collection]);
+    });
+
+    it('should load collections', () => {
+        const initialState = undefined;
+        const collection = {
+            name: 'test',
+            href: 'href',
+            createdAt: '2018-01-01',
+            modifiedAt: '2018-01-01',
+            ownerUuid: 'owner-test123',
+            uuid: 'test123',
+            kind: ""
+        };
+
+        const collections = [collection, collection];
+        const state = collectionsReducer(initialState, actions.COLLECTIONS_SUCCESS({ collections }));
+        expect(state).toEqual([{
+                active: false,
+                open: false,
+                id: "test123",
+                items: [],
+                data: collection,
+                status: 0
+            }, {
+                active: false,
+                open: false,
+                id: "test123",
+                items: [],
+                data: collection,
+                status: 0
+            }
+        ]);
+    });
+});
diff --git a/src/store/collection/collection-reducer.ts b/src/store/collection/collection-reducer.ts
new file mode 100644
index 0000000..939ca62
--- /dev/null
+++ b/src/store/collection/collection-reducer.ts
@@ -0,0 +1,25 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import actions, { CollectionAction } from "./collection-action";
+import { Collection } from "../../models/collection";
+
+export type CollectionState = Collection[];
+
+
+const collectionsReducer = (state: CollectionState = [], action: CollectionAction) => {
+    return actions.match(action, {
+        CREATE_COLLECTION: collection => [...state, collection],
+        REMOVE_COLLECTION: () => state,
+        COLLECTIONS_REQUEST: () => {
+            return state;
+        },
+        COLLECTIONS_SUCCESS: ({ collections }) => {
+            return collections;
+        },
+        default: () => state
+    });
+};
+
+export default collectionsReducer;
diff --git a/src/store/store.ts b/src/store/store.ts
index 499d89e..6b9c31f 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -8,6 +8,7 @@ import thunkMiddleware from 'redux-thunk';
 import { History } from "history";
 import projectsReducer, { ProjectState } from "./project/project-reducer";
 import authReducer, { AuthState } from "./auth/auth-reducer";
+import collectionsReducer from "./collection/collection-reducer";
 
 const composeEnhancers =
     (process.env.NODE_ENV === 'development' &&
@@ -23,6 +24,7 @@ export interface RootState {
 const rootReducer = combineReducers({
     auth: authReducer,
     projects: projectsReducer,
+    collections: collectionsReducer,
     router: routerReducer
 });
 
diff --git a/src/components/api-token/api-token.tsx b/src/views-components/api-token/api-token.tsx
similarity index 100%
rename from src/components/api-token/api-token.tsx
rename to src/views-components/api-token/api-token.tsx
diff --git a/src/components/data-explorer/data-explorer.tsx b/src/views-components/data-explorer/data-explorer.tsx
similarity index 92%
rename from src/components/data-explorer/data-explorer.tsx
rename to src/views-components/data-explorer/data-explorer.tsx
index 9aeb28a..1215915 100644
--- a/src/components/data-explorer/data-explorer.tsx
+++ b/src/views-components/data-explorer/data-explorer.tsx
@@ -3,20 +3,25 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { DataTable, DataTableProps, DataColumn, ColumnSelector } from "../../components/data-table";
 import { Typography, Grid, ListItem, Divider, List, ListItemIcon, ListItemText, Paper, Toolbar } from '@material-ui/core';
 import IconButton, { IconButtonProps } from '@material-ui/core/IconButton';
 import MoreVertIcon from "@material-ui/icons/MoreVert";
-import Popover from '../popover/popover';
+import Popover from '../../components/popover/popover';
 import { formatFileSize, formatDate } from '../../common/formatters';
 import { DataItem } from './data-item';
+import { DataColumns, DataTableProps } from "../../components/data-table/data-table";
+import { DataColumn } from "../../components/data-table/data-column";
+import ColumnSelector from "../../components/column-selector/column-selector";
+import DataTable from "../../components/data-table/data-table";
 
 interface DataExplorerProps {
     items: DataItem[];
     onItemClick: (item: DataItem) => void;
 }
 
-type DataExplorerState = Pick<DataTableProps<DataItem>, "columns">;
+interface DataExplorerState {
+    columns: DataColumns<DataItem>;
+}
 
 class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState> {
     state: DataExplorerState = {
diff --git a/src/components/data-explorer/data-item.ts b/src/views-components/data-explorer/data-item.ts
similarity index 92%
rename from src/components/data-explorer/data-item.ts
rename to src/views-components/data-explorer/data-item.ts
index 3a80992..65e8f63 100644
--- a/src/components/data-explorer/data-item.ts
+++ b/src/views-components/data-explorer/data-item.ts
@@ -3,10 +3,11 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 export interface DataItem {
+    uuid: string;
     name: string;
     type: string;
     owner: string;
     lastModified: string;
     fileSize?: number;
     status?: string;
-}
\ No newline at end of file
+}
diff --git a/src/components/main-app-bar/main-app-bar.test.tsx b/src/views-components/main-app-bar/main-app-bar.test.tsx
similarity index 95%
rename from src/components/main-app-bar/main-app-bar.test.tsx
rename to src/views-components/main-app-bar/main-app-bar.test.tsx
index f08c939..25494b6 100644
--- a/src/components/main-app-bar/main-app-bar.test.tsx
+++ b/src/views-components/main-app-bar/main-app-bar.test.tsx
@@ -6,9 +6,9 @@ import * as React from "react";
 import { mount, configure, ReactWrapper } from "enzyme";
 import * as Adapter from "enzyme-adapter-react-16";
 import MainAppBar from "./main-app-bar";
-import SearchBar from "./search-bar/search-bar";
-import Breadcrumbs from "../breadcrumbs/breadcrumbs";
-import DropdownMenu from "./dropdown-menu/dropdown-menu";
+import SearchBar from "../../components/search-bar/search-bar";
+import Breadcrumbs from "../../components/breadcrumbs/breadcrumbs";
+import DropdownMenu from "../../components/dropdown-menu/dropdown-menu";
 import { Button, MenuItem, IconButton } from "@material-ui/core";
 import { User } from "../../models/user";
 
@@ -98,4 +98,4 @@ describe("<MainAppBar />", () => {
         mainAppBar.find(DropdownMenu).at(0).find(MenuItem).at(1).simulate("click");
         expect(onMenuItemClick).toBeCalledWith(menuItems.accountMenu[0]);
     });
-});
\ No newline at end of file
+});
diff --git a/src/components/main-app-bar/main-app-bar.tsx b/src/views-components/main-app-bar/main-app-bar.tsx
similarity index 94%
rename from src/components/main-app-bar/main-app-bar.tsx
rename to src/views-components/main-app-bar/main-app-bar.tsx
index 27cd8bd..c0525a5 100644
--- a/src/components/main-app-bar/main-app-bar.tsx
+++ b/src/views-components/main-app-bar/main-app-bar.tsx
@@ -7,9 +7,9 @@ import { AppBar, Toolbar, Typography, Grid, IconButton, Badge, StyleRulesCallbac
 import NotificationsIcon from "@material-ui/icons/Notifications";
 import PersonIcon from "@material-ui/icons/Person";
 import HelpIcon from "@material-ui/icons/Help";
-import SearchBar from "./search-bar/search-bar";
-import Breadcrumbs, { Breadcrumb } from "../breadcrumbs/breadcrumbs";
-import DropdownMenu from "./dropdown-menu/dropdown-menu";
+import SearchBar from "../../components/search-bar/search-bar";
+import Breadcrumbs, { Breadcrumb } from "../../components/breadcrumbs/breadcrumbs";
+import DropdownMenu from "../../components/dropdown-menu/dropdown-menu";
 import { User, getUserFullname } from "../../models/user";
 
 export interface MainAppBarMenuItem {
@@ -126,4 +126,4 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
     }
 });
 
-export default withStyles(styles)(MainAppBar);
\ No newline at end of file
+export default withStyles(styles)(MainAppBar);
diff --git a/src/components/project-list/project-list.tsx b/src/views-components/project-list/project-list.tsx
similarity index 100%
rename from src/components/project-list/project-list.tsx
rename to src/views-components/project-list/project-list.tsx
diff --git a/src/components/project-tree/project-tree.test.tsx b/src/views-components/project-tree/project-tree.test.tsx
similarity index 98%
rename from src/components/project-tree/project-tree.test.tsx
rename to src/views-components/project-tree/project-tree.test.tsx
index 932a29c..d531213 100644
--- a/src/components/project-tree/project-tree.test.tsx
+++ b/src/views-components/project-tree/project-tree.test.tsx
@@ -11,7 +11,7 @@ import { Collapse } from '@material-ui/core';
 import CircularProgress from '@material-ui/core/CircularProgress';
 
 import ProjectTree from './project-tree';
-import { TreeItem } from '../tree/tree';
+import { TreeItem } from '../../components/tree/tree';
 import { Project } from '../../models/project';
 Enzyme.configure({ adapter: new Adapter() });
 
diff --git a/src/components/project-tree/project-tree.tsx b/src/views-components/project-tree/project-tree.tsx
similarity index 96%
rename from src/components/project-tree/project-tree.tsx
rename to src/views-components/project-tree/project-tree.tsx
index 275805f..fd32ff0 100644
--- a/src/components/project-tree/project-tree.tsx
+++ b/src/views-components/project-tree/project-tree.tsx
@@ -9,7 +9,7 @@ import ListItemText from "@material-ui/core/ListItemText/ListItemText";
 import ListItemIcon from '@material-ui/core/ListItemIcon';
 import Typography from '@material-ui/core/Typography';
 
-import Tree, { TreeItem, TreeItemStatus } from '../tree/tree';
+import Tree, { TreeItem, TreeItemStatus } from '../../components/tree/tree';
 import { Project } from '../../models/project';
 
 type CssRules = 'active' | 'listItemText' | 'row' | 'treeContainer';
diff --git a/src/views-selectors/data-explorer/data-explorer.ts b/src/views-selectors/data-explorer/data-explorer.ts
new file mode 100644
index 0000000..5f17037
--- /dev/null
+++ b/src/views-selectors/data-explorer/data-explorer.ts
@@ -0,0 +1,11 @@
+import { TreeItem } from "../../components/tree/tree";
+import { Project } from "../../models/project";
+import { DataItem } from "../../views-components/data-explorer/data-item";
+
+export const mapProjectTreeItem = (item: TreeItem<Project>): DataItem => ({
+    name: item.data.name,
+    type: item.data.kind,
+    owner: item.data.ownerUuid,
+    lastModified: item.data.modifiedAt,
+    uuid: item.data.uuid
+});
diff --git a/src/views/data-explorer/data-explorer.tsx b/src/views/data-explorer/data-explorer.tsx
index 5f17b63..20c6df5 100644
--- a/src/views/data-explorer/data-explorer.tsx
+++ b/src/views/data-explorer/data-explorer.tsx
@@ -3,7 +3,6 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { DataTableProps } from "../../components/data-table";
 import { RouteComponentProps } from 'react-router';
 import { Project } from '../../models/project';
 import { ProjectState, findTreeItem } from '../../store/project/project-reducer';
@@ -11,20 +10,17 @@ import { RootState } from '../../store/store';
 import { connect, DispatchProp } from 'react-redux';
 import { push } from 'react-router-redux';
 import projectActions from "../../store/project/project-action";
-import { DataExplorer, DataItem } from '../../components/data-explorer';
-import { TreeItem } from '../../components/tree/tree';
+import { DataColumns } from "../../components/data-table/data-table";
+import { DataItem } from "../../views-components/data-explorer/data-item";
+import DataExplorer from "../../views-components/data-explorer/data-explorer";
+import { mapProjectTreeItem } from "../../views-selectors/data-explorer/data-explorer";
 
 interface DataExplorerViewDataProps {
     projects: ProjectState;
 }
 
 type DataExplorerViewProps = DataExplorerViewDataProps & RouteComponentProps<{ name: string }> & DispatchProp;
-
-type DataExplorerViewState = Pick<DataTableProps<Project>, "columns">;
-
-interface MappedProjectItem extends DataItem {
-    uuid: string;
-}
+type DataExplorerViewState = DataColumns<Project>;
 
 class DataExplorerView extends React.Component<DataExplorerViewProps, DataExplorerViewState> {
 
@@ -33,28 +29,18 @@ class DataExplorerView extends React.Component<DataExplorerViewProps, DataExplor
         const projectItems = project && project.items || [];
         return (
             <DataExplorer
-                items={projectItems.map(mapTreeItem)}
+                items={projectItems.map(mapProjectTreeItem)}
                 onItemClick={this.goToProject}
             />
         );
     }
 
-    goToProject = (project: MappedProjectItem) => {
-        this.props.dispatch(push(`/project/${project.uuid}`));
-        this.props.dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM(project.uuid));
+    goToProject = (item: DataItem) => {
+        this.props.dispatch(push(`/project/${item.uuid}`));
+        this.props.dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM(item.uuid));
     }
-
 }
 
-const mapTreeItem = (item: TreeItem<Project>): MappedProjectItem => ({
-    name: item.data.name,
-    type: item.data.kind,
-    owner: item.data.ownerUuid,
-    lastModified: item.data.modifiedAt,
-    uuid: item.data.uuid
-});
-
-
 export default connect(
     (state: RootState) => ({
         projects: state.projects
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index ee4ac7f..5da3968 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -11,11 +11,11 @@ import { Route, Switch } from "react-router";
 import authActions from "../../store/auth/auth-action";
 import { User } from "../../models/user";
 import { RootState } from "../../store/store";
-import MainAppBar, { MainAppBarActionProps, MainAppBarMenuItem } from '../../components/main-app-bar/main-app-bar';
+import MainAppBar, { MainAppBarActionProps, MainAppBarMenuItem } from '../../views-components/main-app-bar/main-app-bar';
 import { Breadcrumb } from '../../components/breadcrumbs/breadcrumbs';
 import { push } from 'react-router-redux';
 import projectActions from "../../store/project/project-action";
-import ProjectTree from '../../components/project-tree/project-tree';
+import ProjectTree from '../../views-components/project-tree/project-tree';
 import { TreeItem, TreeItemStatus } from "../../components/tree/tree";
 import { Project } from "../../models/project";
 import { projectService } from '../../services/services';
@@ -133,7 +133,8 @@ class Workbench extends React.Component<WorkbenchProps, WorkbenchState> {
         if (status === TreeItemStatus.Loaded) {
             this.openProjectItem(itemId);
         } else {
-            this.props.dispatch<any>(projectService.getProjectList(itemId)).then(() => this.openProjectItem(itemId));
+            this.props.dispatch<any>(projectService.getProjectList(itemId))
+                .then(() => this.openProjectItem(itemId));
         }
     }
 

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list