diff --git a/app/javascript/components/miq-data-table/miq-table-cell.jsx b/app/javascript/components/miq-data-table/miq-table-cell.jsx index e57e3b650a2..0922d0143a7 100644 --- a/app/javascript/components/miq-data-table/miq-table-cell.jsx +++ b/app/javascript/components/miq-data-table/miq-table-cell.jsx @@ -10,6 +10,7 @@ import { CellAction, hasIcon, hasImage, hasButton, hasTextInput, hasToggle, hasLink, isObject, isArray, isNumber, decimalCount, } from './helper'; import { customOnClickHandler } from '../../helpers/custom-click-handler'; +import { carbonizeIcon } from '../../menu/icon'; const MiqTableCell = ({ cell, onCellClick, row, truncate, @@ -74,6 +75,20 @@ const MiqTableCell = ({ ); }; + const returnIcon = (icon, style, styledIconClass, longerTextClass, index = undefined) => { + const extraProps = {}; + if (index !== undefined) { + extraProps.key = index.toString(); + } + if (icon.startsWith('carbon--')) { + const IconElement = carbonizeIcon(icon); + return ( + + ); + } + return (); + }; + /** Function to render icon(s) in cell. */ const renderIcon = (icon, style, showText) => { const hasBackground = Object.keys(style).includes('background'); @@ -83,8 +98,8 @@ const MiqTableCell = ({
{ typeof (icon) === 'string' - ? - : icon.map((i, index) => ) + ? returnIcon(icon, style, styledIconClass, longerTextClass) + : icon.map((i, index) => returnIcon(i, style, styledIconClass, longerTextClass, index)) } {showText && truncateText}
diff --git a/app/javascript/components/request-workflow-status/data.js b/app/javascript/components/request-workflow-status/data.js index 6254ea8fb26..499222e385c 100644 --- a/app/javascript/components/request-workflow-status/data.js +++ b/app/javascript/components/request-workflow-status/data.js @@ -43,13 +43,43 @@ const convertDate = (date) => { return formattedDate.toString(); }; +// Converts the duration time in ms and returns a string in format: w days x hours y minutes z seconds +// duration: time in ms +const convertDuration = (duration) => { + const durationString = moment.duration(duration, 'milliseconds').toISOString().split('PT')[1]; + let startIndex = 0; + let resultString = ''; + if (durationString.indexOf('H') >= 0) { + resultString += `${durationString.slice(startIndex, durationString.indexOf('H'))}h `; + startIndex = durationString.indexOf('H') + 1; + } + if (durationString.indexOf('M') >= 0) { + resultString += `${durationString.slice(startIndex, durationString.indexOf('M'))}m `; + startIndex = durationString.indexOf('M') + 1; + } + if (durationString.indexOf('S') >= 0) { + resultString += `${durationString.slice(startIndex, durationString.indexOf('S'))}s`; + startIndex = durationString.indexOf('S') + 1; + } + return resultString; +}; + +const getItemIcon = (item) => { + if (item.RunnerContext && item.RunnerContext.success) { + return { icon: 'carbon--CheckmarkOutline' }; + } if (item.RunnerContext && item.RunnerContext.Error) { + return { icon: 'carbon--MisuseOutline' }; + } + return { icon: 'carbon--PlayOutline' }; +}; + /** Function to get the row data of workflow states table. */ const rowData = ({ StateHistory }) => StateHistory.map((item) => ({ id: item.Guid.toString(), - name: item.Name, + name: { text: item.Name, ...getItemIcon(item) }, enteredTime: convertDate(item.EnteredTime.toString()), finishedTime: convertDate(item.FinishedTime.toString()), - duration: item.Duration.toFixed(3).toString(), + duration: convertDuration(item.Duration * 1000), })); /** Function to return the header, row and status data required for the RequestWorkflowStatus component. */ @@ -59,6 +89,20 @@ export const workflowStatusData = (response) => { return undefined; } const rows = response.context ? rowData(response.context) : []; + if (response.context && response.context.State) { + const state = response.context.State; + const currentTime = new Date(); // Date Object for current time + const oldTime = Date.parse(state.EnteredTime); // ms since start time to entered time in UTC + const durationTime = currentTime.getTime() - oldTime; // ms from entered time to current time + + rows.push({ + id: state.Guid.toString(), + name: { text: state.Name, icon: 'carbon--PlayOutline' }, + enteredTime: convertDate(state.EnteredTime.toString()), + finishedTime: '', + duration: convertDuration(durationTime), + }); + } const headers = headerData(); const name = response.name || response.description; return { diff --git a/app/stylesheet/miq-data-table.scss b/app/stylesheet/miq-data-table.scss index 278595f2d54..c94ad6510ec 100644 --- a/app/stylesheet/miq-data-table.scss +++ b/app/stylesheet/miq-data-table.scss @@ -1,3 +1,9 @@ +:root { + --green: #2d7623; + --red: #cc0000; + --yellow: #ec7a08; +} + .tenant-quota-data-table { .miq-data-table { margin-bottom: 32px; @@ -113,7 +119,7 @@ } .icon.fa-ruby { - color: #cc0000 !important; + color: var(--red) !important; } span { @@ -387,3 +393,20 @@ table.miq_preview { } } +.request-workflow-status { + .carbon-icons-style { + margin-right: 5px; + } + + .carbon--CheckmarkOutline { + color: var(--green); + } + + .carbon--MisuseOutline { + color: var(--red); + } + + .carbon--PlayOutline { + color: var(--yellow) + } +}