|
|
- <>
- {t`Job`}
- {workflowJob && workflowJob?.id ? (
-
- {`${workflowJob?.id} - ${workflowJob?.name}`}
-
- ) : (
- t`Deleted`
- )}
- >
+ {workflowJob && workflowJob?.id ? (
+
+ {`${workflowJob?.id} - ${workflowJob?.name}`}
+
+ ) : (
+ t`Deleted`
+ )}
|
{formatDateString(workflowApproval.started)}
|
- {getStatus()}
+ {workflowApproval.status === 'pending' ? (
+
+ {getPendingLabel(workflowApproval)}
+
+ ) : (
+
+ )}
|
);
diff --git a/awx/ui/src/screens/WorkflowApproval/data.workflowApprovals.json b/awx/ui/src/screens/WorkflowApproval/data.workflowApprovals.json
index c21ec3df98..031983c610 100644
--- a/awx/ui/src/screens/WorkflowApproval/data.workflowApprovals.json
+++ b/awx/ui/src/screens/WorkflowApproval/data.workflowApprovals.json
@@ -222,6 +222,77 @@
"can_approve_or_deny": false,
"approval_expiration": null,
"timed_out": false
+ },
+ {
+ "id": 220,
+ "type": "workflow_approval",
+ "url": "/api/v2/workflow_approvals/218/",
+ "related": {
+ "created_by": "/api/v2/users/1/",
+ "unified_job_template": "/api/v2/workflow_approval_templates/10/",
+ "source_workflow_job": "/api/v2/workflow_jobs/216/",
+ "workflow_approval_template": "/api/v2/workflow_approval_templates/10/",
+ "approve": "/api/v2/workflow_approvals/218/approve/",
+ "deny": "/api/v2/workflow_approvals/218/deny/"
+ },
+ "summary_fields": {
+ "workflow_job_template": {
+ "id": 9,
+ "name": "Approval @ 9:15:26 AM",
+ "description": ""
+ },
+ "workflow_job": {
+ "id": 216,
+ "name": "Approval @ 9:15:26 AM",
+ "description": ""
+ },
+ "workflow_approval_template": {
+ "id": 10,
+ "name": "approval copy",
+ "description": "",
+ "timeout": 0
+ },
+ "unified_job_template": {
+ "id": 10,
+ "name": "approval copy",
+ "description": "",
+ "unified_job_type": "workflow_approval"
+ },
+ "created_by": {
+ "id": 1,
+ "username": "admin",
+ "first_name": "",
+ "last_name": ""
+ },
+ "user_capabilities": {
+ "delete": true,
+ "start": true
+ },
+ "source_workflow_job": {
+ "id": 216,
+ "name": "Approval @ 9:15:26 AM",
+ "description": "",
+ "status": "running",
+ "failed": false,
+ "elapsed": 0.0
+ }
+ },
+ "created": "2020-10-09T17:13:12.067947Z",
+ "modified": "2020-10-09T17:13:12.068147Z",
+ "name": "approval",
+ "description": "description of approval",
+ "unified_job_template": 10,
+ "launch_type": "workflow",
+ "status": "successful",
+ "failed": false,
+ "started": "2020-10-09T17:13:12.067947Z",
+ "finished": null,
+ "canceled_on": null,
+ "elapsed": 22.879029,
+ "job_explanation": "",
+ "can_approve_or_deny": true,
+ "approval_expiration": null,
+ "timed_out": false
}
]
}
diff --git a/awx/ui/src/screens/WorkflowApproval/shared/WorkflowApprovalControls.js b/awx/ui/src/screens/WorkflowApproval/shared/WorkflowApprovalControls.js
new file mode 100644
index 0000000000..90ae428182
--- /dev/null
+++ b/awx/ui/src/screens/WorkflowApproval/shared/WorkflowApprovalControls.js
@@ -0,0 +1,146 @@
+import React from 'react';
+import { t } from '@lingui/macro';
+import {
+ Dropdown as PFDropdown,
+ DropdownItem,
+ Tooltip,
+ DropdownToggle,
+ DropdownToggleAction,
+} from '@patternfly/react-core';
+import { CaretDownIcon } from '@patternfly/react-icons';
+import { useKebabifiedMenu } from 'contexts/Kebabified';
+import styled from 'styled-components';
+
+const Dropdown = styled(PFDropdown)`
+ --pf-c-dropdown__toggle--disabled--BackgroundColor: var(
+ --pf-global--disabled-color--200
+ );
+
+ &&& {
+ button {
+ color: var(--pf-c-dropdown__toggle--m-primary--Color);
+ }
+ div.pf-m-disabled > button {
+ color: var(--pf-global--disabled-color--100);
+ }
+ }
+`;
+
+function isPending(item) {
+ return item.status === 'pending';
+}
+function isComplete(item) {
+ return item.status !== 'pending';
+}
+
+function WorkflowApprovalControls({
+ selected,
+ onHandleDeny,
+ onHandleCancel,
+ onHandleApprove,
+ onHandleToggleToolbarKebab,
+ isKebabOpen,
+}) {
+ const { isKebabified } = useKebabifiedMenu();
+
+ const hasSelectedItems = selected.length > 0;
+ const isApproveDenyOrCancelDisabled =
+ !hasSelectedItems ||
+ !selected.every(
+ (item) => item.status === 'pending' && item.can_approve_or_deny
+ );
+
+ const renderTooltip = (action) => {
+ if (!hasSelectedItems) {
+ return t`Select items to approve, deny, or cancel`;
+ }
+ if (!selected.some(isPending)) {
+ return t`Cannot approve, cancel or deny completed workflow approvals`;
+ }
+
+ const completedItems = selected
+ .filter(isComplete)
+ .map((item) => item.name)
+ .join(', ');
+ if (selected.some(isPending) && selected.some(isComplete)) {
+ return t`The following selected items are complete and cannot be acted on: ${completedItems}`;
+ }
+ return action;
+ };
+
+ const dropdownItems = [
+