export interface ConfirmationDialogDataProps {
title: string;
text: string;
+ info?: string;
cancelButtonLabel?: string;
confirmButtonLabel?: string;
}
<DialogContent style={{ display: 'flex', alignItems: 'center' }}>
<WarningIcon />
<DialogContentText style={{ paddingLeft: '8px' }}>
- {props.data.text}
- <br />
- {props.data.title === 'Removing file' ? 'Removing a file will change content adress.' : 'Removing files will change content adress.'}
+ <div>{props.data.text}</div>
+ <div>{props.data.info}</div>
</DialogContentText>
</DialogContent>
<DialogActions>
(dispatch: Dispatch, getState: () => RootState) => {
const file = getNodeValue(filePath)(getState().collectionPanelFiles);
if (file) {
- const title = file.type === CollectionFileType.DIRECTORY
+ const isDirectory = file.type === CollectionFileType.DIRECTORY;
+ const title = isDirectory
? 'Removing directory'
: 'Removing file';
- const text = file.type === CollectionFileType.DIRECTORY
+ const text = isDirectory
? 'Are you sure you want to remove this directory?'
: 'Are you sure you want to remove this file?';
+ const info = isDirectory
+ ? 'Removing files will change content adress.'
+ : 'Removing a file will change content adress.';
dispatch(dialogActions.OPEN_DIALOG({
id: FILE_REMOVE_DIALOG,
data: {
title,
text,
+ info,
confirmButtonLabel: 'Remove',
filePath
}
data: {
title: 'Removing files',
text: 'Are you sure you want to remove selected files?',
+ info: 'Removing files will change content adress.',
confirmButtonLabel: 'Remove'
}
});
import { RunProcessAdvancedFormData, RUN_PROCESS_ADVANCED_FORM } from '~/views/run-process-panel/run-process-advanced-form';
import { isItemNotInProject, isProjectOrRunProcessRoute } from '~/store/projects/project-create-actions';
import { matchProjectRoute } from '~/routes/routes';
+import { dialogActions } from '~/store/dialog/dialog-actions';
+import * as uuid from 'uuid/v4';
export const runProcessPanelActions = unionize({
SET_PROCESS_OWNER_UUID: ofType<string>(),
SET_CURRENT_STEP: ofType<number>(),
+ SET_STEP_CHANGED: ofType<boolean>(),
SET_WORKFLOWS: ofType<WorkflowResource[]>(),
SET_SELECTED_WORKFLOW: ofType<WorkflowResource>(),
SEARCH_WORKFLOWS: ofType<string>(),
description: string;
}
+export const SET_WORKFLOW_DIALOG = 'setWorkflowDialog';
export const RUN_PROCESS_SECOND_STEP_FORM_NAME = 'runProcessSecondStepFormName';
export type RunProcessPanelAction = UnionOf<typeof runProcessPanelActions>;
}
};
-export const setWorkflow = (workflow: WorkflowResource) =>
- async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
- dispatch(runProcessPanelActions.SET_SELECTED_WORKFLOW(workflow));
+export const openSetWorkflowDialog = (workflow: WorkflowResource) =>
+ (dispatch: Dispatch, getState: () => RootState) => {
+ const selectedWorkflow = getState().runProcessPanel.selectedWorkflow;
+ const isStepChanged = getState().runProcessPanel.isStepChanged;
+ if (isStepChanged && selectedWorkflow && selectedWorkflow.uuid !== workflow.uuid) {
+ dispatch(dialogActions.OPEN_DIALOG({
+ id: SET_WORKFLOW_DIALOG,
+ data: {
+ title: 'Data loss warning',
+ text: 'Changing a workflow will clean all input fields in next step.',
+ confirmButtonLabel: 'Change Workflow',
+ workflow
+ }
+ }));
+ } else {
+ dispatch<any>(setWorkflow(workflow, false));
+ }
};
-export const goToStep = (step: number) => runProcessPanelActions.SET_CURRENT_STEP(step);
+export const setWorkflow = (workflow: WorkflowResource, isWorkflowChanged = true) =>
+ (dispatch: Dispatch<any>, getState: () => RootState) => {
+ const isStepChanged = getState().runProcessPanel.isStepChanged;
+ if (isStepChanged && isWorkflowChanged) {
+ dispatch(runProcessPanelActions.SET_STEP_CHANGED(false));
+ dispatch(runProcessPanelActions.SET_SELECTED_WORKFLOW(workflow));
+ }
+ if (!isWorkflowChanged) {
+ dispatch(runProcessPanelActions.SET_SELECTED_WORKFLOW(workflow));
+ }
+ };
-const isRunProcessRoute = ({ router }: RootState) => {
- const pathname = router.location ? router.location.pathname : '';
- const match = matchProjectRoute(pathname);
- return !!match;
-};
+export const goToStep = (step: number) =>
+ (dispatch: Dispatch, getState: () => RootState) => {
+ if (step === 1) {
+ dispatch(runProcessPanelActions.SET_STEP_CHANGED(true));
+ }
+ dispatch(runProcessPanelActions.SET_CURRENT_STEP(step));
+ };
export const runProcess = async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
const state = getState();
interface RunProcessPanel {
processOwnerUuid: string;
currentStep: number;
+ isStepChanged: boolean;
workflows: WorkflowResource[];
searchWorkflows: WorkflowResource[];
selectedWorkflow: WorkflowResource | undefined;
const initialState: RunProcessPanel = {
processOwnerUuid: '',
currentStep: 0,
+ isStepChanged: false,
workflows: [],
selectedWorkflow: undefined,
inputs: [],
runProcessPanelActions.match(action, {
SET_PROCESS_OWNER_UUID: processOwnerUuid => ({ ...state, processOwnerUuid }),
SET_CURRENT_STEP: currentStep => ({ ...state, currentStep }),
+ SET_STEP_CHANGED: isStepChanged => ({ ...state, isStepChanged }),
SET_SELECTED_WORKFLOW: selectedWorkflow => ({
...state,
selectedWorkflow,
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from "redux";
+import { connect } from "react-redux";
+import { RootState } from '~/store/store';
+import { setWorkflow, SET_WORKFLOW_DIALOG } from '~/store/run-process-panel/run-process-panel-actions';
+import { ConfirmationDialog } from "~/components/confirmation-dialog/confirmation-dialog";
+import { withDialog, WithDialogProps } from "~/store/dialog/with-dialog";
+import { WorkflowResource } from '~/models/workflow';
+
+const mapStateToProps = (state: RootState, props: WithDialogProps<{ workflow: WorkflowResource }>) => ({
+ workflow: props.data.workflow
+});
+
+const mapDispatchToProps = (dispatch: Dispatch, props: WithDialogProps<any>) => ({
+ onConfirm: (workflow: WorkflowResource) => {
+ props.closeDialog();
+ dispatch<any>(setWorkflow(workflow));
+ }
+});
+
+const mergeProps = (
+ stateProps: { workflow: WorkflowResource },
+ dispatchProps: { onConfirm: (workflow: WorkflowResource) => void },
+ props: WithDialogProps<{ workflow: WorkflowResource }>) => ({
+ onConfirm: () => dispatchProps.onConfirm(stateProps.workflow),
+ ...props
+ });
+
+export const [ChangeWorkflowDialog] = [ConfirmationDialog]
+ .map(connect(mapStateToProps, mapDispatchToProps, mergeProps) as any)
+ .map(withDialog(SET_WORKFLOW_DIALOG));
\ No newline at end of file
import { connect } from 'react-redux';
import { RootState } from '~/store/store';
import { RunProcessPanelRootDataProps, RunProcessPanelRootActionProps, RunProcessPanelRoot } from '~/views/run-process-panel/run-process-panel-root';
-import { goToStep, setWorkflow, runProcess, searchWorkflows } from '~/store/run-process-panel/run-process-panel-actions';
+import { goToStep, setWorkflow, runProcess, searchWorkflows, openSetWorkflowDialog } from '~/store/run-process-panel/run-process-panel-actions';
import { WorkflowResource } from '~/models/workflow';
const mapStateToProps = ({ runProcessPanel }: RootState): RunProcessPanelRootDataProps => {
dispatch<any>(goToStep(step));
},
onSetWorkflow: (workflow: WorkflowResource) => {
- dispatch<any>(setWorkflow(workflow));
+ dispatch<any>(openSetWorkflowDialog(workflow));
},
runProcess: () => {
dispatch<any>(runProcess);
import { SidePanel } from '~/views-components/side-panel/side-panel';
import { ProcessPanel } from '~/views/process-panel/process-panel';
import { ProcessLogPanel } from '~/views/process-log-panel/process-log-panel';
+import { ChangeWorkflowDialog } from '~/views-components/run-process-dialog/change-workflow-dialog';
import { CreateProjectDialog } from '~/views-components/dialog-forms/create-project-dialog';
import { CreateCollectionDialog } from '~/views-components/dialog-forms/create-collection-dialog';
import { CopyCollectionDialog } from '~/views-components/dialog-forms/copy-collection-dialog';
<DetailsPanel />
</Grid>
<AdvancedTabDialog />
+ <ChangeWorkflowDialog />
<ContextMenu />
<CopyCollectionDialog />
<CopyProcessDialog />