import { projectActions, getProjectList } from "../project/project-action";
import { push } from "react-router-redux";
import { TreeItemStatus } from "../../components/tree/tree";
-import { findTreeItem } from "../project/project-reducer";
+import { findTreeItem, getTreePath } from "../project/project-reducer";
- import { dataExplorerActions } from "../data-explorer/data-explorer-action";
- import { PROJECT_PANEL_ID } from "../../views/project-panel/project-panel";
import { RootState } from "../store";
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/services";
++import { ServiceRepository } from "../../services/services";
++import { ProjectService } from "../../services/project-service/project-service";
export const getResourceUrl = <T extends Resource>(resource: T): string => {
switch (resource.kind) {
}
};
- export const loadProjectAncestors = async (uuid: string): Promise<Array<ProjectResource>> => {
+ const USER_UUID_REGEX = /.*tpzed.*/;
+
- const currentProject = await projectService.get(uuid);
++ export const loadProjectAncestors = async (uuid: string, services?: any): Promise<Array<ProjectResource>> => {
+ if (USER_UUID_REGEX.test(uuid)) {
+ return [];
+ } else {
++ const currentProject = await services.projectService.get(uuid);
+ const ancestors = await loadProjectAncestors(currentProject.ownerUuid);
+ return [...ancestors, currentProject];
+ }
+ };
--- /dev/null
-import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-project/create-project-validator';
+ // Copyright (C) The Arvados Authors. All rights reserved.
+ //
+ // SPDX-License-Identifier: AGPL-3.0
+
+ import * as React from 'react';
+ import { reduxForm, Field } from 'redux-form';
+ 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-collection/create-collection-validator';
+ import { COLLECTION_FORM_NAME } from '../../store/collections/updator/collection-updator-action';
+
+ type CssRules = 'content' | 'actions' | 'textField' | 'buttonWrapper' | 'saveButton' | 'circularProgress';
+
+ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ content: {
+ display: 'flex',
+ flexDirection: 'column'
+ },
+ actions: {
+ margin: 0,
+ padding: `${theme.spacing.unit}px ${theme.spacing.unit * 3 - theme.spacing.unit / 2}px
+ ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`
+ },
+ textField: {
+ marginBottom: theme.spacing.unit * 3
+ },
+ buttonWrapper: {
+ position: 'relative'
+ },
+ saveButton: {
+ boxShadow: 'none'
+ },
+ circularProgress: {
+ position: 'absolute',
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0,
+ margin: 'auto'
+ }
+ });
+
+ interface DialogCollectionDataProps {
+ open: boolean;
+ handleSubmit: any;
+ submitting: boolean;
+ invalid: boolean;
+ pristine: boolean;
+ }
+
+ interface DialogCollectionAction {
+ handleClose: () => void;
+ onSubmit: (data: { name: string, description: string }) => void;
+ }
+
+ type DialogCollectionProps = DialogCollectionDataProps & DialogCollectionAction & WithStyles<CssRules>;
+
+ interface TextFieldProps {
+ label: string;
+ floatinglabeltext: string;
+ className?: string;
+ input?: string;
+ meta?: any;
+ }
+
+ export const DialogCollectionUpdate = compose(
+ reduxForm({ form: COLLECTION_FORM_NAME }),
+ withStyles(styles))(
+
+ class DialogCollectionUpdate extends React.Component<DialogCollectionProps> {
+
+ render() {
+ const { classes, open, handleClose, handleSubmit, onSubmit, submitting, invalid, pristine } = this.props;
+ return (
+ <Dialog open={open}
+ onClose={handleClose}
+ fullWidth={true}
+ maxWidth='sm'
+ disableBackdropClick={true}
+ disableEscapeKeyDown={true}>
+
+ <form onSubmit={handleSubmit((data: any) => onSubmit(data))}>
+ <DialogTitle>Edit Collection</DialogTitle>
+ <DialogContent className={classes.content}>
+ <Field name="name"
+ disabled={submitting}
+ component={this.renderTextField}
+ floatinglabeltext="Collection Name"
+ validate={COLLECTION_NAME_VALIDATION}
+ className={classes.textField}
+ label="Collection Name" />
+ <Field name="description"
+ disabled={submitting}
+ component={this.renderTextField}
+ floatinglabeltext="Description - optional"
+ validate={COLLECTION_DESCRIPTION_VALIDATION}
+ className={classes.textField}
+ label="Description - optional" />
+ </DialogContent>
+ <DialogActions className={classes.actions}>
+ <Button onClick={handleClose} color="primary"
+ disabled={submitting}>CANCEL</Button>
+ <div className={classes.buttonWrapper}>
+ <Button type="submit" className={classes.saveButton}
+ color="primary"
+ disabled={invalid || submitting || pristine}
+ variant="contained">
+ SAVE
+ </Button>
+ {submitting && <CircularProgress size={20} className={classes.circularProgress} />}
+ </div>
+ </DialogActions>
+ </form>
+ </Dialog>
+ );
+ }
+
+ renderTextField = ({ input, label, meta: { touched, error }, ...custom }: TextFieldProps) => (
+ <TextField
+ helperText={touched && error}
+ label={label}
+ className={this.props.classes.textField}
+ error={touched && !!error}
+ autoComplete='off'
+ {...input}
+ {...custom}
+ />
+ )
+ }
+ );
version "10.5.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.2.tgz#f19f05314d5421fe37e74153254201a7bf00a707"
++"@types/react-copy-to-clipboard@4.2.5":
++ version "4.2.5"
++ resolved "https://registry.yarnpkg.com/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-4.2.5.tgz#bda288b4256288676019b75ca86f1714bbd206d4"
++ dependencies:
++ "@types/react" "*"
++
"@types/react-dom@16.0.6":
version "16.0.6"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.6.tgz#f1a65a4e7be8ed5d123f8b3b9eacc913e35a1a3c"
version "0.1.1"
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
++copy-to-clipboard@^3:
++ version "3.0.8"
++ resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.0.8.tgz#f4e82f4a8830dce4666b7eb8ded0c9bcc313aba9"
++ dependencies:
++ toggle-selection "^1.0.3"
++
core-js@^1.0.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
++react-copy-to-clipboard@5.0.1:
++ version "5.0.1"
++ resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz#8eae107bb400be73132ed3b6a7b4fb156090208e"
++ dependencies:
++ copy-to-clipboard "^3"
++ prop-types "^15.5.8"
++
react-dev-utils@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.1.tgz#1f396e161fe44b595db1b186a40067289bf06613"
regex-not "^1.0.2"
safe-regex "^1.1.0"
++toggle-selection@^1.0.3:
++ version "1.0.6"
++ resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
++
toposort@^1.0.0:
version "1.0.7"
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029"