X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/89161730d7d5e7d16a8fe2f5494db6560e718fa3..d842372e4f45ee06315e511529e65ae1d3f319a0:/src/store/project/project-reducer.ts diff --git a/src/store/project/project-reducer.ts b/src/store/project/project-reducer.ts index ac6d4b73ff..bb0748657e 100644 --- a/src/store/project/project-reducer.ts +++ b/src/store/project/project-reducer.ts @@ -2,14 +2,31 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { Project } from "../../models/project"; -import actions, { ProjectAction } from "./project-action"; -import { TreeItem } from "../../components/tree/tree"; import * as _ from "lodash"; -export type ProjectState = Array>; +import { projectActions, ProjectAction } from "./project-action"; +import { TreeItem, TreeItemStatus } from "~/components/tree/tree"; +import { ProjectResource } from "~/models/project"; -function findTreeItem(tree: Array>, itemId: string): TreeItem | undefined { +export type ProjectState = { + items: Array>, + currentItemId: string, + creator: ProjectCreator, + updater: ProjectUpdater +}; + +interface ProjectCreator { + opened: boolean; + ownerUuid: string; + error?: string; +} + +interface ProjectUpdater { + opened: boolean; + uuid: string; +} + +export function findTreeItem(tree: Array>, itemId: string): TreeItem | undefined { let item; for (const t of tree) { item = t.id === itemId @@ -22,13 +39,26 @@ function findTreeItem(tree: Array>, itemId: string): TreeItem return item; } -export function findTreeBranch(tree: Array>, itemId: string): Array> { - for(const item of tree){ - if(item.id === itemId){ +export function getActiveTreeItem(tree: Array>): TreeItem | undefined { + let item; + for (const t of tree) { + item = t.active + ? t + : getActiveTreeItem(t.items ? t.items : []); + if (item) { + break; + } + } + return item; +} + +export function getTreePath(tree: Array>, itemId: string): Array> { + for (const item of tree) { + if (item.id === itemId) { return [item]; } else { - const branch = findTreeBranch(item.items || [], itemId); - if(branch.length > 0){ + const branch = getTreePath(item.items || [], itemId); + if (branch.length > 0) { return [item, ...branch]; } } @@ -43,18 +73,22 @@ function resetTreeActivity(tree: Array>) { } } -function updateProjectTree(tree: Array>, projects: Project[], parentItemId?: string): Array> { +function updateProjectTree(tree: Array>, projects: ProjectResource[], parentItemId?: string): Array> { let treeItem; if (parentItemId) { treeItem = findTreeItem(tree, parentItemId); + if (treeItem) { + treeItem.status = TreeItemStatus.LOADED; + } } - const items = projects.map((p, idx) => ({ + const items = projects.map(p => ({ id: p.uuid, open: false, active: false, + status: TreeItemStatus.INITIAL, data: p, items: [] - } as TreeItem)); + } as TreeItem)); if (treeItem) { treeItem.items = items; @@ -64,27 +98,96 @@ function updateProjectTree(tree: Array>, projects: Project[], return items; } +const updateCreator = (state: ProjectState, creator: Partial) => ({ + ...state, + creator: { + ...state.creator, + ...creator + } +}); + +const updateProject = (state: ProjectState, updater?: Partial) => ({ + ...state, + updater: { + ...state.updater, + ...updater + } +}); + +const initialState: ProjectState = { + items: [], + currentItemId: "", + creator: { + opened: false, + ownerUuid: "" + }, + updater: { + opened: false, + uuid: '' + } +}; + -const projectsReducer = (state: ProjectState = [], action: ProjectAction) => { - return actions.match(action, { - CREATE_PROJECT: project => [...state, project], +export const projectsReducer = (state: ProjectState = initialState, action: ProjectAction) => { + return projectActions.match(action, { + OPEN_PROJECT_CREATOR: ({ ownerUuid }) => updateCreator(state, { ownerUuid, opened: true }), + CLOSE_PROJECT_CREATOR: () => updateCreator(state, { opened: false }), + CREATE_PROJECT: () => updateCreator(state, { error: undefined }), + CREATE_PROJECT_SUCCESS: () => updateCreator(state, { opened: false, ownerUuid: "" }), + OPEN_PROJECT_UPDATER: ({ uuid }) => updateProject(state, { uuid, opened: true }), + CLOSE_PROJECT_UPDATER: () => updateProject(state, { opened: false, uuid: "" }), + UPDATE_PROJECT_SUCCESS: () => updateProject(state, { opened: false, uuid: "" }), REMOVE_PROJECT: () => state, - PROJECTS_REQUEST: () => state, + PROJECTS_REQUEST: itemId => { + const items = _.cloneDeep(state.items); + const item = findTreeItem(items, itemId); + if (item) { + item.status = TreeItemStatus.PENDING; + state.items = items; + } + return { ...state, items }; + }, PROJECTS_SUCCESS: ({ projects, parentItemId }) => { - return updateProjectTree(state, projects, parentItemId); + const items = _.cloneDeep(state.items); + return { + ...state, + items: updateProjectTree(items, projects, parentItemId) + }; }, - TOGGLE_PROJECT_TREE_ITEM: itemId => { - const tree = _.cloneDeep(state); - resetTreeActivity(tree); - const item = findTreeItem(tree, itemId); + TOGGLE_PROJECT_TREE_ITEM_OPEN: itemId => { + const items = _.cloneDeep(state.items); + const item = findTreeItem(items, itemId); if (item) { item.open = !item.open; + } + return { + ...state, + items, + currentItemId: itemId + }; + }, + TOGGLE_PROJECT_TREE_ITEM_ACTIVE: itemId => { + const items = _.cloneDeep(state.items); + resetTreeActivity(items); + const item = findTreeItem(items, itemId); + if (item) { item.active = true; } - return tree; + return { + ...state, + items, + currentItemId: itemId + }; + }, + RESET_PROJECT_TREE_ACTIVITY: () => { + const items = _.cloneDeep(state.items); + resetTreeActivity(items); + return { + ...state, + items, + currentItemId: "" + }; }, default: () => state }); }; - -export default projectsReducer;