import { getCommonResourceServiceError, CommonResourceServiceError } from '~/services/common-service/common-resource-service';
import { CopyFormDialogData } from '~/store/copy-dialog/copy-dialog';
import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
+import { initProjectsTreePicker } from '~/store/tree-picker/tree-picker-actions';
export const COLLECTION_COPY_FORM_NAME = 'collectionCopyFormName';
export const openCollectionCopyDialog = (resource: { name: string, uuid: string }) =>
(dispatch: Dispatch) => {
dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(COLLECTION_COPY_FORM_NAME));
const initialData: CopyFormDialogData = { name: `Copy of: ${resource.name}`, ownerUuid: '', uuid: resource.uuid };
dispatch<any>(initialize(COLLECTION_COPY_FORM_NAME, initialData));
dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_COPY_FORM_NAME, data: {} }));
import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
import { resetPickerProjectTree } from '~/store/project-tree-picker/project-tree-picker-actions';
import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
+import { initProjectsTreePicker } from '~/store/tree-picker/tree-picker-actions';
export const COLLECTION_MOVE_FORM_NAME = 'collectionMoveFormName';
export const openMoveCollectionDialog = (resource: { name: string, uuid: string }) =>
(dispatch: Dispatch) => {
dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(COLLECTION_MOVE_FORM_NAME));
dispatch(initialize(COLLECTION_MOVE_FORM_NAME, resource));
dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_MOVE_FORM_NAME, data: {} }));
};
import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
import { getCommonResourceServiceError, CommonResourceServiceError } from '~/services/common-service/common-resource-service';
import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
+import { initProjectsTreePicker } from '~/store/tree-picker/tree-picker-actions';
export const COLLECTION_PARTIAL_COPY_FORM_NAME = 'COLLECTION_PARTIAL_COPY_DIALOG';
};
dispatch(initialize(COLLECTION_PARTIAL_COPY_FORM_NAME, initialData));
dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(COLLECTION_PARTIAL_COPY_FORM_NAME));
dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME, data: {} }));
}
};
import { CopyFormDialogData } from '~/store/copy-dialog/copy-dialog';
import { getProcess, ProcessStatus, getProcessStatus } from '~/store/processes/process';
import { snackbarActions } from '~/store/snackbar/snackbar-actions';
+import { initProjectsTreePicker } from '~/store/tree-picker/tree-picker-actions';
export const PROCESS_COPY_FORM_NAME = 'processCopyFormName';
const processStatus = getProcessStatus(process);
if (processStatus === ProcessStatus.DRAFT) {
dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(PROCESS_COPY_FORM_NAME));
const initialData: CopyFormDialogData = { name: `Copy of: ${resource.name}`, uuid: resource.uuid, ownerUuid: '' };
dispatch<any>(initialize(PROCESS_COPY_FORM_NAME, initialData));
dispatch(dialogActions.OPEN_DIALOG({ id: PROCESS_COPY_FORM_NAME, data: {} }));
import { resetPickerProjectTree } from '~/store/project-tree-picker/project-tree-picker-actions';
import { projectPanelActions } from '~/store/project-panel/project-panel-action';
import { getProcess, getProcessStatus, ProcessStatus } from '~/store/processes/process';
+import { initProjectsTreePicker } from '~/store/tree-picker/tree-picker-actions';
export const PROCESS_MOVE_FORM_NAME = 'processMoveFormName';
const processStatus = getProcessStatus(process);
if (processStatus === ProcessStatus.DRAFT) {
dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(PROCESS_MOVE_FORM_NAME));
dispatch(initialize(PROCESS_MOVE_FORM_NAME, resource));
dispatch(dialogActions.OPEN_DIALOG({ id: PROCESS_MOVE_FORM_NAME, data: {} }));
} else {
import { getCommonResourceServiceError, CommonResourceServiceError } from "~/services/common-service/common-resource-service";
import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
import { resetPickerProjectTree } from '~/store/project-tree-picker/project-tree-picker-actions';
+import { initProjectsTreePicker } from '~/store/tree-picker/tree-picker-actions';
export const PROJECT_MOVE_FORM_NAME = 'projectMoveFormName';
export const openMoveProjectDialog = (resource: { name: string, uuid: string }) =>
(dispatch: Dispatch) => {
dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(PROJECT_MOVE_FORM_NAME));
dispatch(initialize(PROJECT_MOVE_FORM_NAME, resource));
dispatch(dialogActions.OPEN_DIALOG({ id: PROJECT_MOVE_FORM_NAME, data: {} }));
};
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+
+export interface PickerIdProp {
+ pickerId: string;
+}
+
+export const pickerId =
+ (id: string) =>
+ <P extends PickerIdProp>(Component: React.ComponentType<P>) =>
+ (props: P) =>
+ <Component {...props} pickerId={id} />;
+
\ No newline at end of file
if (node && 'kind' in node.value && node.value.kind === ResourceKind.COLLECTION) {
const filesTree = await services.collectionService.files(node.value.portableDataHash);
-
+
dispatch(
treePickerActions.APPEND_TREE_PICKER_NODE_SUBTREE({
id,
}
};
-
+export const SHARED_PROJECT_ID = 'Shared with me';
export const initSharedProject = (pickerId: string) =>
async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
dispatch(receiveTreePickerData({
id: '',
pickerId,
- data: [{ uuid: 'Shared with me', name: 'Shared with me' }],
+ data: [{ uuid: SHARED_PROJECT_ID, name: SHARED_PROJECT_ID }],
extractNodeData: value => ({
id: value.uuid,
status: TreeNodeStatus.INITIAL,
}));
};
+export const FAVORITES_PROJECT_ID = 'Favorites';
export const initFavoritesProject = (pickerId: string) =>
async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
dispatch(receiveTreePickerData({
id: '',
pickerId,
- data: [{ uuid: 'Favorites', name: 'Favorites' }],
+ data: [{ uuid: FAVORITES_PROJECT_ID, name: FAVORITES_PROJECT_ID }],
extractNodeData: value => ({
id: value.uuid,
status: TreeNodeStatus.INITIAL,
// SPDX-License-Identifier: AGPL-3.0
import * as React from "react";
+import { memoize } from "lodash/fp";
import { FormDialog } from '~/components/form-dialog/form-dialog';
import { CollectionNameField, CollectionDescriptionField, CollectionProjectPickerField } from '~/views-components/form-fields/collection-form-fields';
import { WithDialogProps } from '~/store/dialog/with-dialog';
import { InjectedFormProps } from 'redux-form';
import { CollectionPartialCopyFormData } from '~/store/collections/collection-partial-copy-actions';
+import { PickerIdProp } from "~/store/tree-picker/picker-id";
type DialogCollectionPartialCopyProps = WithDialogProps<string> & InjectedFormProps<CollectionPartialCopyFormData>;
-export const DialogCollectionPartialCopy = (props: DialogCollectionPartialCopyProps) =>
+export const DialogCollectionPartialCopy = (props: DialogCollectionPartialCopyProps & PickerIdProp) =>
<FormDialog
dialogTitle='Create a collection'
- formFields={CollectionPartialCopyFields}
+ formFields={CollectionPartialCopyFields(props.pickerId)}
submitLabel='Create a collection'
{...props}
/>;
-export const CollectionPartialCopyFields = () => <div>
- <CollectionNameField />
- <CollectionDescriptionField />
- <CollectionProjectPickerField />
-</div>;
+export const CollectionPartialCopyFields = memoize(
+ (pickerId: string) =>
+ () =>
+ <div>
+ <CollectionNameField />
+ <CollectionDescriptionField />
+ <CollectionProjectPickerField {...{ pickerId }} />
+ </div>);
// SPDX-License-Identifier: AGPL-3.0
import * as React from "react";
+import { memoize } from 'lodash/fp';
import { InjectedFormProps, Field } from 'redux-form';
import { WithDialogProps } from '~/store/dialog/with-dialog';
import { FormDialog } from '~/components/form-dialog/form-dialog';
import { COPY_NAME_VALIDATION, COPY_FILE_VALIDATION } from '~/validators/validators';
import { TextField } from "~/components/text-field/text-field";
import { CopyFormDialogData } from '~/store/copy-dialog/copy-dialog';
+import { PickerIdProp } from '~/store/tree-picker/picker-id';
type CopyFormDialogProps = WithDialogProps<string> & InjectedFormProps<CopyFormDialogData>;
-export const DialogCopy = (props: CopyFormDialogProps) =>
+export const DialogCopy = (props: CopyFormDialogProps & PickerIdProp) =>
<FormDialog
dialogTitle='Make a copy'
- formFields={CopyDialogFields}
+ formFields={CopyDialogFields(props.pickerId)}
submitLabel='Copy'
{...props}
/>;
-const CopyDialogFields = () => <span>
- <Field
- name='name'
- component={TextField}
- validate={COPY_NAME_VALIDATION}
- label="Enter a new name for the copy" />
- <Field
- name="ownerUuid"
- component={ProjectTreePickerField}
- validate={COPY_FILE_VALIDATION} />
-</span>;
+const CopyDialogFields = memoize((pickerId: string) =>
+ () =>
+ <span>
+ <Field
+ name='name'
+ component={TextField}
+ validate={COPY_NAME_VALIDATION}
+ label="Enter a new name for the copy" />
+ <Field
+ name="ownerUuid"
+ component={ProjectTreePickerField}
+ validate={COPY_FILE_VALIDATION}
+ pickerId={pickerId}/>
+ </span>);
import { DialogCopy } from "~/views-components/dialog-copy/dialog-copy";
import { copyCollection } from '~/store/workbench/workbench-actions';
import { CopyFormDialogData } from '~/store/copy-dialog/copy-dialog';
+import { pickerId } from '~/store/tree-picker/picker-id';
export const CopyCollectionDialog = compose(
withDialog(COLLECTION_COPY_FORM_NAME),
onSubmit: (data, dispatch) => {
dispatch(copyCollection(data));
}
- })
+ }),
+ pickerId(COLLECTION_COPY_FORM_NAME),
)(DialogCopy);
\ No newline at end of file
import { DialogCopy } from "~/views-components/dialog-copy/dialog-copy";
import { copyProcess } from '~/store/workbench/workbench-actions';
import { CopyFormDialogData } from '~/store/copy-dialog/copy-dialog';
+import { pickerId } from "~/store/tree-picker/picker-id";
export const CopyProcessDialog = compose(
withDialog(PROCESS_COPY_FORM_NAME),
onSubmit: (data, dispatch) => {
dispatch(copyProcess(data));
}
- })
+ }),
+ pickerId(PROCESS_COPY_FORM_NAME),
)(DialogCopy);
\ No newline at end of file
import { COLLECTION_MOVE_FORM_NAME } from '~/store/collections/collection-move-actions';
import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
import { moveCollection } from '~/store/workbench/workbench-actions';
+import { pickerId } from '~/store/tree-picker/picker-id';
export const MoveCollectionDialog = compose(
withDialog(COLLECTION_MOVE_FORM_NAME),
onSubmit: (data, dispatch) => {
dispatch(moveCollection(data));
}
- })
+ }),
+ pickerId(COLLECTION_MOVE_FORM_NAME),
)(DialogMoveTo);
import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
import { DialogMoveTo } from '~/views-components/dialog-move/dialog-move-to';
import { moveProcess } from '~/store/workbench/workbench-actions';
+import { pickerId } from '~/store/tree-picker/picker-id';
export const MoveProcessDialog = compose(
withDialog(PROCESS_MOVE_FORM_NAME),
onSubmit: (data, dispatch) => {
dispatch(moveProcess(data));
}
- })
+ }),
+ pickerId(PROCESS_MOVE_FORM_NAME),
)(DialogMoveTo);
\ No newline at end of file
import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
import { DialogMoveTo } from '~/views-components/dialog-move/dialog-move-to';
import { moveProject } from '~/store/workbench/workbench-actions';
+import { pickerId } from '~/store/tree-picker/picker-id';
export const MoveProjectDialog = compose(
withDialog(PROJECT_MOVE_FORM_NAME),
onSubmit: (data, dispatch) => {
dispatch(moveProject(data));
}
- })
+ }),
+ pickerId(PROJECT_MOVE_FORM_NAME),
)(DialogMoveTo);
import { withDialog, } from '~/store/dialog/with-dialog';
import { CollectionPartialCopyFormData, copyCollectionPartial, COLLECTION_PARTIAL_COPY_FORM_NAME } from '~/store/collections/collection-partial-copy-actions';
import { DialogCollectionPartialCopy } from "~/views-components/dialog-copy/dialog-collection-partial-copy";
+import { pickerId } from "~/store/tree-picker/picker-id";
export const PartialCopyCollectionDialog = compose(
onSubmit: (data, dispatch) => {
dispatch(copyCollectionPartial(data));
}
- }))(DialogCollectionPartialCopy);
\ No newline at end of file
+ }),
+ pickerId(COLLECTION_PARTIAL_COPY_FORM_NAME),
+)(DialogCollectionPartialCopy);
\ No newline at end of file
// SPDX-License-Identifier: AGPL-3.0
import * as React from "react";
+import { memoize } from 'lodash/fp';
import { InjectedFormProps, Field } from 'redux-form';
import { WithDialogProps } from '~/store/dialog/with-dialog';
import { FormDialog } from '~/components/form-dialog/form-dialog';
import { ProjectTreePickerField } from '~/views-components/project-tree-picker/project-tree-picker';
import { MOVE_TO_VALIDATION } from '~/validators/validators';
import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
+import { PickerIdProp } from "~/store/tree-picker/picker-id";
-export const DialogMoveTo = (props: WithDialogProps<string> & InjectedFormProps<MoveToFormDialogData>) =>
+export const DialogMoveTo = (props: WithDialogProps<string> & InjectedFormProps<MoveToFormDialogData> & PickerIdProp) =>
<FormDialog
dialogTitle='Move to'
- formFields={MoveToDialogFields}
+ formFields={MoveToDialogFields(props.pickerId)}
submitLabel='Move'
{...props}
/>;
-const MoveToDialogFields = () =>
- <Field
- name="ownerUuid"
- component={ProjectTreePickerField}
- validate={MOVE_TO_VALIDATION} />;
+const MoveToDialogFields = memoize(
+ (pickerId: string) => () =>
+ <Field
+ name="ownerUuid"
+ pickerId={pickerId}
+ component={ProjectTreePickerField}
+ validate={MOVE_TO_VALIDATION} />);
import { Field, WrappedFieldProps } from "redux-form";
import { TextField } from "~/components/text-field/text-field";
import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION, COLLECTION_PROJECT_VALIDATION } from "~/validators/validators";
-import { ProjectTreePicker } from "~/views-components/project-tree-picker/project-tree-picker";
+import { ProjectTreePicker, ProjectTreePickerField } from "~/views-components/project-tree-picker/project-tree-picker";
+import { PickerIdProp } from '../../store/tree-picker/picker-id';
export const CollectionNameField = () =>
<Field
validate={COLLECTION_DESCRIPTION_VALIDATION}
label="Description - optional" />;
-export const CollectionProjectPickerField = () =>
+export const CollectionProjectPickerField = (props: PickerIdProp) =>
<Field
name="projectUuid"
- component={ProjectPicker}
+ pickerId={props.pickerId}
+ component={ProjectTreePickerField}
validate={COLLECTION_PROJECT_VALIDATION} />;
-
-const ProjectPicker = (props: WrappedFieldProps) =>
- <div style={{ height: '144px', display: 'flex', flexDirection: 'column' }}>
- <ProjectTreePicker onChange={projectUuid => props.input.onChange(projectUuid)} />
- </div>;
import { ServiceRepository } from "~/services/services";
import { WrappedFieldProps } from 'redux-form';
import { TreePickerId } from '~/models/tree';
+import { ProjectsTreePicker } from '~/views-components/projects-tree-picker/projects-tree-picker';
+import { ProjectsTreePickerItem } from '~/views-components/projects-tree-picker/generic-projects-tree-picker';
+import { PickerIdProp } from '~/store/tree-picker/picker-id';
type ProjectTreePickerProps = Pick<TreePickerProps<ProjectResource>, 'onContextMenu' | 'toggleItemActive' | 'toggleItemOpen' | 'toggleItemSelection'>;
isActive={item.active}
hasMargin={true} />;
-export const ProjectTreePickerField = (props: WrappedFieldProps) =>
+export const ProjectTreePickerField = (props: WrappedFieldProps & PickerIdProp) =>
<div style={{ height: '200px', display: 'flex', flexDirection: 'column' }}>
- <ProjectTreePicker onChange={handleChange(props)} />
+ <ProjectsTreePicker
+ pickerId={props.pickerId}
+ toggleItemActive={handleChange(props)} />
{props.meta.dirty && props.meta.error &&
<Typography variant='caption' color='error'>
{props.meta.error}
</Typography>}
</div>;
-const handleChange = (props: WrappedFieldProps) => (value: string) =>
- props.input.value === value
- ? props.input.onChange('')
- : props.input.onChange(value);
-
+const handleChange = (props: WrappedFieldProps) =>
+ (_: any, { id }: TreeItem<ProjectsTreePickerItem>) =>
+ props.input.onChange(id);
import * as React from "react";
import { Dispatch } from "redux";
import { connect } from "react-redux";
+import { isEqual } from 'lodash/fp';
import { TreeItem, TreeItemStatus } from '~/components/tree/tree';
import { ProjectResource } from "~/models/project";
import { treePickerActions } from "~/store/tree-picker/tree-picker-actions";
rootItemIcon: IconType;
showSelection?: boolean;
relatedTreePickers?: string[];
+ disableActivation?: string[];
loadRootItem: (item: TreeItem<ProjectsTreePickerRootItem>, pickerId: string, includeCollections?: boolean, inlcudeFiles?: boolean) => void;
}
const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollections, includeFiles, relatedTreePickers, ...props }: ProjectsTreePickerProps): PickedTreePickerProps => ({
onContextMenu: () => { return; },
toggleItemActive: (event, item, pickerId) => {
+
+ const { disableActivation = [] } = props;
+ if(disableActivation.some(isEqual(item.id))){
+ return;
+ }
+
dispatch(treePickerActions.ACTIVATE_TREE_PICKER_NODE({ id: item.id, pickerId, relatedTreePickers }));
if (props.toggleItemActive) {
props.toggleItemActive(event, item, pickerId);
// SPDX-License-Identifier: AGPL-3.0
import * as React from 'react';
-import { values, memoize, pipe } from 'lodash/fp';
+import { values, memoize, pipe, pick } from 'lodash/fp';
import { HomeTreePicker } from '~/views-components/projects-tree-picker/home-tree-picker';
import { SharedTreePicker } from '~/views-components/projects-tree-picker/shared-tree-picker';
import { FavoritesTreePicker } from '~/views-components/projects-tree-picker/favorites-tree-picker';
-import { getProjectsTreePickerIds } from '~/store/tree-picker/tree-picker-actions';
+import { getProjectsTreePickerIds, SHARED_PROJECT_ID, FAVORITES_PROJECT_ID } from '~/store/tree-picker/tree-picker-actions';
import { TreeItem } from '~/components/tree/tree';
import { ProjectsTreePickerItem } from './generic-projects-tree-picker';
export const ProjectsTreePicker = ({ pickerId, ...props }: ProjectsTreePickerProps) => {
const { home, shared, favorites } = getProjectsTreePickerIds(pickerId);
const relatedTreePickers = getRelatedTreePickers(pickerId);
+ const p = {
+ ...props,
+ relatedTreePickers,
+ disableActivation
+ };
return <div>
- <HomeTreePicker pickerId={home} {...props} {...{ relatedTreePickers }} />
- <SharedTreePicker pickerId={shared} {...props} {...{ relatedTreePickers }} />
- <FavoritesTreePicker pickerId={favorites} {...props} {...{ relatedTreePickers }} />
+ <HomeTreePicker pickerId={home} {...p} />
+ <SharedTreePicker pickerId={shared} {...p} />
+ <FavoritesTreePicker pickerId={favorites} {...p} />
</div>;
};
const getRelatedTreePickers = memoize(pipe(getProjectsTreePickerIds, values));
+const disableActivation = [SHARED_PROJECT_ID, FAVORITES_PROJECT_ID];