hide the revert button on the migration page on the web ui if it cannot be reverted to that revision w/ burnettk (#1935)

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
jasquat 2024-07-16 14:26:58 -04:00 committed by GitHub
parent dfce83c684
commit 461b37d3d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 80 additions and 43 deletions

View File

@ -1344,6 +1344,12 @@ paths:
description: The unique id of an existing process instance. description: The unique id of an existing process instance.
schema: schema:
type: integer type: integer
- name: target_bpmn_process_hash
in: query
required: false
description: The full bpmn process hash of the target version of the process model.
schema:
type: string
get: get:
tags: tags:
- Process Instances - Process Instances

View File

@ -551,6 +551,7 @@ def process_instance_reset(
def process_instance_check_can_migrate( def process_instance_check_can_migrate(
process_instance_id: int, process_instance_id: int,
modified_process_model_identifier: str, modified_process_model_identifier: str,
target_bpmn_process_hash: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
process_instance = _find_process_instance_by_id_or_raise(process_instance_id) process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
return_dict: dict = { return_dict: dict = {
@ -560,7 +561,9 @@ def process_instance_check_can_migrate(
"current_bpmn_process_hash": process_instance.bpmn_process.bpmn_process_definition.full_process_model_hash, "current_bpmn_process_hash": process_instance.bpmn_process.bpmn_process_definition.full_process_model_hash,
} }
try: try:
ProcessInstanceService.check_process_instance_can_be_migrated(process_instance) ProcessInstanceService.check_process_instance_can_be_migrated(
process_instance, target_bpmn_process_hash=target_bpmn_process_hash
)
except (ProcessInstanceMigrationNotSafeError, ProcessInstanceMigrationUnnecessaryError) as exception: except (ProcessInstanceMigrationNotSafeError, ProcessInstanceMigrationUnnecessaryError) as exception:
return_dict["can_migrate"] = False return_dict["can_migrate"] = False
return_dict["exception_class"] = exception.__class__.__name__ return_dict["exception_class"] = exception.__class__.__name__

View File

@ -558,3 +558,9 @@ export interface MigrationEvent {
timestamp: string; timestamp: string;
username: string; username: string;
} }
export interface MigrationCheckResult {
can_migrate: boolean;
process_instance_id: number;
current_git_revision: string;
current_bpmn_process_hash: string;
}

View File

@ -21,31 +21,49 @@ import HttpService from '../services/HttpService';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import { useUriListForPermissions } from '../hooks/UriListForPermissions'; import { useUriListForPermissions } from '../hooks/UriListForPermissions';
import { MigrationEvent } from '../interfaces'; import { MigrationEvent, MigrationCheckResult } from '../interfaces';
import CellRenderer from '../a-spiffui-v2/views/Dashboards/myProcesses/CellRenderer'; import CellRenderer from '../a-spiffui-v2/views/Dashboards/myProcesses/CellRenderer';
function DangerousMigrationButton({ function DangerousMigrationButton({
successCallback, successCallback,
failureCallback, failureCallback,
migrationEvent, targetBpmnProcessHash,
title, title,
buttonText = 'Migrate to Newest', buttonText = 'Migrate to Newest',
}: { }: {
successCallback: (result: any) => void; successCallback: (result: any) => void;
failureCallback: (error: any) => void; failureCallback: (error: any) => void;
title?: string; title?: string;
migrationEvent?: MigrationEvent; targetBpmnProcessHash?: string;
buttonText?: string; buttonText?: string;
}) { }) {
const params = useParams();
const [openDialog, setOpenDialog] = useState(false); const [openDialog, setOpenDialog] = useState(false);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const { targetUris } = useUriListForPermissions(); 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 = () => { const handleRunMigration = () => {
setIsLoading(true); setIsLoading(true);
let queryParams = ''; let queryParams = '';
if (migrationEvent) { if (targetBpmnProcessHash) {
queryParams = `?target_bpmn_process_hash=${migrationEvent.initial_bpmn_process_hash}`; queryParams = `?target_bpmn_process_hash=${targetBpmnProcessHash}`;
} }
HttpService.makeCallToBackend({ HttpService.makeCallToBackend({
httpMethod: 'POST', httpMethod: 'POST',
@ -71,42 +89,45 @@ function DangerousMigrationButton({
setOpenDialog(false); setOpenDialog(false);
}; };
return ( if (migrationCheckResult?.can_migrate) {
<> return (
<Button <>
variant="contained" <Button
color="secondary" variant="contained"
onClick={handleOpenDialog} color="secondary"
title={title} onClick={handleOpenDialog}
size="small" title={title}
> size="small"
{buttonText} >
</Button> {buttonText}
</Button>
<Dialog open={openDialog} onClose={handleCloseDialog}> <Dialog open={openDialog} onClose={handleCloseDialog}>
<DialogTitle>Confirm Migrate Instance</DialogTitle> <DialogTitle>Confirm Migrate Instance</DialogTitle>
<DialogContent> <DialogContent>
<DialogContentText> <DialogContentText>
Are you sure you want to proceed with this potentially-dangerous Are you sure you want to proceed with this potentially-dangerous
process instance migration? process instance migration?
</DialogContentText> </DialogContentText>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button onClick={handleCloseDialog} disabled={isLoading}> <Button onClick={handleCloseDialog} disabled={isLoading}>
Cancel Cancel
</Button> </Button>
<Button <Button
onClick={handleRunMigration} onClick={handleRunMigration}
color="secondary" color="secondary"
variant="contained" variant="contained"
disabled={isLoading} disabled={isLoading}
> >
{isLoading ? <CircularProgress size={24} /> : 'Confirm'} {isLoading ? <CircularProgress size={24} /> : 'Confirm'}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</> </>
); );
}
return null;
} }
function MigrationStatus({ function MigrationStatus({
migrationCheckResult, migrationCheckResult,
@ -159,7 +180,8 @@ function MigrationStatus({
export default function ProcessInstanceMigratePage() { export default function ProcessInstanceMigratePage() {
const params = useParams(); const params = useParams();
const [migrationCheckResult, setMigrationCheckResult] = useState<any>(null); const [migrationCheckResult, setMigrationCheckResult] =
useState<MigrationCheckResult | null>(null);
const [migrationResult, setMigrationResult] = useState<any>(null); const [migrationResult, setMigrationResult] = useState<any>(null);
const [migrationEvents, setMigrationEvents] = useState< const [migrationEvents, setMigrationEvents] = useState<
MigrationEvent[] | null MigrationEvent[] | null
@ -291,7 +313,7 @@ export default function ProcessInstanceMigratePage() {
successCallback={onMigrationComplete} successCallback={onMigrationComplete}
failureCallback={onMigrationFailure} failureCallback={onMigrationFailure}
title={`Run another migration to switch to model version: '${data.row.initial_git_revision}'`} title={`Run another migration to switch to model version: '${data.row.initial_git_revision}'`}
migrationEvent={data.row} targetBpmnProcessHash={data.row.initial_bpmn_process_hash}
buttonText="Revert" buttonText="Revert"
/> />
); );