import { Resource, ResourceKind } from "../../models/resource";
import { projectPanelActions } from "../project-panel/project-panel-action";
import { getCollectionUrl } from "../../models/collection";
-import { getProjectUrl } from "../../models/project";
+import { getProjectUrl, ProjectResource } from "../../models/project";
+import { ProjectService } from "../../services/project-service/project-service";
+import { ServiceRepository } from "../../services/services";
+import { sidePanelActions } from "../side-panel/side-panel-action";
+import { SidePanelIdentifiers } from "../side-panel/side-panel-reducer";
export const getResourceUrl = <T extends Resource>(resource: T): string => {
switch (resource.kind) {
}
export const setProjectItem = (itemId: string, itemMode: ItemMode) =>
- (dispatch: Dispatch, getState: () => RootState) => {
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
const { projects, router } = getState();
const treeItem = findTreeItem(projects.items, itemId);
}
};
+export const restoreBranch = (itemId: string) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ const ancestors = await loadProjectAncestors(itemId, services.projectService);
+ const uuids = ancestors.map(ancestor => ancestor.uuid);
+ await loadBranch(uuids, dispatch);
+ dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(SidePanelIdentifiers.PROJECTS));
+ uuids.forEach(uuid => {
+ dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN(uuid));
+ });
+ };
+
+const USER_UUID_REGEX = /.*tpzed.*/;
+
+export const loadProjectAncestors = async (uuid: string, projectService: ProjectService): Promise<Array<ProjectResource>> => {
+ if (USER_UUID_REGEX.test(uuid)) {
+ return [];
+ } else {
+ const currentProject = await projectService.get(uuid);
+ const ancestors = await loadProjectAncestors(currentProject.ownerUuid, projectService);
+ return [...ancestors, currentProject];
+ }
+};
+
+const loadBranch = async (uuids: string[], dispatch: Dispatch): Promise<any> => {
+ const [uuid, ...rest] = uuids;
+ if (uuid) {
+ await dispatch<any>(getProjectList(uuid));
+ return loadBranch(rest, dispatch);
+ }
+};
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { require } from '../require';
+import { maxLength } from '../max-length';
+
+export const COLLECTION_NAME_VALIDATION = [require, maxLength(255)];
+export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)];
\ No newline at end of file
export const PROJECT_NAME_VALIDATION = [require, maxLength(255)];
export const PROJECT_DESCRIPTION_VALIDATION = [maxLength(255)];
-export const COLLECTION_NAME_VALIDATION = [require, maxLength(255)];
-export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)];
const { ownerUuid } = getState().projects.creator;
return dispatch<any>(createProject(data)).then(() => {
dispatch(snackbarActions.OPEN_SNACKBAR({
- message: "Created a new project",
+ message: "Project has been successfully created.",
hideDuration: 2000
}));
dispatch(projectPanelActions.REQUEST_ITEMS());
import DialogTitle from '@material-ui/core/DialogTitle';
import { Button, StyleRulesCallback, WithStyles, withStyles, CircularProgress } from '@material-ui/core';
-import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-project/create-project-validator';
+import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-collection/create-collection-validator';
type CssRules = "button" | "lastButton" | "formContainer" | "textField" | "createProgress" | "dialogActions";
import { compose } from 'redux';
import { ArvadosTheme } from '../../common/custom-theme';
import { Dialog, DialogActions, DialogContent, DialogTitle, TextField, StyleRulesCallback, withStyles, WithStyles, Button, CircularProgress } from '../../../node_modules/@material-ui/core';
-import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-project/create-project-validator';
+import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-collection/create-collection-validator';
import { COLLECTION_FORM_NAME } from '../../store/collections/updator/collection-updator-action';
type CssRules = 'content' | 'actions' | 'textField' | 'buttonWrapper' | 'saveButton' | 'circularProgress';
import { getTreePath } from '../../store/project/project-reducer';
import { sidePanelActions } from '../../store/side-panel/side-panel-action';
import { SidePanel, SidePanelItem } from '../../components/side-panel/side-panel';
-import { ItemMode, setProjectItem } from "../../store/navigation/navigation-action";
+import { ItemMode, setProjectItem, restoreBranch } from "../../store/navigation/navigation-action";
import { projectActions } from "../../store/project/project-action";
import { collectionCreateActions } from '../../store/collections/creator/collection-creator-action';
import { ProjectPanel } from "../project-panel/project-panel";
user?: User;
currentToken?: string;
sidePanelItems: SidePanelItem[];
+ router?: any;
}
interface WorkbenchServiceProps {
currentProjectId: state.projects.currentItemId,
user: state.auth.user,
currentToken: state.auth.apiToken,
- sidePanelItems: state.sidePanel
+ sidePanelItems: state.sidePanel,
+ router: state.router.location
})
)(
class extends React.Component<WorkbenchProps, WorkbenchState> {
}
};
+ componentDidMount() {
+ const PROJECT_URL_REGEX = /\/projects\/(.*)/;
+ const getProjectIdFromUrl = (url: string) => {
+ const match = PROJECT_URL_REGEX.exec(url);
+ return match ? match[1] : match;
+ };
+
+ const id = getProjectIdFromUrl(this.props.router.pathname);
+ if (id) {
+ this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
+ this.props.dispatch<any>(restoreBranch(id));
+ }
+ }
+
render() {
const path = getTreePath(this.props.projects, this.props.currentProjectId);
const breadcrumbs = path.map(item => ({
case ResourceKind.COLLECTION:
this.props.dispatch(loadCollection(item.uuid, item.kind as ResourceKind));
this.props.dispatch(push(getCollectionUrl(item.uuid)));
- default:
+ default:
this.props.dispatch(setProjectItem(item.uuid, ItemMode.ACTIVE));
this.props.dispatch(loadDetails(item.uuid, item.kind as ResourceKind));
}