Skip to content

Commit

Permalink
Introducing workflow status list in request's show page
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffibm committed Aug 9, 2023
1 parent 2a30ec0 commit 403ee67
Show file tree
Hide file tree
Showing 6 changed files with 321 additions and 0 deletions.
209 changes: 209 additions & 0 deletions app/javascript/components/request-workflow-status/data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import moment from 'moment';

/** Types of workflow state status */
export const workflowStateTypes = {
success: { text: 'success', tagType: 'green' },
error: { text: 'error', tagType: 'red' },
failed: { text: 'failed', tagType: 'gray' },
};

/** Function to get the header data of workflow states table. */
const headerData = () => ([
{
key: 'name',
header: 'Name',
},
{
key: 'enteredTime',
header: 'Entered Time',
},
{
key: 'finishedTime',
header: 'Finished Time',
},
{
key: 'duration',
header: 'Duration',
},
]);

const convertDate = (date) => `${moment(date).format('MM/DD/YYYY')} ${moment(date).format('h:mm:ss A')}`;

/** Function to get the row data of workflow states table. */
const rowData = ({ States }) => States.map((item) => ({
id: item.Guid,
name: item.Name,
enteredTime: convertDate(item.EnteredTime),
finishedTime: convertDate(item.FinishedTime),
duration: item.Duration,
}));

/** Dummy data received from api response. */
const responseItem = () => ({
href: 'https://ag-im-devel.rtp.raleigh.ibm.com/api/configuration_scripts/41',
id: '41',
manager_id: '2',
manager_ref: null,
name: null,
description: null,
variables: null,
created_at: '2023-07-28T15:05:07Z',
updated_at: '2023-07-28T15:05:10Z',
survey_spec: null,
inventory_root_group_id: null,
type: 'ManageIQ::Providers::Workflows::AutomationManager::WorkflowInstance',
parent_id: '1',
configuration_script_source_id: null,
run_by_userid: 'admin',
payload: '{\n "Comment": "List providers.",\n "StartAt": "ListProviders",\n "States": {\n "ListProviders": {\n "Type": "Task",\n "Resource": "docker://docker.io/agrare/list-providers:latest",\n "End": true,\n "Credentials": {\n "api_user": "$.api_user",\n "api_password": "$.api_password"\n },\n "Parameters": {\n "provider_type": "ManageIQ::Providers::vmware::InfraManager"\n }\n }\n }\n}\n',
payload_type: null,
credentials: {
api_user: '$.manageiq_api.userid',
},
context: {
Task: {},
State: {
Guid: 'b7752c4f-a1c9-4be9-867b-75454a143b88',
Name: 'ListProviders',
Input: {
dialog: {
dialog_vm_name: 'ag-prov-test-1',
dialog_provider: 0,
dialog_source_template: null,
},
},
Output: {
values: {
3: 'vcenter5.tivlab.raleigh.ibm.com',
},
provider_type: 'ManageIQ::Providers::vmware::InfraManager',
},
Duration: 2.845886593000614e-06,
EnteredTime: '2023-07-28T15:05:08.099Z',
FinishedTime: '2023-07-28T15:05:10.945Z',
},
States: [
{
Guid: '9f050a84-0551-4a03-afe6-e819fdf4b6f0',
Name: 'CloneTemplate',
Input: {
dialog_vm_name: 'ag-prov-test-1',
dialog_provider: 3,
dialog_source_template: 'vm-16018',
},
Output: {
name: 'ag-prov-test-1',
task: 'task-263457',
template: 'vm-16018',
provider_id: '3',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Duration: 3.7600120970018907e-06,
EnteredTime: '2023-07-28T17:13:20.235Z',
FinishedTime: '2023-07-28T17:13:23.995Z',
},
{
Guid: '55eafa18-6459-4250-9b26-73fbbacb2e56',
Name: 'CheckTaskComplete',
Input: {
name: 'ag-prov-test-1',
task: 'task-263457',
template: 'vm-16018',
provider_id: '3',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Output: {
vm: 'vm-18251',
task: 'task-263457',
state: 'success',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Duration: 2.016900707996683e-06,
EnteredTime: '2023-07-28T17:13:24.070Z',
FinishedTime: '2023-07-28T17:13:26.087Z',
},
{
Guid: '21807106-42d2-456a-9ae8-5f67fe809144',
Name: 'PollTaskComplete',
Input: {
vm: 'vm-18251',
task: 'task-263457',
state: 'success',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Output: {
vm: 'vm-18251',
task: 'task-263457',
state: 'success',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Duration: 2.0984100410714745e-10,
EnteredTime: '2023-07-28T17:13:27.701Z',
FinishedTime: '2023-07-28T17:13:27.701Z',
},
{
Guid: 'cdbb7dcf-1373-48e0-a1ef-61391f949dfe',
Name: 'PowerOnVM',
Input: {
vm: 'vm-18251',
task: 'task-263457',
state: 'success',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Output: {
vm: 'vm-18251',
task_id: 'task-263458',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Duration: 1.326430924993474e-06,
EnteredTime: '2023-07-28T17:13:27.736Z',
FinishedTime: '2023-07-28T17:13:29.062Z',
},
{
Guid: 'ee07309c-fb21-43f5-b616-b9b44021c20c',
Name: 'SuccessState',
Input: {
vm: 'vm-18251',
task_id: 'task-263458',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Output: {
vm: 'vm-18251',
task_id: 'task-263458',
vcenter_host: 'vcenter5.tivlab.raleigh.ibm.com',
},
Duration: 3.695007762871683e-12,
EnteredTime: '2023-07-28T17:13:29.098Z',
FinishedTime: '2023-07-28T17:13:29.098Z',
},
],
Execution: {
Input: {
dialog: {
dialog_vm_name: 'ag-prov-test-1',
dialog_provider: 0,
dialog_source_template: null,
},
},
StartTime: '2023-07-28T15:05:08.099Z',
},
StateMachine: {},
},
output: {
values: {
3: 'vcenter5.tivlab.raleigh.ibm.com',
},
provider_type: 'ManageIQ::Providers::vmware::InfraManager',
},
status: 'success',
miq_task_id: '114',
}
);

/** Function to return the header, row and status data required for the RequestWorkflowStatus component. */
export const workflowStatusData = (_response) => {
const dummyItem = responseItem();
const rows = rowData(dummyItem.context);
const headers = headerData();
return { headers, rows, status: dummyItem.status };
};
92 changes: 92 additions & 0 deletions app/javascript/components/request-workflow-status/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import React, { useEffect, useState } from 'react';
import {
Tag, Loading,
} from 'carbon-components-react';
import PropTypes from 'prop-types';
import { workflowStatusData, workflowStateTypes } from './data';
import MiqDataTable from '../miq-data-table';

/** Component to render the Workflow status in /miq_request/show/#{id} page */
const RequestWorkflowStatus = (recordId) => {
const RELOAD = 5000; // Time interval to reload the RequestWorkflowStatus component.

const [data, setData] = useState(
{
isLoading: true,
responseData: undefined,
}
);

/** Function to get the Workflow
* TODO: Use the recordId in the api url when it's ready.
*/
const getWorkflow = () => {
const url = `/api/configuration_scripts/342`;
API.get(url)
.then((response) => {
setData({
...data,
responseData: workflowStatusData(response),
isLoading: false,
});
});
};

/** Logic to reload the component every (RELOAD) 5 seconds. */
useEffect(() => {
const interval = setInterval(() => {
setData({ ...data, isLoading: true });
getWorkflow();
}, RELOAD);
return () => clearInterval(interval); // This represents the unmount function, in which you need to clear your interval to prevent memory leaks.
}, [data.responseData]);

useEffect(() => {
getWorkflow();
}, [recordId]);

/** Function to render the status of workflow. */
const renderStatusTag = () => {
const status = workflowStateTypes[data.responseData.status];
return (
<Tag type={status.tagType} title={status.text}>
{status.text.toUpperCase()}
</Tag>
);
};

/** Function to render the status of workflow status row. */
const renderWorkflowStatusRow = () => (
<div className="workflow-status-container">
<div className="workflow-status-label">
{__('Status')}
:
</div>
<div className="workflow-status-tag">{data.responseData && renderStatusTag()}</div>
<div className="workflow-status-action">
{data.isLoading && <Loading active small withOverlay={false} className="loading" />}
</div>
</div>

);

return (
<div>
{renderWorkflowStatusRow()}
{data.responseData
&& (
<MiqDataTable
headers={data.responseData.headers}
rows={data.responseData.rows}
mode="request-workflow-status"
/>
) }
</div>
);
};

RequestWorkflowStatus.defaultProps = {
recordId: PropTypes.number.isRequired,
};

export default RequestWorkflowStatus;
2 changes: 2 additions & 0 deletions app/javascript/packs/component-definitions-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import ReportDataTable from '../components/data-tables/report-data-table/report-
import RetirementForm from '../components/retirement-form';
import RoleList from '../components/data-tables/role-list';
import RequestsTable from '../components/data-tables/requests-table';
import RequestWorkflowStatus from '../components/request-workflow-status';
import RoutersForm from '../components/routers-form';
import ServiceDialogFromForm from '../components/service-dialog-from-form/service-dialog-from';
import ServiceDetailStdout from '../components/service-detail-stdout';
Expand Down Expand Up @@ -268,6 +269,7 @@ ManageIQ.component.addReact('ReportList', ReportList);
ManageIQ.component.addReact('RetirementForm', RetirementForm);
ManageIQ.component.addReact('RoleList', RoleList);
ManageIQ.component.addReact('RequestsTable', RequestsTable);
ManageIQ.component.addReact('RequestWorkflowStatus', RequestWorkflowStatus);
ManageIQ.component.addReact('RoutersForm', RoutersForm);
ManageIQ.component.addReact('SearchBar', SearchBar);
ManageIQ.component.addReact('ServiceDialogFromForm', ServiceDialogFromForm);
Expand Down
1 change: 1 addition & 0 deletions app/stylesheet/application-webpack.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@
@import './tree.scss';
@import './toolbar.scss';
@import './widget.scss';
@import './workflows.scss';
@import './cloud-container-projects-dashboard.scss';
14 changes: 14 additions & 0 deletions app/stylesheet/workflows.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.workflow-status-container {
display: flex;
flex-direction: row;
align-items: center;

.workflow-status-label {
font-weight:bold;
margin-right: 5px;
}

.workflow-status-tag {
margin-right: 5px;
}
}
3 changes: 3 additions & 0 deletions app/views/miq_request/_request.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,6 @@
- else
= render :partial => "reconfigure_show"
%h3
= _("Workflow States")
= react('RequestWorkflowStatus', :recordId => @miq_request.id)

0 comments on commit 403ee67

Please sign in to comment.