Create shared projects tree picker
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Tue, 9 Oct 2018 12:02:26 +0000 (14:02 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Tue, 9 Oct 2018 12:02:26 +0000 (14:02 +0200)
Feature #13862

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

src/index.tsx
src/services/groups-service/groups-service.ts
src/store/tree-picker/tree-picker-actions.ts
src/views-components/projects-tree-picker/projects-tree-picker.tsx
src/views-components/projects-tree-picker/shared-projects-tree-picker.tsx
src/views/workbench/workbench.tsx

index 84b765792bd7411043bf0d616a1fb1eb47fe8335..444a3ec0a397b71f5097509cc1b0b981c7f46fb1 100644 (file)
@@ -43,7 +43,7 @@ import { trashedCollectionActionSet } from '~/views-components/context-menu/acti
 import { ContainerRequestState } from '~/models/container-request';
 import { MountKind } from '~/models/mount-types';
 import { receiveTreePickerData, loadUserProject } from '~/store/tree-picker/tree-picker-actions';
-import { loadProject, loadCollection, initUserProject } from './store/tree-picker/tree-picker-actions';
+import { loadProject, loadCollection, initUserProject, initSharedProject } from './store/tree-picker/tree-picker-actions';
 import { ResourceKind } from '~/models/resource';
 
 const getBuildNumber = () => "BN-" + (process.env.REACT_APP_BUILD_NUMBER || "dev");
@@ -120,6 +120,9 @@ const initListener = (history: History, store: RootStore, services: ServiceRepos
             store.dispatch(initUserProject('testPicker1'));
             store.dispatch(initUserProject('testPicker2'));
             store.dispatch(initUserProject('testPicker3'));
+            store.dispatch(initSharedProject('testPicker4'));
+            store.dispatch(initSharedProject('testPicker5'));
+            store.dispatch(initSharedProject('testPicker6'));
             // await store.dispatch(loadCollection(
             //     'c97qk-4zz18-9sn8ygaf62chkkd',
             //     'testPicker',
index c4c56f38fc514efaa602d377f2ef9d8a0e70e728..3864a0b12db0ca098ebf6fd42b16b39a394baa88 100644 (file)
@@ -20,6 +20,7 @@ export interface ContentsArguments {
     filters?: string;
     recursive?: boolean;
     includeTrash?: boolean;
+    excludeHomeProject?: boolean;
 }
 
 export interface SharedArguments extends ListArguments {
@@ -45,14 +46,16 @@ export class GroupsService<T extends GroupResource = GroupResource> extends Tras
             order: order ? order : undefined
         };
 
+        const pathUrl = uuid ? `${uuid}/contents` : 'contents';
         const response = await CommonResourceService.defaultResponse(
             this.serverApi
-                .get(this.resourceType + `${uuid}/contents`, {
+                .get(this.resourceType + pathUrl, {
                     params: CommonResourceService.mapKeys(_.snakeCase)(params)
                 }),
-            this.actions, 
+            this.actions,
             false
         );
+        
         const { items, ...res } = response;
         const mappedItems = items.map((item: GroupContentsResource) => {
             const mappedItem = TrashableResourceService.mapKeys(_.camelCase)(item);
index 3c3b052af3aefc7e1ef4f76676d55a40815fd69c..a4da9d46c4ba88d4454164bad84a9c500abaa756 100644 (file)
@@ -41,20 +41,28 @@ export const receiveTreePickerData = <T>(params: ReceiveTreePickerDataParams<T>)
         }));
         dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id, pickerId }));
     };
-export const loadProject = (id: string, pickerId: string, includeCollections = false, includeFiles = false) =>
+
+interface LoadProjectParams {
+    id: string;
+    pickerId: string;
+    includeCollections?: boolean;
+    includeFiles?: boolean;
+    loadShared?: boolean;
+}
+export const loadProject = (params: LoadProjectParams) =>
     async (dispatch: Dispatch, _: () => RootState, services: ServiceRepository) => {
+        const { id, pickerId, includeCollections = false, includeFiles = false, loadShared = false } = params;
 
         dispatch(treePickerActions.LOAD_TREE_PICKER_NODE({ id, pickerId }));
 
         const filters = pipe(
-            (fb: FilterBuilder) => fb.addEqual('ownerUuid', id),
-            fb => includeCollections
+            (fb: FilterBuilder) => includeCollections
                 ? fb.addIsA('uuid', [ResourceKind.PROJECT, ResourceKind.COLLECTION])
                 : fb.addIsA('uuid', [ResourceKind.PROJECT]),
             fb => fb.getFilters(),
         )(new FilterBuilder());
 
-        const { items } = await services.groupsService.contents(id, { filters });
+        const { items } = await services.groupsService.contents(loadShared ? '' : id, { filters, excludeHomeProject: loadShared || undefined });
 
         dispatch<any>(receiveTreePickerData<GroupContentsResource>({
             id,
@@ -112,7 +120,7 @@ export const loadUserProject = (pickerId: string, includeCollections = false, in
     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
         const uuid = services.authService.getUuid();
         if (uuid) {
-            dispatch(loadProject(uuid, pickerId, includeCollections, includeFiles));
+            dispatch(loadProject({id: uuid, pickerId, includeCollections, includeFiles}));
         }
     };
 
index ac6d76e6d1a90de3adfb0407dbd46d0dda866ddd..be030efff7691d33d7bae626319439201b04fa03 100644 (file)
@@ -42,7 +42,7 @@ const mapStateToProps = (_: any, { pickerId, rootItemIcon }: ProjectsTreePickerP
     pickerId,
 });
 
-const mapDispatchToProps = (dispatch: Dispatch, props: ProjectsTreePickerProps): PickedTreePickerProps => ({
+const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollections, includeFiles }: ProjectsTreePickerProps): PickedTreePickerProps => ({
     onContextMenu: () => { return; },
     toggleItemActive: (_, { id }, pickerId) => {
         dispatch(treePickerActions.ACTIVATE_TREE_PICKER_NODE({ id, pickerId }));
@@ -54,10 +54,10 @@ const mapDispatchToProps = (dispatch: Dispatch, props: ProjectsTreePickerProps):
                 dispatch<any>(
                     data.kind === ResourceKind.COLLECTION
                         ? loadCollection(id, pickerId)
-                        : loadProject(id, pickerId, props.includeCollections, props.includeFiles)
+                        : loadProject({ id, pickerId, includeCollections, includeFiles })
                 );
-            } else if (!('type' in data) && props.loadRootItem) {
-                props.loadRootItem(item as TreeItem<ProjectsTreePickerRootItem>, pickerId, props.includeCollections, props.includeFiles);
+            } else if (!('type' in data) && loadRootItem) {
+                loadRootItem(item as TreeItem<ProjectsTreePickerRootItem>, pickerId, includeCollections, includeFiles);
             }
         } else if (status === TreeItemStatus.LOADED) {
             dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id, pickerId }));
index 2039db720331512908c2d457895d23bb59cb6766..6a05c2aac9716cc02ab4eb7b9895fe060c28f5f1 100644 (file)
@@ -5,13 +5,13 @@
 import { connect } from 'react-redux';
 import { ProjectsTreePicker, ProjectsTreePickerProps } from '~/views-components/projects-tree-picker/projects-tree-picker';
 import { Dispatch } from 'redux';
-import { loadUserProject } from '~/store/tree-picker/tree-picker-actions';
-import { ShareIcon } from '~/components/icon/icon';
+import { ShareMeIcon } from '~/components/icon/icon';
+import { loadProject } from '../../store/tree-picker/tree-picker-actions';
 
-export const UserProjectsTreePicker = connect(() => ({
-    rootItemIcon: ShareIcon,
+export const SharedProjectsTreePicker = connect(() => ({
+    rootItemIcon: ShareMeIcon,
 }), (dispatch: Dispatch): Pick<ProjectsTreePickerProps, 'loadRootItem'> => ({
     loadRootItem: (_, pickerId, includeCollections, includeFiles) => {
-        dispatch<any>(loadUserProject(pickerId, includeCollections, includeFiles));
+        dispatch<any>(loadProject({ id: 'Shared with me', pickerId, includeCollections, includeFiles, loadShared: true }));
     },
 }))(ProjectsTreePicker);
\ No newline at end of file
index 998e40045d25aab3500dc86812e23015acd08762..96f54730062573e00ac6da30e9d672f492f79798 100644 (file)
@@ -47,6 +47,7 @@ import { TreeItem } from '~/components/tree/tree';
 import { GroupContentsResource } from '~/services/groups-service/groups-service';
 import { ProjectsTreePicker } from '~/views-components/projects-tree-picker/projects-tree-picker';
 import { UserProjectsTreePicker } from '~/views-components/projects-tree-picker/user-projects-tree-picker';
+import { SharedProjectsTreePicker } from '~/views-components/projects-tree-picker/shared-projects-tree-picker';
 
 type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content';
 
@@ -97,6 +98,9 @@ export const WorkbenchPanel =
                             <UserProjectsTreePicker pickerId='testPicker1'/>
                             <UserProjectsTreePicker pickerId='testPicker2' includeCollections/>
                             <UserProjectsTreePicker pickerId='testPicker3' includeCollections includeFiles/>
+                            <SharedProjectsTreePicker pickerId='testPicker4'/>
+                            <SharedProjectsTreePicker pickerId='testPicker5' includeCollections/>
+                            <SharedProjectsTreePicker pickerId='testPicker6' includeCollections includeFiles/>
                             <Switch>
                                 <Route path={Routes.PROJECTS} component={ProjectPanel} />
                                 <Route path={Routes.COLLECTIONS} component={CollectionPanel} />