-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introducing workflow status list in request's show page
- Loading branch information
Showing
7 changed files
with
360 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
216 changes: 216 additions & 0 deletions
216
app/javascript/components/request-workflow-status/data.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
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')}`; | ||
|
||
const duration = (StartTime, FinishedTime) => { | ||
const start = moment(StartTime); | ||
const end = moment(FinishedTime); | ||
const diff = end.diff(start); | ||
return `${moment.utc(diff).format('.SSS')}s`; | ||
}; | ||
|
||
/** 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: duration(item.StartTime, item.FinishedTime), | ||
})); | ||
|
||
/** 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: 'error', | ||
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 }; | ||
}; |
107 changes: 107 additions & 0 deletions
107
app/javascript/components/request-workflow-status/index.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
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'; | ||
import NotificationMessage from '../notification-message'; | ||
|
||
/** Component to render the Workflow status in /miq_request/show/#{id} page */ | ||
const RequestWorkflowStatus = (recordId) => { | ||
const RELOAD = 2000; // 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(() => { | ||
if (data.responseData && ![workflowStateTypes.success.text, workflowStateTypes.error.text].includes(data.responseData.status)) { | ||
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. | ||
} | ||
return undefined; | ||
}, [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. */ | ||
const renderWorkflowStatus = () => ( | ||
<div className="workflow-status-container"> | ||
<div className="workflow-status-label"> | ||
{__('Status')} | ||
: | ||
</div> | ||
<div className="workflow-status-tag"> | ||
{data.responseData && data.responseData.status && renderStatusTag()} | ||
</div> | ||
<div className="workflow-status-action"> | ||
{data.isLoading && <Loading active small withOverlay={false} className="loading" />} | ||
</div> | ||
</div> | ||
); | ||
|
||
/** Function to render the notification. */ | ||
const renderNotitication = () => ( | ||
<div className="workflow-notification-container"> | ||
<NotificationMessage type="error" message="Error messages goes here" /> | ||
</div> | ||
); | ||
|
||
/** Function to render the list. */ | ||
const renderList = ({ headers, rows }) => ( | ||
<MiqDataTable | ||
headers={headers} | ||
rows={rows} | ||
mode="request-workflow-status" | ||
/> | ||
); | ||
|
||
return ( | ||
<div className="workflow-states-container"> | ||
{renderWorkflowStatus()} | ||
{data.responseData && data.responseData.status === workflowStateTypes.error.text && renderNotitication()} | ||
{data.responseData && renderList(data.responseData)} | ||
</div> | ||
); | ||
}; | ||
|
||
RequestWorkflowStatus.defaultProps = { | ||
recordId: PropTypes.number.isRequired, | ||
}; | ||
|
||
export default RequestWorkflowStatus; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.