// Copyright (C) The Arvados Authors. All rights reserved. // // SPDX-License-Identifier: AGPL-3.0 import * as React from "react"; import { Dispatch } from "redux"; import { connect } from "react-redux"; import { Typography } from "@material-ui/core"; 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, 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, 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
); // 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, pickerKind: TreePickerKind.PROJECTS })); const ownerUuid = id.length === 0 ? services.authService.getUuid() || '' : id; const filters = new FilterBuilder() .addEqual('ownerUuid', ownerUuid) .getFilters(); const { items } = await services.projectService.list({ filters }); 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 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 })), pickerKind, })); 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 ); };