X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/8b501e5ced1608766db8d16022d34c1ad363fcc8..67d63d61aa5a1f1bc1bb85bf6b788e6c0d21e298:/src/views-components/project-tree-picker/project-tree-picker.tsx diff --git a/src/views-components/project-tree-picker/project-tree-picker.tsx b/src/views-components/project-tree-picker/project-tree-picker.tsx index 49fb4d455f..ddf684381a 100644 --- a/src/views-components/project-tree-picker/project-tree-picker.tsx +++ b/src/views-components/project-tree-picker/project-tree-picker.tsx @@ -6,78 +6,167 @@ import * as React from "react"; import { Dispatch } from "redux"; import { connect } from "react-redux"; import { Typography } from "@material-ui/core"; -import { TreePicker } from "../tree-picker/tree-picker"; -import { TreeProps, TreeItem, TreeItemStatus } from "../../components/tree/tree"; -import { ProjectResource } from "../../models/project"; -import { treePickerActions } from "../../store/tree-picker/tree-picker-actions"; -import { ListItemTextIcon } from "../../components/list-item-text-icon/list-item-text-icon"; -import { ProjectIcon } from "../../components/icon/icon"; -import { createTreePickerNode } from "../../store/tree-picker/tree-picker"; -import { RootState } from "../../store/store"; -import { ServiceRepository } from "../../services/services"; -import { FilterBuilder } from "../../common/api/filter-builder"; - -type ProjectTreePickerProps = Pick, 'toggleItemActive' | 'toggleItemOpen'>; +import { TreePicker, TreePickerProps } from "../tree-picker/tree-picker"; +import { TreeItem, TreeItemStatus } from "~/components/tree/tree"; +import { ProjectResource } from "~/models/project"; +import { treePickerActions } from "~/store/tree-picker/tree-picker-actions"; +import { ListItemTextIcon } from "~/components/list-item-text-icon/list-item-text-icon"; +import { ProjectIcon, FavoriteIcon, ProjectsIcon, ShareMeIcon } from "~/components/icon/icon"; +import { createTreePickerNode } from "~/store/tree-picker/tree-picker"; +import { RootState } from "~/store/store"; +import { ServiceRepository } from "~/services/services"; +import { FilterBuilder } from "~/common/api/filter-builder"; +import { mockProjectResource } from "~/models/test-utils"; + +type ProjectTreePickerProps = Pick; const mapDispatchToProps = (dispatch: Dispatch, props: { onChange: (projectUuid: string) => void }): ProjectTreePickerProps => ({ - toggleItemActive: id => { - dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECT({ id })); + toggleItemActive: (id, status, pickerKind) => { + getNotSelectedTreePickerKind(pickerKind) + .forEach(pickerKind => dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECT({ id: '', pickerKind }))); + dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECT({ id, pickerKind })); + props.onChange(id); }, - toggleItemOpen: (id, status) => { - status === TreeItemStatus.INITIAL - ? dispatch(loadProjectTreePickerProjects(id)) - : dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id })); + toggleItemOpen: (id, status, pickerKind) => { + dispatch(toggleItemOpen(id, status, pickerKind)); } }); +const toggleItemOpen = (id: string, status: TreeItemStatus, pickerKind: string) => + (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + if (status === TreeItemStatus.INITIAL) { + if (pickerKind === TreePickerKind.PROJECTS) { + dispatch(loadProjectTreePickerProjects(id)); + } else if (pickerKind === TreePickerKind.FAVORITES) { + dispatch(loadFavoriteTreePickerProjects(id === services.authService.getUuid() ? '' : id)); + } else { + // TODO: load sharedWithMe + } + } else { + dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id, pickerKind })); + } + }; + +const getNotSelectedTreePickerKind = (pickerKind: string) => { + return [TreePickerKind.PROJECTS, TreePickerKind.FAVORITES, TreePickerKind.SHARED_WITH_ME].filter(id => id !== pickerKind); +}; + +export enum TreePickerKind { + PROJECTS = 'Projects', + SHARED_WITH_ME = 'Shared with me', + FAVORITES = 'Favorites' +} + export const ProjectTreePicker = connect(undefined, mapDispatchToProps)((props: ProjectTreePickerProps) =>
Select a project
- + + +
); -export const ProjectTreePickerWithSidePanel = connect(undefined, mapDispatchToProps)((props: ProjectTreePickerProps) => -
-
- -
-
-); // TODO: move action creator to store directory export const loadProjectTreePickerProjects = (id: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - dispatch(treePickerActions.LOAD_TREE_PICKER_NODE({ id })); + dispatch(treePickerActions.LOAD_TREE_PICKER_NODE({ id, pickerKind: TreePickerKind.PROJECTS })); const ownerUuid = id.length === 0 ? services.authService.getUuid() || '' : id; - const filters = FilterBuilder - .create() - .addEqual('ownerUuid', ownerUuid); + const filters = new FilterBuilder() + .addEqual('ownerUuid', ownerUuid) + .getFilters(); const { items } = await services.projectService.list({ filters }); - dispatch(receiveProjectTreePickerData(id, items)); + dispatch(receiveTreePickerData(id, items, TreePickerKind.PROJECTS)); }; +export const loadFavoriteTreePickerProjects = (id: string) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const parentId = services.authService.getUuid() || ''; + + if (id === '') { + dispatch(treePickerActions.LOAD_TREE_PICKER_NODE({ id: parentId, pickerKind: TreePickerKind.FAVORITES })); + const { items } = await services.favoriteService.list(parentId); + + dispatch(receiveTreePickerData(parentId, items as ProjectResource[], TreePickerKind.FAVORITES)); + } else { + dispatch(treePickerActions.LOAD_TREE_PICKER_NODE({ id, pickerKind: TreePickerKind.FAVORITES })); + const filters = new FilterBuilder() + .addEqual('ownerUuid', id) + .getFilters(); + + const { items } = await services.projectService.list({ filters }); + + dispatch(receiveTreePickerData(id, items, TreePickerKind.FAVORITES)); + } + + }; + +const getProjectPickerIcon = (item: TreeItem) => { + switch (item.data.name) { + case TreePickerKind.FAVORITES: + return FavoriteIcon; + case TreePickerKind.PROJECTS: + return ProjectsIcon; + case TreePickerKind.SHARED_WITH_ME: + return ShareMeIcon; + default: + return ProjectIcon; + } +}; + const renderTreeItem = (item: TreeItem) => ; + // TODO: move action creator to store directory -const receiveProjectTreePickerData = (id: string, projects: ProjectResource[]) => +export const receiveTreePickerData = (id: string, projects: ProjectResource[], pickerKind: string) => (dispatch: Dispatch) => { dispatch(treePickerActions.LOAD_TREE_PICKER_NODE_SUCCESS({ id, - nodes: projects.map(project => createTreePickerNode({ id: project.uuid, value: project })) + nodes: projects.map(project => createTreePickerNode({ id: project.uuid, value: project })), + pickerKind, })); - dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id })); - }; \ No newline at end of file + + dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id, pickerKind })); + }; + +export const initPickerProjectTree = () => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const uuid = services.authService.getUuid(); + + dispatch(getPickerTreeProjects(uuid)); + dispatch(getSharedWithMeProjectsPickerTree(uuid)); + dispatch(getFavoritesProjectsPickerTree(uuid)); +}; + +const getPickerTreeProjects = (uuid: string = '') => { + return getProjectsPickerTree(uuid, TreePickerKind.PROJECTS); +}; + +const getSharedWithMeProjectsPickerTree = (uuid: string = '') => { + return getProjectsPickerTree(uuid, TreePickerKind.SHARED_WITH_ME); +}; + +const getFavoritesProjectsPickerTree = (uuid: string = '') => { + return getProjectsPickerTree(uuid, TreePickerKind.FAVORITES); +}; + +const getProjectsPickerTree = (uuid: string, kind: string) => { + return receiveTreePickerData( + '', + [mockProjectResource({ uuid, name: kind })], + kind + ); +}; +