added detailed area to process instance show page w/ burnettk

This commit is contained in:
jasquat 2023-01-12 15:27:32 -05:00
parent 89f2e9c562
commit 781c9814c2
7 changed files with 122 additions and 15 deletions

View File

@ -98,12 +98,14 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
"status": self.status, "status": self.status,
"start_in_seconds": self.start_in_seconds, "start_in_seconds": self.start_in_seconds,
"end_in_seconds": self.end_in_seconds, "end_in_seconds": self.end_in_seconds,
"created_at_in_seconds": self.created_at_in_seconds,
"updated_at_in_seconds": self.updated_at_in_seconds,
"process_initiator_id": self.process_initiator_id, "process_initiator_id": self.process_initiator_id,
"bpmn_xml_file_contents": self.bpmn_xml_file_contents, "bpmn_xml_file_contents": self.bpmn_xml_file_contents,
"bpmn_version_control_identifier": self.bpmn_version_control_identifier, "bpmn_version_control_identifier": self.bpmn_version_control_identifier,
"bpmn_version_control_type": self.bpmn_version_control_type, "bpmn_version_control_type": self.bpmn_version_control_type,
"spiff_step": self.spiff_step, "spiff_step": self.spiff_step,
"username": self.process_initiator.username, "process_initiator_username": self.process_initiator.username,
} }
@property @property

View File

@ -178,20 +178,32 @@ def set_new_access_token_in_cookie(
It will also delete the cookies if the user has logged out. It will also delete the cookies if the user has logged out.
""" """
tld = current_app.config["THREAD_LOCAL_DATA"] tld = current_app.config["THREAD_LOCAL_DATA"]
domain_for_frontend_cookie: Optional[str] = re.sub(r"^https?:\/\/", '', current_app.config['SPIFFWORKFLOW_FRONTEND_URL']) domain_for_frontend_cookie: Optional[str] = re.sub(
if domain_for_frontend_cookie and domain_for_frontend_cookie.startswith('localhost'): r"^https?:\/\/", "", current_app.config["SPIFFWORKFLOW_FRONTEND_URL"]
)
if domain_for_frontend_cookie and domain_for_frontend_cookie.startswith(
"localhost"
):
domain_for_frontend_cookie = None domain_for_frontend_cookie = None
if hasattr(tld, "new_access_token") and tld.new_access_token: if hasattr(tld, "new_access_token") and tld.new_access_token:
response.set_cookie("access_token", tld.new_access_token, domain=domain_for_frontend_cookie) response.set_cookie(
"access_token", tld.new_access_token, domain=domain_for_frontend_cookie
)
# id_token is required for logging out since this gets passed back to the openid server # id_token is required for logging out since this gets passed back to the openid server
if hasattr(tld, "new_id_token") and tld.new_id_token: if hasattr(tld, "new_id_token") and tld.new_id_token:
response.set_cookie("id_token", tld.new_id_token, domain=domain_for_frontend_cookie) response.set_cookie(
"id_token", tld.new_id_token, domain=domain_for_frontend_cookie
)
if hasattr(tld, "user_has_logged_out") and tld.user_has_logged_out: if hasattr(tld, "user_has_logged_out") and tld.user_has_logged_out:
response.set_cookie("id_token", "", max_age=0, domain=domain_for_frontend_cookie) response.set_cookie(
response.set_cookie("access_token", "", max_age=0, domain=domain_for_frontend_cookie) "id_token", "", max_age=0, domain=domain_for_frontend_cookie
)
response.set_cookie(
"access_token", "", max_age=0, domain=domain_for_frontend_cookie
)
_clear_auth_tokens_from_thread_local_data() _clear_auth_tokens_from_thread_local_data()

View File

@ -338,7 +338,11 @@ class ProcessInstanceReportService:
}, },
{"Header": "Start", "accessor": "start_in_seconds", "filterable": False}, {"Header": "Start", "accessor": "start_in_seconds", "filterable": False},
{"Header": "End", "accessor": "end_in_seconds", "filterable": False}, {"Header": "End", "accessor": "end_in_seconds", "filterable": False},
{"Header": "Username", "accessor": "username", "filterable": False}, {
"Header": "Started By",
"accessor": "process_initiator_username",
"filterable": False,
},
{"Header": "Status", "accessor": "status", "filterable": False}, {"Header": "Status", "accessor": "status", "filterable": False},
] ]

View File

@ -232,7 +232,7 @@ class TestProcessApi(BaseTest):
"process_model_display_name", "process_model_display_name",
"start_in_seconds", "start_in_seconds",
"end_in_seconds", "end_in_seconds",
"username", "process_initiator_username",
"status", "status",
"summary", "summary",
"description", "description",
@ -3145,7 +3145,7 @@ class TestProcessApi(BaseTest):
assert response.json["pagination"]["pages"] == 1 assert response.json["pagination"]["pages"] == 1
assert response.json["pagination"]["total"] == 1 assert response.json["pagination"]["total"] == 1
def test_can_get_process_instance_list_with_report_metadata_and_process_initator( def test_can_get_process_instance_list_with_report_metadata_and_process_initiator(
self, self,
app: Flask, app: Flask,
client: FlaskClient, client: FlaskClient,
@ -3223,8 +3223,14 @@ class TestProcessApi(BaseTest):
assert response.json is not None assert response.json is not None
assert response.status_code == 200 assert response.status_code == 200
assert len(response.json["results"]) == 2 assert len(response.json["results"]) == 2
assert response.json["results"][0]["username"] == user_one.username assert (
assert response.json["results"][1]["username"] == user_one.username response.json["results"][0]["process_initiator_username"]
== user_one.username
)
assert (
response.json["results"][1]["process_initiator_username"]
== user_one.username
)
response = client.get( response = client.get(
f"/v1.0/process-instances?report_identifier={process_instance_report_dne.identifier}", f"/v1.0/process-instances?report_identifier={process_instance_report_dne.identifier}",
@ -3276,7 +3282,11 @@ class TestProcessApi(BaseTest):
}, },
{"Header": "Start", "accessor": "start_in_seconds", "filterable": False}, {"Header": "Start", "accessor": "start_in_seconds", "filterable": False},
{"Header": "End", "accessor": "end_in_seconds", "filterable": False}, {"Header": "End", "accessor": "end_in_seconds", "filterable": False},
{"Header": "Username", "accessor": "username", "filterable": False}, {
"Header": "Username",
"accessor": "process_initiator_username",
"filterable": False,
},
{"Header": "Status", "accessor": "status", "filterable": False}, {"Header": "Status", "accessor": "status", "filterable": False},
{"Header": "key1", "accessor": "key1", "filterable": True}, {"Header": "key1", "accessor": "key1", "filterable": True},
{"Header": "key2", "accessor": "key2", "filterable": True}, {"Header": "key2", "accessor": "key2", "filterable": True},

View File

@ -1171,7 +1171,7 @@ export default function ProcessInstanceListTable({
start_in_seconds: 'Start Time', start_in_seconds: 'Start Time',
end_in_seconds: 'End Time', end_in_seconds: 'End Time',
status: 'Status', status: 'Status',
username: 'Started By', process_initiator_username: 'Started By',
spiff_step: 'SpiffWorkflow Step', spiff_step: 'SpiffWorkflow Step',
}; };
const getHeaderLabel = (header: string) => { const getHeaderLabel = (header: string) => {

View File

@ -73,8 +73,13 @@ export interface ProcessInstance {
status: string; status: string;
start_in_seconds: number | null; start_in_seconds: number | null;
end_in_seconds: number | null; end_in_seconds: number | null;
process_initiator_username: string;
bpmn_xml_file_contents?: string; bpmn_xml_file_contents?: string;
spiff_step?: number; spiff_step?: number;
created_at_in_seconds: number;
updated_at_in_seconds: number;
bpmn_version_control_identifier: string;
bpmn_version_control_type: string;
} }
export interface MessageCorrelationProperties { export interface MessageCorrelationProperties {

View File

@ -7,12 +7,12 @@ import {
useSearchParams, useSearchParams,
} from 'react-router-dom'; } from 'react-router-dom';
import { import {
CaretRight,
TrashCan, TrashCan,
StopOutline, StopOutline,
PauseOutline, PauseOutline,
PlayOutline, PlayOutline,
CaretLeft, CaretLeft,
CaretRight,
InProgress, InProgress,
Checkmark, Checkmark,
Warning, Warning,
@ -72,6 +72,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
const [eventPayload, setEventPayload] = useState<string>('{}'); const [eventPayload, setEventPayload] = useState<string>('{}');
const [eventTextEditorEnabled, setEventTextEditorEnabled] = const [eventTextEditorEnabled, setEventTextEditorEnabled] =
useState<boolean>(false); useState<boolean>(false);
const [displayDetails, setDisplayDetails] = useState<boolean>(false);
const setErrorObject = (useContext as any)(ErrorContext)[1]; const setErrorObject = (useContext as any)(ErrorContext)[1];
@ -280,6 +281,70 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
}); });
}; };
const detailedViewElement = () => {
if (!processInstance) {
return null;
}
if (displayDetails) {
return (
<>
<Grid condensed fullWidth>
<Button
kind="ghost"
className="button-link"
onClick={() => setDisplayDetails(false)}
title="Hide Details"
>
&laquo; Hide Details
</Button>
</Grid>
<Grid condensed fullWidth>
<Column sm={1} md={1} lg={2} className="grid-list-title">
Updated At:{' '}
</Column>
<Column sm={3} md={3} lg={3} className="grid-date">
{convertSecondsToFormattedDateTime(
processInstance.updated_at_in_seconds
)}
</Column>
</Grid>
<Grid condensed fullWidth>
<Column sm={1} md={1} lg={2} className="grid-list-title">
Created At:{' '}
</Column>
<Column sm={3} md={3} lg={3} className="grid-date">
{convertSecondsToFormattedDateTime(
processInstance.created_at_in_seconds
)}
</Column>
</Grid>
<Grid condensed fullWidth>
<Column sm={1} md={1} lg={2} className="grid-list-title">
Process model revision:{' '}
</Column>
<Column sm={3} md={3} lg={3} className="grid-date">
{processInstance.bpmn_version_control_identifier} (
{processInstance.bpmn_version_control_type})
</Column>
</Grid>
</>
);
}
return (
<Grid condensed fullWidth>
<Button
kind="ghost"
className="button-link"
onClick={() => setDisplayDetails(true)}
title="Show Details"
>
View Details &raquo;
</Button>
</Grid>
);
};
const getInfoTag = () => { const getInfoTag = () => {
if (!processInstance) { if (!processInstance) {
return null; return null;
@ -316,6 +381,14 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
return ( return (
<> <>
<Grid condensed fullWidth>
<Column sm={1} md={1} lg={2} className="grid-list-title">
Started By:{' '}
</Column>
<Column sm={3} md={3} lg={3} className="grid-date">
{processInstance.process_initiator_username}
</Column>
</Grid>
<Grid condensed fullWidth> <Grid condensed fullWidth>
<Column sm={1} md={1} lg={2} className="grid-list-title"> <Column sm={1} md={1} lg={2} className="grid-list-title">
Started:{' '} Started:{' '}
@ -337,6 +410,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
</Tag> </Tag>
</Column> </Column>
</Grid> </Grid>
{detailedViewElement()}
<br /> <br />
<Grid condensed fullWidth> <Grid condensed fullWidth>
<Column sm={2} md={2} lg={2}> <Column sm={2} md={2} lg={2}>