@@ -132,14 +140,14 @@ function ProjectListItem({
)}
|
- {project.summary_fields.last_job && (
+ {job && (
-
-
+
+
)}
@@ -169,7 +177,10 @@ function ProjectListItem({
visible={project.summary_fields.user_capabilities.start}
tooltip={i18n._(t`Sync Project`)}
>
-
+
', () => {
description: '',
name: 'Mock org',
},
+ last_job: {
+ id: 9000,
+ status: 'successful',
+ },
user_capabilities: {
start: true,
},
diff --git a/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.js b/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.js
index 38303c9ed3..de863a7ee7 100644
--- a/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.js
+++ b/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.js
@@ -26,7 +26,7 @@ export default function useWsProjects(initialProjects) {
...project,
summary_fields: {
...project.summary_fields,
- last_job: {
+ current_job: {
id: lastMessage.unified_job_id,
status: lastMessage.status,
finished: lastMessage.finished,
diff --git a/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.test.jsx b/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.test.jsx
index 0a41c39689..426de68429 100644
--- a/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.test.jsx
+++ b/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.test.jsx
@@ -64,7 +64,7 @@ describe('useWsProjects', () => {
{
id: 1,
summary_fields: {
- last_job: {
+ current_job: {
id: 1,
status: 'running',
finished: null,
@@ -87,7 +87,7 @@ describe('useWsProjects', () => {
})
);
expect(
- wrapper.find('TestInner').prop('projects')[0].summary_fields.last_job
+ wrapper.find('TestInner').prop('projects')[0].summary_fields.current_job
.status
).toEqual('running');
await act(async () => {
@@ -104,7 +104,7 @@ describe('useWsProjects', () => {
wrapper.update();
expect(
- wrapper.find('TestInner').prop('projects')[0].summary_fields.last_job
+ wrapper.find('TestInner').prop('projects')[0].summary_fields.current_job
).toEqual({
id: 12,
status: 'successful',
diff --git a/awx/ui_next/src/screens/Project/shared/ProjectSyncButton.jsx b/awx/ui_next/src/screens/Project/shared/ProjectSyncButton.jsx
index 2d316d5fa7..e8569620b6 100644
--- a/awx/ui_next/src/screens/Project/shared/ProjectSyncButton.jsx
+++ b/awx/ui_next/src/screens/Project/shared/ProjectSyncButton.jsx
@@ -1,6 +1,6 @@
import React, { useCallback } from 'react';
import { useRouteMatch } from 'react-router-dom';
-import { Button } from '@patternfly/react-core';
+import { Button, Tooltip } from '@patternfly/react-core';
import { SyncIcon } from '@patternfly/react-icons';
import { number } from 'prop-types';
@@ -12,7 +12,7 @@ import AlertModal from '../../../components/AlertModal';
import ErrorDetail from '../../../components/ErrorDetail';
import { ProjectsAPI } from '../../../api';
-function ProjectSyncButton({ i18n, projectId }) {
+function ProjectSyncButton({ i18n, projectId, lastJobStatus = null }) {
const match = useRouteMatch();
const { request: handleSync, error: syncError } = useRequest(
@@ -24,16 +24,39 @@ function ProjectSyncButton({ i18n, projectId }) {
const { error, dismissError } = useDismissableError(syncError);
const isDetailsView = match.url.endsWith('/details');
+ const isDisabled = ['pending', 'waiting', 'running'].includes(lastJobStatus);
+
return (
<>
-
+ {isDisabled ? (
+
+
+
+
+
+ ) : (
+
+ )}
{error && (
{
expect(ProjectsAPI.sync).toHaveBeenCalledWith(1);
});
+ test('disable button and set onClick to undefined on sync', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ {children}
+
+ );
+ });
+
+ expect(wrapper.find('Button').prop('isDisabled')).toBe(true);
+ expect(wrapper.find('Button').prop('onClick')).toBe(undefined);
+ });
+ test('should render tooltip on sync', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ {children}
+
+ );
+ });
+
+ expect(wrapper.find('Tooltip')).toHaveLength(1);
+ expect(wrapper.find('Tooltip').prop('content')).toEqual(
+ 'This project is currently on sync and cannot be clicked until sync process completed'
+ );
+ });
test('displays error modal after unsuccessful sync', async () => {
ProjectsAPI.sync.mockRejectedValue(
new Error({
|