[ARVADOS-WORKBENCH2] created: 1.2.0-320-g8805314
Git user
git at public.curoverse.com
Fri Sep 7 09:50:44 EDT 2018
at 8805314e7327cda30d455d0c05075ee37f3a490e (commit)
commit 8805314e7327cda30d455d0c05075ee37f3a490e
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Fri Sep 7 15:50:24 2018 +0200
14096-move-to-process
Feature #14096
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
diff --git a/src/index.tsx b/src/index.tsx
index a921b47..8ab089a 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -35,6 +35,7 @@ import { ServiceRepository } from '~/services/services';
import { initWebSocket } from '~/websocket/websocket';
import { Config } from '~/common/config';
import { addRouteChangeHandlers } from './routes/route-change-handlers';
+import { processResourceActionSet } from './views-components/context-menu/action-sets/process-resource-action-set';
const getBuildNumber = () => "BN-" + (process.env.REACT_APP_BUILD_NUMBER || "dev");
const getGitCommit = () => "GIT-" + (process.env.REACT_APP_GIT_COMMIT || "latest").substr(0, 7);
@@ -53,6 +54,7 @@ addMenuActionSet(ContextMenuKind.COLLECTION_FILES_ITEM, collectionFilesItemActio
addMenuActionSet(ContextMenuKind.COLLECTION, collectionActionSet);
addMenuActionSet(ContextMenuKind.COLLECTION_RESOURCE, collectionResourceActionSet);
addMenuActionSet(ContextMenuKind.PROCESS, processActionSet);
+addMenuActionSet(ContextMenuKind.PROCESS_RESOURCE, processResourceActionSet);
addMenuActionSet(ContextMenuKind.TRASH, trashActionSet);
fetchConfig()
diff --git a/src/routes/routes.ts b/src/routes/routes.ts
index f108e0b..29941b4 100644
--- a/src/routes/routes.ts
+++ b/src/routes/routes.ts
@@ -25,6 +25,8 @@ export const getResourceUrl = (uuid: string) => {
return getProjectUrl(uuid);
case ResourceKind.COLLECTION:
return getCollectionUrl(uuid);
+ case ResourceKind.PROCESS:
+ return getProcessUrl(uuid);
default:
return undefined;
}
diff --git a/src/services/common-service/common-resource-service.ts b/src/services/common-service/common-resource-service.ts
index 7b36b71..abc856f 100644
--- a/src/services/common-service/common-resource-service.ts
+++ b/src/services/common-service/common-resource-service.ts
@@ -32,6 +32,7 @@ export interface Errors {
export enum CommonResourceServiceError {
UNIQUE_VIOLATION = 'UniqueViolation',
OWNERSHIP_CYCLE = 'OwnershipCycle',
+ MODIFYING_CONTAINER_REQUEST_FINAL_STATE = 'ModifyingFinalState',
UNKNOWN = 'Unknown',
NONE = 'None'
}
@@ -121,6 +122,8 @@ export const getCommonResourceServiceError = (errorResponse: any) => {
return CommonResourceServiceError.UNIQUE_VIOLATION;
case /ownership cycle/.test(error):
return CommonResourceServiceError.OWNERSHIP_CYCLE;
+ case /Mounts cannot be modified in state 'Final'/.test(error):
+ return CommonResourceServiceError.MODIFYING_CONTAINER_REQUEST_FINAL_STATE;
default:
return CommonResourceServiceError.UNKNOWN;
}
diff --git a/src/store/context-menu/context-menu-actions.ts b/src/store/context-menu/context-menu-actions.ts
index bb404b8..eabf41a 100644
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@ -88,7 +88,7 @@ export const openProcessContextMenu = (event: React.MouseEvent<HTMLElement>) =>
(dispatch: Dispatch, getState: () => RootState) => {
const { location } = getState().router;
const pathname = location ? location.pathname : '';
- const match = matchProcessRoute(pathname);
+ const match = matchProcessRoute(pathname);
const uuid = match ? match.params.id : '';
const resource = {
uuid,
@@ -108,6 +108,8 @@ export const resourceKindToContextMenuKind = (uuid: string) => {
return ContextMenuKind.PROJECT;
case ResourceKind.COLLECTION:
return ContextMenuKind.COLLECTION_RESOURCE;
+ case ResourceKind.PROCESS:
+ return ContextMenuKind.PROCESS_RESOURCE;
case ResourceKind.USER:
return ContextMenuKind.ROOT_PROJECT;
default:
diff --git a/src/store/processes/process-move-actions.ts b/src/store/processes/process-move-actions.ts
new file mode 100644
index 0000000..d59cdca
--- /dev/null
+++ b/src/store/processes/process-move-actions.ts
@@ -0,0 +1,57 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from "redux";
+import { dialogActions } from "~/store/dialog/dialog-actions";
+import { startSubmit, stopSubmit, initialize } from 'redux-form';
+import { ServiceRepository } from '~/services/services';
+import { RootState } from '~/store/store';
+import { getCommonResourceServiceError, CommonResourceServiceError } from "~/services/common-service/common-resource-service";
+import { snackbarActions } from '~/store/snackbar/snackbar-actions';
+import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
+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';
+
+export const PROCESS_MOVE_FORM_NAME = 'processMoveFormName';
+
+export const openMoveProcessDialog = (resource: { name: string, uuid: string }) =>
+ (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ const process = getProcess(resource.uuid)(getState().resources);
+ if (process) {
+ const processStatus = getProcessStatus(process);
+ if (processStatus === ProcessStatus.DRAFT) {
+ dispatch<any>(resetPickerProjectTree());
+ dispatch(initialize(PROCESS_MOVE_FORM_NAME, resource));
+ dispatch(dialogActions.OPEN_DIALOG({ id: PROCESS_MOVE_FORM_NAME, data: {} }));
+ } else {
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'You can move only draft processes.', hideDuration: 2000 }));
+ }
+ }
+ };
+
+export const moveProcess = (resource: MoveToFormDialogData) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ dispatch(startSubmit(PROCESS_MOVE_FORM_NAME));
+ try {
+ const process = await services.containerRequestService.get(resource.uuid);
+ await services.containerRequestService.update(resource.uuid, { ...process, ownerUuid: resource.ownerUuid });
+ dispatch(projectPanelActions.REQUEST_ITEMS());
+ dispatch(dialogActions.CLOSE_DIALOG({ id: PROCESS_MOVE_FORM_NAME }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Process has been moved', hideDuration: 2000 }));
+ return process;
+ } catch (e) {
+ const error = getCommonResourceServiceError(e);
+ if (error === CommonResourceServiceError.UNIQUE_VIOLATION) {
+ dispatch(stopSubmit(PROCESS_MOVE_FORM_NAME, { ownerUuid: 'A process with the same name already exists in the target project.' }));
+ } else if (error === CommonResourceServiceError.MODIFYING_CONTAINER_REQUEST_FINAL_STATE) {
+ dispatch(stopSubmit(PROCESS_MOVE_FORM_NAME, { ownerUuid: 'You can move only uncommitted process.' }));
+ }
+ else {
+ dispatch(dialogActions.CLOSE_DIALOG({ id: PROCESS_MOVE_FORM_NAME }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Could not move the process.', hideDuration: 2000 }));
+ }
+ return;
+ }
+ };
\ No newline at end of file
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 036f4a3..cb65c24 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -29,6 +29,7 @@ import * as collectionCopyActions from '~/store/collections/collection-copy-acti
import * as collectionUpdateActions from '~/store/collections/collection-update-actions';
import * as collectionMoveActions from '~/store/collections/collection-move-actions';
import * as processesActions from '../processes/processes-actions';
+import * as processMoveActions from '~/store/processes/process-move-actions';
import { trashPanelColumns } from "~/views/trash-panel/trash-panel";
import { loadTrashPanel, trashPanelActions } from "~/store/trash-panel/trash-panel-action";
import { initProcessLogsPanel } from '../process-logs-panel/process-logs-panel-actions';
@@ -191,7 +192,19 @@ export const loadProcess = (uuid: string) =>
await dispatch<any>(activateSidePanelTreeItem(process.containerRequest.ownerUuid));
dispatch<any>(setProcessBreadcrumbs(uuid));
dispatch(loadDetailsPanel(uuid));
-
+
+ };
+
+export const moveProcess = (data: MoveToFormDialogData) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ try {
+ const process = await dispatch<any>(processMoveActions.moveProcess(data));
+ dispatch<any>(updateResources([process]));
+ dispatch<any>(reloadProjectMatchingUuid([process.ownerUuid]));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Process has been moved.', hideDuration: 2000 }));
+ } catch (e) {
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.message, hideDuration: 2000 }));
+ }
};
export const loadProcessLog = (uuid: string) =>
diff --git a/src/views-components/context-menu/action-sets/process-action-set.ts b/src/views-components/context-menu/action-sets/process-action-set.ts
index 2897455..3a824ec 100644
--- a/src/views-components/context-menu/action-sets/process-action-set.ts
+++ b/src/views-components/context-menu/action-sets/process-action-set.ts
@@ -11,6 +11,7 @@ import {
} from "~/components/icon/icon";
import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
import { navigateToProcessLogs } from '~/store/navigation/navigation-action';
+import { openMoveProcessDialog } from '~/store/processes/process-move-actions';
export const processActionSet: ContextMenuActionSet = [[
{
@@ -30,9 +31,7 @@ export const processActionSet: ContextMenuActionSet = [[
{
icon: MoveToIcon,
name: "Move to",
- execute: (dispatch, resource) => {
- // add code
- }
+ execute: (dispatch, resource) => dispatch<any>(openMoveProcessDialog(resource))
},
{
component: ToggleFavoriteAction,
diff --git a/src/views-components/context-menu/action-sets/process-resource-action-set.ts b/src/views-components/context-menu/action-sets/process-resource-action-set.ts
new file mode 100644
index 0000000..64e30f7
--- /dev/null
+++ b/src/views-components/context-menu/action-sets/process-resource-action-set.ts
@@ -0,0 +1,61 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ContextMenuActionSet } from "../context-menu-action-set";
+import { ToggleFavoriteAction } from "../actions/favorite-action";
+import { toggleFavorite } from "~/store/favorites/favorites-actions";
+import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, RemoveIcon } from "~/components/icon/icon";
+import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
+import { openMoveProcessDialog } from '~/store/processes/process-move-actions';
+
+export const processResourceActionSet: ContextMenuActionSet = [[
+ {
+ icon: RenameIcon,
+ name: "Edit process",
+ execute: (dispatch, resource) => {
+ // add code
+ }
+ },
+ {
+ icon: ShareIcon,
+ name: "Share",
+ execute: (dispatch, resource) => {
+ // add code
+ }
+ },
+ {
+ icon: MoveToIcon,
+ name: "Move to",
+ execute: (dispatch, resource) => dispatch<any>(openMoveProcessDialog(resource))
+ },
+ {
+ component: ToggleFavoriteAction,
+ execute: (dispatch, resource) => {
+ dispatch<any>(toggleFavorite(resource)).then(() => {
+ dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
+ });
+ }
+ },
+ {
+ icon: CopyIcon,
+ name: "Copy to project",
+ execute: (dispatch, resource) => {
+ // add code
+ }
+ },
+ {
+ icon: DetailsIcon,
+ name: "View details",
+ execute: (dispatch, resource) => {
+ // add code
+ }
+ },
+ {
+ icon: RemoveIcon,
+ name: "Remove",
+ execute: (dispatch, resource) => {
+ // add code
+ }
+ }
+]];
diff --git a/src/views-components/context-menu/context-menu.tsx b/src/views-components/context-menu/context-menu.tsx
index a545b2b..d5c82be 100644
--- a/src/views-components/context-menu/context-menu.tsx
+++ b/src/views-components/context-menu/context-menu.tsx
@@ -65,5 +65,6 @@ export enum ContextMenuKind {
COLLECTION = 'Collection',
COLLECTION_RESOURCE = 'CollectionResource',
PROCESS = "Process",
+ PROCESS_RESOURCE = 'ProcessResource',
PROCESS_LOGS = "ProcessLogs"
}
diff --git a/src/views-components/dialog-forms/move-process-dialog.ts b/src/views-components/dialog-forms/move-process-dialog.ts
new file mode 100644
index 0000000..baea34b
--- /dev/null
+++ b/src/views-components/dialog-forms/move-process-dialog.ts
@@ -0,0 +1,21 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { compose } from 'redux';
+import { withDialog } from "~/store/dialog/with-dialog";
+import { reduxForm } from 'redux-form';
+import { PROCESS_MOVE_FORM_NAME } from '~/store/processes/process-move-actions';
+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';
+
+export const MoveProcessDialog = compose(
+ withDialog(PROCESS_MOVE_FORM_NAME),
+ reduxForm<MoveToFormDialogData>({
+ form: PROCESS_MOVE_FORM_NAME,
+ onSubmit: (data, dispatch) => {
+ dispatch(moveProcess(data));
+ }
+ })
+)(DialogMoveTo);
\ No newline at end of file
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index 3c28108..f202b69 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -34,11 +34,11 @@ import { CreateCollectionDialog } from '~/views-components/dialog-forms/create-c
import { CopyCollectionDialog } from '~/views-components/dialog-forms/copy-collection-dialog';
import { UpdateCollectionDialog } from '~/views-components/dialog-forms/update-collection-dialog';
import { UpdateProjectDialog } from '~/views-components/dialog-forms/update-project-dialog';
+import { MoveProcessDialog } from '~/views-components/dialog-forms/move-process-dialog';
import { MoveProjectDialog } from '~/views-components/dialog-forms/move-project-dialog';
import { MoveCollectionDialog } from '~/views-components/dialog-forms/move-collection-dialog';
import { FilesUploadCollectionDialog } from '~/views-components/dialog-forms/files-upload-collection-dialog';
import { PartialCopyCollectionDialog } from '~/views-components/dialog-forms/partial-copy-collection-dialog';
-
import { TrashPanel } from "~/views/trash-panel/trash-panel";
const APP_BAR_HEIGHT = 100;
@@ -189,6 +189,7 @@ export const Workbench = withStyles(styles)(
<FilesUploadCollectionDialog />
<UpdateProjectDialog />
<MoveCollectionDialog />
+ <MoveProcessDialog />
<MoveProjectDialog />
<CurrentTokenDialog
currentToken={this.props.currentToken}
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list