mirror of
https://github.com/sartography/spiff-arena.git
synced 2025-02-23 06:38:24 +00:00
more updates for pi show page w/ burnettk
This commit is contained in:
parent
cb38a5ec76
commit
c30b248572
@ -0,0 +1,62 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
import { Tabs, Tab } from '@mui/material';
|
||||||
|
import { Can } from '@casl/react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { usePermissionFetcher } from '../hooks/PermissionService';
|
||||||
|
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
||||||
|
import { PermissionsToCheck } from '../interfaces';
|
||||||
|
import SpiffTooltip from './SpiffTooltip';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
variant: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ProcessInstanceListTabs({ variant }: OwnProps) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { targetUris } = useUriListForPermissions();
|
||||||
|
const permissionRequestData: PermissionsToCheck = {
|
||||||
|
[targetUris.processInstanceListPath]: ['GET'],
|
||||||
|
};
|
||||||
|
const { ability } = usePermissionFetcher(permissionRequestData);
|
||||||
|
|
||||||
|
let selectedTabIndex = 0;
|
||||||
|
if (variant === 'all') {
|
||||||
|
selectedTabIndex = 1;
|
||||||
|
} else if (variant === 'find-by-id') {
|
||||||
|
selectedTabIndex = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tabs value={selectedTabIndex} aria-label="List of tabs">
|
||||||
|
<SpiffTooltip title="Only show process instances for the current user">
|
||||||
|
<Tab
|
||||||
|
label="For Me"
|
||||||
|
data-qa="process-instance-list-for-me"
|
||||||
|
onClick={() => {
|
||||||
|
navigate('/process-instances/for-me');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SpiffTooltip>
|
||||||
|
<Can I="GET" a={targetUris.processInstanceListPath} ability={ability}>
|
||||||
|
<SpiffTooltip title="Show process instances for all users">
|
||||||
|
<Tab
|
||||||
|
label="All"
|
||||||
|
data-qa="process-instance-list-all"
|
||||||
|
onClick={() => {
|
||||||
|
navigate('/process-instances/all');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SpiffTooltip>
|
||||||
|
</Can>
|
||||||
|
<SpiffTooltip title="Search for a process instance by id">
|
||||||
|
<Tab
|
||||||
|
label="Find By Id"
|
||||||
|
data-qa="process-instance-list-find-by-id"
|
||||||
|
onClick={() => {
|
||||||
|
navigate('/process-instances/find-by-id');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SpiffTooltip>
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
}
|
@ -83,9 +83,9 @@ export default function ProcessInstanceLogList({
|
|||||||
shouldDisplayClearButton = true;
|
shouldDisplayClearButton = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let processInstanceShowPageBaseUrl = `/process-instances/for-me/${processModelId}`;
|
let processInstanceShowPageBaseUrl = `/newui/process-instances/for-me/${processModelId}`;
|
||||||
if (variant === 'all') {
|
if (variant === 'all') {
|
||||||
processInstanceShowPageBaseUrl = `/process-instances/${processModelId}`;
|
processInstanceShowPageBaseUrl = `/newui/process-instances/${processModelId}`;
|
||||||
}
|
}
|
||||||
const taskNameHeader = isEventsView ? 'Task name' : 'Milestone';
|
const taskNameHeader = isEventsView ? 'Task name' : 'Milestone';
|
||||||
const tableType = isEventsView ? 'events' : 'milestones';
|
const tableType = isEventsView ? 'events' : 'milestones';
|
||||||
@ -516,17 +516,11 @@ export default function ProcessInstanceLogList({
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid container spacing={2} className="with-bottom-margin">
|
<Grid container spacing={2} className="with-bottom-margin">
|
||||||
<Grid item sm={4} md={4} lg={8}>
|
<Grid item sm={4} md={4} lg={8}>
|
||||||
<Button
|
<Button variant="outlined" onClick={resetFiltersAndRun}>
|
||||||
variant="outlined"
|
|
||||||
onClick={resetFiltersAndRun}
|
|
||||||
>
|
|
||||||
Reset
|
Reset
|
||||||
</Button>
|
</Button>
|
||||||
{shouldDisplayClearButton && (
|
{shouldDisplayClearButton && (
|
||||||
<Button
|
<Button variant="outlined" onClick={clearFilters}>
|
||||||
variant="outlined"
|
|
||||||
onClick={clearFilters}
|
|
||||||
>
|
|
||||||
Clear
|
Clear
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
@ -221,7 +221,7 @@ export default function TaskListTable({
|
|||||||
<td>
|
<td>
|
||||||
<Link
|
<Link
|
||||||
data-qa="process-instance-show-link-id"
|
data-qa="process-instance-show-link-id"
|
||||||
to={`/process-instances/for-me/${modifiedProcessModelIdentifier}/${processInstanceTask.process_instance_id}`}
|
to={`/newui/process-instances/for-me/${modifiedProcessModelIdentifier}/${processInstanceTask.process_instance_id}`}
|
||||||
title={`View process instance ${processInstanceTask.process_instance_id}`}
|
title={`View process instance ${processInstanceTask.process_instance_id}`}
|
||||||
>
|
>
|
||||||
{processInstanceTask.process_instance_id}
|
{processInstanceTask.process_instance_id}
|
||||||
@ -246,7 +246,7 @@ export default function TaskListTable({
|
|||||||
<td>
|
<td>
|
||||||
<Link
|
<Link
|
||||||
data-qa="process-model-show-link"
|
data-qa="process-model-show-link"
|
||||||
to={`/process-models/${modifiedProcessModelIdentifier}`}
|
to={`/newui/process-models/${modifiedProcessModelIdentifier}`}
|
||||||
title={processInstanceTask.process_model_identifier}
|
title={processInstanceTask.process_model_identifier}
|
||||||
>
|
>
|
||||||
{processInstanceTask.process_model_display_name}
|
{processInstanceTask.process_model_display_name}
|
||||||
@ -257,7 +257,7 @@ export default function TaskListTable({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getActionButtons = (processInstanceTask: ProcessInstanceTask) => {
|
const getActionButtons = (processInstanceTask: ProcessInstanceTask) => {
|
||||||
const taskUrl = `/tasks/${processInstanceTask.process_instance_id}/${processInstanceTask.task_id}`;
|
const taskUrl = `/newui/tasks/${processInstanceTask.process_instance_id}/${processInstanceTask.task_id}`;
|
||||||
const regex = new RegExp(`\\b(${preferredUsername}|${userEmail})\\b`);
|
const regex = new RegExp(`\\b(${preferredUsername}|${userEmail})\\b`);
|
||||||
let hasAccessToCompleteTask = false;
|
let hasAccessToCompleteTask = false;
|
||||||
if (
|
if (
|
||||||
|
@ -16,7 +16,7 @@ export default function useProcessInstanceNavigate() {
|
|||||||
suffix: string | undefined,
|
suffix: string | undefined,
|
||||||
) => {
|
) => {
|
||||||
const processInstanceResult: ProcessInstance = result.process_instance;
|
const processInstanceResult: ProcessInstance = result.process_instance;
|
||||||
let path = '/process-instances';
|
let path = '/newui/process-instances';
|
||||||
if (result.uri_type === 'for-me') {
|
if (result.uri_type === 'for-me') {
|
||||||
path += '/for-me';
|
path += '/for-me';
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { Button, TextField, Box } from '@mui/material';
|
||||||
|
import { isANumber, modifyProcessIdentifierForPathParam } from '../helpers';
|
||||||
|
import HttpService from '../services/HttpService';
|
||||||
|
import ProcessInstanceListTabs from '../components/ProcessInstanceListTabs';
|
||||||
|
import { ProcessInstance } from '../interfaces';
|
||||||
|
|
||||||
|
export default function ProcessInstanceFindById() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [processInstanceId, setProcessInstanceId] = useState<string>('');
|
||||||
|
const [processInstanceIdValid, setProcessInstanceIdValid] =
|
||||||
|
useState<boolean>(true);
|
||||||
|
|
||||||
|
useEffect(() => {}, []);
|
||||||
|
|
||||||
|
const handleProcessInstanceNavigation = (result: any) => {
|
||||||
|
const processInstance: ProcessInstance = result.process_instance;
|
||||||
|
let path = '/process-instances/';
|
||||||
|
if (result.uri_type === 'for-me') {
|
||||||
|
path += 'for-me/';
|
||||||
|
}
|
||||||
|
path += `${modifyProcessIdentifierForPathParam(
|
||||||
|
processInstance.process_model_identifier,
|
||||||
|
)}/${processInstance.id}`;
|
||||||
|
navigate(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFormSubmission = (event: any) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (!processInstanceId) {
|
||||||
|
setProcessInstanceIdValid(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processInstanceId && processInstanceIdValid) {
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: `/process-instances/find-by-id/${processInstanceId}`,
|
||||||
|
successCallback: handleProcessInstanceNavigation,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleProcessInstanceIdChange = (event: any) => {
|
||||||
|
if (isANumber(event.target.value)) {
|
||||||
|
setProcessInstanceIdValid(true);
|
||||||
|
} else {
|
||||||
|
setProcessInstanceIdValid(false);
|
||||||
|
}
|
||||||
|
setProcessInstanceId(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formElements = () => {
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
id="process-instance-id-input"
|
||||||
|
error={!processInstanceIdValid}
|
||||||
|
helperText={
|
||||||
|
!processInstanceIdValid ? 'Process Instance Id must be a number.' : ''
|
||||||
|
}
|
||||||
|
label="Process Instance Id*"
|
||||||
|
value={processInstanceId}
|
||||||
|
onChange={handleProcessInstanceIdChange}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formButtons = () => {
|
||||||
|
return (
|
||||||
|
<Button type="submit" variant="contained">
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ProcessInstanceListTabs variant="find-by-id" />
|
||||||
|
<br />
|
||||||
|
<Box component="form" onSubmit={handleFormSubmission} sx={{ mt: 1 }}>
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||||
|
{formElements()}
|
||||||
|
{formButtons()}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,386 @@
|
|||||||
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
Alert,
|
||||||
|
AlertTitle,
|
||||||
|
CircularProgress,
|
||||||
|
Typography,
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogContentText,
|
||||||
|
DialogTitle,
|
||||||
|
} from '@mui/material';
|
||||||
|
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||||
|
|
||||||
|
import { green } from '@mui/material/colors';
|
||||||
|
import { DataGrid } from '@mui/x-data-grid';
|
||||||
|
import HttpService from '../services/HttpService';
|
||||||
|
|
||||||
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
||||||
|
import { MigrationEvent, MigrationCheckResult } from '../interfaces';
|
||||||
|
import CellRenderer from '../components/CellRenderer';
|
||||||
|
|
||||||
|
function DangerousMigrationButton({
|
||||||
|
successCallback,
|
||||||
|
failureCallback,
|
||||||
|
targetBpmnProcessHash,
|
||||||
|
title,
|
||||||
|
buttonText = 'Migrate to Newest',
|
||||||
|
}: {
|
||||||
|
successCallback: (result: any) => void;
|
||||||
|
failureCallback: (error: any) => void;
|
||||||
|
title?: string;
|
||||||
|
targetBpmnProcessHash?: string;
|
||||||
|
buttonText?: string;
|
||||||
|
}) {
|
||||||
|
const params = useParams();
|
||||||
|
const [openDialog, setOpenDialog] = useState(false);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const { targetUris } = useUriListForPermissions();
|
||||||
|
const [migrationCheckResult, setMigrationCheckResult] =
|
||||||
|
useState<MigrationCheckResult | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let queryParams = '';
|
||||||
|
if (targetBpmnProcessHash) {
|
||||||
|
queryParams = `?target_bpmn_process_hash=${targetBpmnProcessHash}`;
|
||||||
|
}
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: `/process-instances/${params.process_model_id}/${params.process_instance_id}/check-can-migrate${queryParams}`,
|
||||||
|
successCallback: (result: any) => setMigrationCheckResult(result),
|
||||||
|
});
|
||||||
|
}, [
|
||||||
|
targetBpmnProcessHash,
|
||||||
|
params.process_model_id,
|
||||||
|
params.process_instance_id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const handleRunMigration = () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
let queryParams = '';
|
||||||
|
if (targetBpmnProcessHash) {
|
||||||
|
queryParams = `?target_bpmn_process_hash=${targetBpmnProcessHash}`;
|
||||||
|
}
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
httpMethod: 'POST',
|
||||||
|
path: `${targetUris.processInstanceMigratePath}${queryParams}`,
|
||||||
|
successCallback: (result: any) => {
|
||||||
|
setIsLoading(false);
|
||||||
|
setOpenDialog(false);
|
||||||
|
successCallback(result);
|
||||||
|
},
|
||||||
|
failureCallback: (error: any) => {
|
||||||
|
setIsLoading(false);
|
||||||
|
setOpenDialog(false);
|
||||||
|
failureCallback(error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenDialog = () => {
|
||||||
|
setOpenDialog(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseDialog = () => {
|
||||||
|
setOpenDialog(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (migrationCheckResult?.can_migrate) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
onClick={handleOpenDialog}
|
||||||
|
title={title}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{buttonText}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Dialog open={openDialog} onClose={handleCloseDialog}>
|
||||||
|
<DialogTitle>Confirm Migrate Instance</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText>
|
||||||
|
Are you sure you want to proceed with this potentially-dangerous
|
||||||
|
process instance migration?
|
||||||
|
</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleCloseDialog} disabled={isLoading}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleRunMigration}
|
||||||
|
color="secondary"
|
||||||
|
variant="contained"
|
||||||
|
disabled={isLoading}
|
||||||
|
>
|
||||||
|
{isLoading ? <CircularProgress size={24} /> : 'Confirm'}
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
function MigrationStatus({
|
||||||
|
migrationCheckResult,
|
||||||
|
}: {
|
||||||
|
migrationCheckResult: any | null;
|
||||||
|
}) {
|
||||||
|
let returnComponent = null;
|
||||||
|
if (migrationCheckResult === null) {
|
||||||
|
returnComponent = (
|
||||||
|
<>
|
||||||
|
<CircularProgress style={{ marginRight: 8 }} />
|
||||||
|
<Typography>Checking if ready to migrate</Typography>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else if (migrationCheckResult.can_migrate) {
|
||||||
|
returnComponent = (
|
||||||
|
<>
|
||||||
|
<CheckCircleIcon style={{ color: green[500], marginRight: 8 }} />
|
||||||
|
<Typography>
|
||||||
|
Ready to migrate to newest process model version
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
migrationCheckResult.exception_class ===
|
||||||
|
'ProcessInstanceMigrationUnnecessaryError'
|
||||||
|
) {
|
||||||
|
returnComponent = (
|
||||||
|
<Alert severity="success">
|
||||||
|
<AlertTitle>Nothing to migrate</AlertTitle>The process instance is
|
||||||
|
already associated with the most recent process model version.
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
returnComponent = (
|
||||||
|
<Alert severity="warning">
|
||||||
|
<AlertTitle>Process instance not migratable</AlertTitle>
|
||||||
|
Process Instances can be migrated if the target process model version
|
||||||
|
has not changed any of the tasks that have already been completed and if
|
||||||
|
the process instance is not already at the newest version.
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Box display="flex" alignItems="center">
|
||||||
|
{returnComponent}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ProcessInstanceMigratePage() {
|
||||||
|
const params = useParams();
|
||||||
|
const [migrationCheckResult, setMigrationCheckResult] =
|
||||||
|
useState<MigrationCheckResult | null>(null);
|
||||||
|
const [migrationResult, setMigrationResult] = useState<any>(null);
|
||||||
|
const [migrationEvents, setMigrationEvents] = useState<
|
||||||
|
MigrationEvent[] | null
|
||||||
|
>(null);
|
||||||
|
|
||||||
|
const fetchProcessInstanceMigrationDetails = useCallback(() => {
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: `/process-instances/${params.process_model_id}/${params.process_instance_id}/check-can-migrate`,
|
||||||
|
successCallback: (result: any) => setMigrationCheckResult(result),
|
||||||
|
});
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: `/process-instance-events/${params.process_model_id}/${params.process_instance_id}/migration`,
|
||||||
|
successCallback: (result: any) => setMigrationEvents(result.results),
|
||||||
|
});
|
||||||
|
}, [params.process_instance_id, params.process_model_id]);
|
||||||
|
|
||||||
|
useEffect(fetchProcessInstanceMigrationDetails, [
|
||||||
|
fetchProcessInstanceMigrationDetails,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const onMigrationComplete = (result: any) => {
|
||||||
|
fetchProcessInstanceMigrationDetails();
|
||||||
|
setMigrationResult(result);
|
||||||
|
};
|
||||||
|
const onMigrationFailure = (error: any) => {
|
||||||
|
setMigrationResult(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
const migrationResultComponent = () => {
|
||||||
|
if (!migrationResult) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (migrationResult.ok) {
|
||||||
|
return <Alert severity="success">Process instance migrated</Alert>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let alertBody = null;
|
||||||
|
if (typeof migrationResult === 'string') {
|
||||||
|
alertBody = migrationResult;
|
||||||
|
} else if (
|
||||||
|
typeof migrationResult === 'object' &&
|
||||||
|
migrationResult.error_code
|
||||||
|
) {
|
||||||
|
alertBody = migrationResult.message;
|
||||||
|
} else {
|
||||||
|
alertBody = (
|
||||||
|
<ul>
|
||||||
|
{Object.keys(migrationResult).map((key) => (
|
||||||
|
<li key={key}>
|
||||||
|
{key}: {migrationResult[key]}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Alert severity="error">
|
||||||
|
<AlertTitle>Error</AlertTitle>
|
||||||
|
{alertBody}
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const processInstanceMigrationEventTable = () => {
|
||||||
|
if (!migrationEvents || migrationEvents.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
field: 'username',
|
||||||
|
headerName: 'Username',
|
||||||
|
flex: 2,
|
||||||
|
renderCell: (data: Record<string, any>) => {
|
||||||
|
return <CellRenderer header="username" data={data} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'timestamp',
|
||||||
|
headerName: 'Timestamp',
|
||||||
|
flex: 2,
|
||||||
|
renderCell: (data: Record<string, any>) => {
|
||||||
|
return <CellRenderer header="timestamp" data={data} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'initial_git_revision',
|
||||||
|
headerName: 'Initial Git Revision',
|
||||||
|
flex: 2,
|
||||||
|
renderCell: (data: Record<string, any>) => {
|
||||||
|
return (
|
||||||
|
<CellRenderer
|
||||||
|
header="initial_git_revision"
|
||||||
|
data={data}
|
||||||
|
title={data.row.initial_bpmn_process_hash}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'target_git_revision',
|
||||||
|
headerName: 'Target Git Revision',
|
||||||
|
flex: 2,
|
||||||
|
renderCell: (data: Record<string, any>) => {
|
||||||
|
return (
|
||||||
|
<CellRenderer
|
||||||
|
header="target_git_revision"
|
||||||
|
data={data}
|
||||||
|
title={data.row.target_bpmn_process_hash}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'actions',
|
||||||
|
headerName: 'Actions',
|
||||||
|
flex: 2,
|
||||||
|
renderCell: (data: Record<string, any>) => {
|
||||||
|
if (
|
||||||
|
migrationCheckResult &&
|
||||||
|
data.row.initial_bpmn_process_hash ===
|
||||||
|
migrationCheckResult.current_bpmn_process_hash
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<DangerousMigrationButton
|
||||||
|
successCallback={onMigrationComplete}
|
||||||
|
failureCallback={onMigrationFailure}
|
||||||
|
title={`Run another migration to switch to model version: '${data.row.initial_git_revision}'`}
|
||||||
|
targetBpmnProcessHash={data.row.initial_bpmn_process_hash}
|
||||||
|
buttonText="Revert"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const rows = migrationEvents.map((migrationEvent: MigrationEvent) => {
|
||||||
|
return migrationEvent;
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3>Previous Migrations</h3>
|
||||||
|
<DataGrid
|
||||||
|
sx={{
|
||||||
|
'& .MuiDataGrid-cell:focus': {
|
||||||
|
outline: 'none',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
initialState={{
|
||||||
|
columns: {
|
||||||
|
columnVisibilityModel: {
|
||||||
|
status: false,
|
||||||
|
last_milestone_bpmn_name: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
autoHeight
|
||||||
|
getRowHeight={() => 'auto'}
|
||||||
|
rows={rows}
|
||||||
|
columns={columns}
|
||||||
|
hideFooter
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ProcessBreadcrumb
|
||||||
|
hotCrumbs={[
|
||||||
|
['Process Groups', '/newui/process-groups'],
|
||||||
|
{
|
||||||
|
entityToExplode: String(params.process_model_id),
|
||||||
|
entityType: 'process-model-id',
|
||||||
|
linkLastItem: true,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
`Process Instance: ${params.process_instance_id}`,
|
||||||
|
`/newui/i/${params.process_instance_id}`,
|
||||||
|
],
|
||||||
|
['Migrate'],
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
{migrationResultComponent()}
|
||||||
|
<br />
|
||||||
|
<MigrationStatus migrationCheckResult={migrationCheckResult} />
|
||||||
|
<br />
|
||||||
|
{migrationCheckResult?.can_migrate ? (
|
||||||
|
<DangerousMigrationButton
|
||||||
|
successCallback={onMigrationComplete}
|
||||||
|
failureCallback={onMigrationFailure}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{processInstanceMigrationEventTable()}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -4,10 +4,10 @@ import ProcessInstanceShow from './ProcessInstanceShow';
|
|||||||
// import ProcessInstanceReportList from './ProcessInstanceReportList';
|
// import ProcessInstanceReportList from './ProcessInstanceReportList';
|
||||||
// import ProcessInstanceReportNew from './ProcessInstanceReportNew';
|
// import ProcessInstanceReportNew from './ProcessInstanceReportNew';
|
||||||
// import ProcessInstanceReportEdit from './ProcessInstanceReportEdit';
|
// import ProcessInstanceReportEdit from './ProcessInstanceReportEdit';
|
||||||
// import ProcessInstanceFindById from './ProcessInstanceFindById';
|
import ProcessInstanceFindById from './ProcessInstanceFindById';
|
||||||
// import ProcessInterstitialPage from './ProcessInterstitialPage';
|
import ProcessInterstitialPage from './TaskShow/ProcessInterstitialPage';
|
||||||
// import ProcessInstanceProgressPage from './ProcessInstanceProgressPage';
|
import ProcessInstanceProgressPage from './TaskShow/ProcessInstanceProgressPage';
|
||||||
// import ProcessInstanceMigratePage from './ProcessInstanceMigratePage';
|
import ProcessInstanceMigratePage from './ProcessInstanceMigratePage';
|
||||||
|
|
||||||
export default function ProcessInstanceRoutes() {
|
export default function ProcessInstanceRoutes() {
|
||||||
return (
|
return (
|
||||||
@ -23,26 +23,26 @@ export default function ProcessInstanceRoutes() {
|
|||||||
path="for-me/:process_model_id/:process_instance_id/:to_task_guid"
|
path="for-me/:process_model_id/:process_instance_id/:to_task_guid"
|
||||||
element={<ProcessInstanceShow variant="for-me" />}
|
element={<ProcessInstanceShow variant="for-me" />}
|
||||||
/>
|
/>
|
||||||
{/* <Route */}
|
<Route
|
||||||
{/* path="for-me/:process_model_id/:process_instance_id/interstitial" */}
|
path="for-me/:process_model_id/:process_instance_id/interstitial"
|
||||||
{/* element={<ProcessInterstitialPage variant="for-me" />} */}
|
element={<ProcessInterstitialPage variant="for-me" />}
|
||||||
{/* /> */}
|
/>
|
||||||
{/* <Route */}
|
<Route
|
||||||
{/* path=":process_model_id/:process_instance_id/interstitial" */}
|
path=":process_model_id/:process_instance_id/interstitial"
|
||||||
{/* element={<ProcessInterstitialPage variant="all" />} */}
|
element={<ProcessInterstitialPage variant="all" />}
|
||||||
{/* /> */}
|
/>
|
||||||
{/* <Route */}
|
<Route
|
||||||
{/* path="for-me/:process_model_id/:process_instance_id/progress" */}
|
path="for-me/:process_model_id/:process_instance_id/progress"
|
||||||
{/* element={<ProcessInstanceProgressPage variant="for-me" />} */}
|
element={<ProcessInstanceProgressPage variant="for-me" />}
|
||||||
{/* /> */}
|
/>
|
||||||
{/* <Route */}
|
<Route
|
||||||
{/* path=":process_model_id/:process_instance_id/progress" */}
|
path=":process_model_id/:process_instance_id/progress"
|
||||||
{/* element={<ProcessInstanceProgressPage variant="all" />} */}
|
element={<ProcessInstanceProgressPage variant="all" />}
|
||||||
{/* /> */}
|
/>
|
||||||
{/* <Route */}
|
<Route
|
||||||
{/* path=":process_model_id/:process_instance_id/migrate" */}
|
path=":process_model_id/:process_instance_id/migrate"
|
||||||
{/* element={<ProcessInstanceMigratePage />} */}
|
element={<ProcessInstanceMigratePage />}
|
||||||
{/* /> */}
|
/>
|
||||||
<Route
|
<Route
|
||||||
path=":process_model_id/:process_instance_id"
|
path=":process_model_id/:process_instance_id"
|
||||||
element={<ProcessInstanceShow variant="all" />}
|
element={<ProcessInstanceShow variant="all" />}
|
||||||
@ -57,7 +57,7 @@ export default function ProcessInstanceRoutes() {
|
|||||||
{/* path="reports/:report_identifier/edit" */}
|
{/* path="reports/:report_identifier/edit" */}
|
||||||
{/* element={<ProcessInstanceReportEdit />} */}
|
{/* element={<ProcessInstanceReportEdit />} */}
|
||||||
{/* /> */}
|
{/* /> */}
|
||||||
{/* <Route path="find-by-id" element={<ProcessInstanceFindById />} /> */}
|
<Route path="find-by-id" element={<ProcessInstanceFindById />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import useProcessInstanceNavigate from '../hooks/useProcessInstanceNavigate';
|
||||||
|
|
||||||
|
export default function ProcessInstanceShortLink() {
|
||||||
|
const params = useParams();
|
||||||
|
const { navigateToInstance } = useProcessInstanceNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
navigateToInstance({
|
||||||
|
processInstanceId: parseInt(params.process_instance_id || '0', 10),
|
||||||
|
});
|
||||||
|
}, [params.process_instance_id, navigateToInstance]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
@ -173,7 +173,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
|
|
||||||
const navigateToProcessInstances = (_result: any) => {
|
const navigateToProcessInstances = (_result: any) => {
|
||||||
navigate(
|
navigate(
|
||||||
`/process-instances?process_model_identifier=${unModifiedProcessModelId}`,
|
`/newui/process-instances?process_model_identifier=${unModifiedProcessModelId}`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
navigate(
|
navigate(
|
||||||
`/editor/process-models/${modifiedProcessModelId}/files/${primaryFileName}`,
|
`/newui/process-models/${modifiedProcessModelId}/files/${primaryFileName}`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
@ -236,8 +236,8 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
};
|
};
|
||||||
const keyboardShortcutArea = useKeyboardShortcut(keyboardShortcuts);
|
const keyboardShortcutArea = useKeyboardShortcut(keyboardShortcuts);
|
||||||
|
|
||||||
let processInstanceShowPageBaseUrl = `/process-instances/for-me/${params.process_model_id}/${params.process_instance_id}`;
|
let processInstanceShowPageBaseUrl = `/newui/process-instances/for-me/${params.process_model_id}/${params.process_instance_id}`;
|
||||||
const processInstanceShowPageBaseUrlAllVariant = `/process-instances/${params.process_model_id}/${params.process_instance_id}`;
|
const processInstanceShowPageBaseUrlAllVariant = `/newui/process-instances/${params.process_model_id}/${params.process_instance_id}`;
|
||||||
if (variant === 'all') {
|
if (variant === 'all') {
|
||||||
processInstanceShowPageBaseUrl = processInstanceShowPageBaseUrlAllVariant;
|
processInstanceShowPageBaseUrl = processInstanceShowPageBaseUrlAllVariant;
|
||||||
}
|
}
|
||||||
@ -596,7 +596,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
|
|
||||||
const navigateToProcessInstanceMigratePage = () => {
|
const navigateToProcessInstanceMigratePage = () => {
|
||||||
navigate(
|
navigate(
|
||||||
`/process-instances/${params.process_model_id}/${params.process_instance_id}/migrate`,
|
`/newui/process-instances/${params.process_model_id}/${params.process_instance_id}/migrate`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ export default function TaskShow() {
|
|||||||
},
|
},
|
||||||
[
|
[
|
||||||
`Process Instance Id: ${result.process_instance_id}`,
|
`Process Instance Id: ${result.process_instance_id}`,
|
||||||
`/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
`/newui/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
||||||
result.process_model_identifier,
|
result.process_model_identifier,
|
||||||
)}/${result.process_instance_id}`,
|
)}/${result.process_instance_id}`,
|
||||||
],
|
],
|
||||||
@ -214,7 +214,7 @@ export default function TaskShow() {
|
|||||||
const dataToSubmit = formObject?.formData;
|
const dataToSubmit = formObject?.formData;
|
||||||
|
|
||||||
if (!dataToSubmit) {
|
if (!dataToSubmit) {
|
||||||
navigate(`/tasks`);
|
navigate(`/newui/tasks`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const queryParams = '';
|
const queryParams = '';
|
||||||
|
@ -44,6 +44,7 @@ import ProcessModelEdit from '../a-spiffui-v3/views/ProcessModelEdit'; // Import
|
|||||||
import ProcessModelEditDiagram from '../a-spiffui-v3/views/ProcessModelEditDiagram';
|
import ProcessModelEditDiagram from '../a-spiffui-v3/views/ProcessModelEditDiagram';
|
||||||
import ReactFormEditor from '../a-spiffui-v3/views/ReactFormEditor'; // Import the new component
|
import ReactFormEditor from '../a-spiffui-v3/views/ReactFormEditor'; // Import the new component
|
||||||
import ProcessInstanceRoutes from '../a-spiffui-v3/views/ProcessInstanceRoutes';
|
import ProcessInstanceRoutes from '../a-spiffui-v3/views/ProcessInstanceRoutes';
|
||||||
|
import ProcessInstanceShortLink from '../a-spiffui-v3/views/ProcessInstanceShortLink';
|
||||||
|
|
||||||
const fadeIn = 'fadeIn';
|
const fadeIn = 'fadeIn';
|
||||||
const fadeOutImmediate = 'fadeOutImmediate';
|
const fadeOutImmediate = 'fadeOutImmediate';
|
||||||
@ -332,6 +333,10 @@ export default function SpiffUIV3() {
|
|||||||
path="process-instances/*"
|
path="process-instances/*"
|
||||||
element={<ProcessInstanceRoutes />}
|
element={<ProcessInstanceRoutes />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="i/:process_instance_id"
|
||||||
|
element={<ProcessInstanceShortLink />}
|
||||||
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user