diff --git a/awx/ui_next/src/api/models/InventorySources.js b/awx/ui_next/src/api/models/InventorySources.js
index 292aebf290..8d20076ba8 100644
--- a/awx/ui_next/src/api/models/InventorySources.js
+++ b/awx/ui_next/src/api/models/InventorySources.js
@@ -1,8 +1,11 @@
import Base from '../Base';
import NotificationsMixin from '../mixins/Notifications.mixin';
import LaunchUpdateMixin from '../mixins/LaunchUpdate.mixin';
+import SchedulesMixin from '../mixins/Schedules.mixin';
-class InventorySources extends LaunchUpdateMixin(NotificationsMixin(Base)) {
+class InventorySources extends LaunchUpdateMixin(
+ NotificationsMixin(SchedulesMixin(Base))
+) {
constructor(http) {
super(http);
this.baseUrl = '/api/v2/inventory_sources/';
diff --git a/awx/ui_next/src/components/Schedule/Schedule.jsx b/awx/ui_next/src/components/Schedule/Schedule.jsx
index 6282e50bfb..260655f27c 100644
--- a/awx/ui_next/src/components/Schedule/Schedule.jsx
+++ b/awx/ui_next/src/components/Schedule/Schedule.jsx
@@ -35,7 +35,6 @@ function Schedule({ i18n, setBreadcrumb, unifiedJobTemplate }) {
try {
const { data } = await SchedulesAPI.readDetail(scheduleId);
setSchedule(data);
- setBreadcrumb(unifiedJobTemplate, data);
} catch (err) {
setContentError(err);
} finally {
@@ -44,8 +43,14 @@ function Schedule({ i18n, setBreadcrumb, unifiedJobTemplate }) {
};
loadData();
- }, [location.pathname, scheduleId, unifiedJobTemplate, setBreadcrumb]);
+ }, [location.pathname, scheduleId]);
+ useEffect(() => {
+ if (schedule) {
+ setBreadcrumb(unifiedJobTemplate, schedule);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [schedule, unifiedJobTemplate]);
const tabsArray = [
{
name: (
diff --git a/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.jsx b/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.jsx
index bc04a578d8..0cb8a51eb5 100644
--- a/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.jsx
+++ b/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.jsx
@@ -43,7 +43,7 @@ function ScheduleListItem({ i18n, isSelected, onSelect, schedule }) {
switch (schedule.summary_fields.unified_job_template.unified_job_type) {
case 'inventory_update':
- scheduleBaseUrl = `/inventories/${schedule.summary_fields.inventory.id}/sources/${schedule.summary_fields.unified_job_template.id}/schedules/${schedule.id}`;
+ scheduleBaseUrl = `/inventories/inventory/${schedule.summary_fields.inventory.id}/sources/${schedule.summary_fields.unified_job_template.id}/schedules/${schedule.id}`;
break;
case 'job':
scheduleBaseUrl = `/templates/job_template/${schedule.summary_fields.unified_job_template.id}/schedules/${schedule.id}`;
@@ -98,31 +98,31 @@ function ScheduleListItem({ i18n, isSelected, onSelect, schedule }) {
)}
,
-
-
- {schedule.summary_fields.user_capabilities.edit ? (
-
-
-
- ) : (
- ''
- )}
- ,
]}
/>
+
+
+ {schedule.summary_fields.user_capabilities.edit ? (
+
+
+
+ ) : (
+ ''
+ )}
+
);
diff --git a/awx/ui_next/src/screens/Inventory/Inventories.jsx b/awx/ui_next/src/screens/Inventory/Inventories.jsx
index c4c18e76cf..9ddf8723c0 100644
--- a/awx/ui_next/src/screens/Inventory/Inventories.jsx
+++ b/awx/ui_next/src/screens/Inventory/Inventories.jsx
@@ -27,7 +27,7 @@ class Inventories extends Component {
};
}
- setBreadCrumbConfig = (inventory, nested) => {
+ setBreadCrumbConfig = (inventory, nested, schedule) => {
const { i18n } = this.props;
if (!inventory) {
return;
@@ -80,6 +80,11 @@ class Inventories extends Component {
[`${inventorySourcesPath}/${nested?.id}`]: `${nested?.name}`,
[`${inventorySourcesPath}/${nested?.id}/details`]: i18n._(t`Details`),
[`${inventorySourcesPath}/${nested?.id}/edit`]: i18n._(t`Edit details`),
+ [`${inventorySourcesPath}/${nested?.id}/schedules`]: i18n._(t`Schedules`),
+ [`${inventorySourcesPath}/${nested?.id}/schedules/${schedule?.id}`]: `${schedule?.name}`,
+ [`${inventorySourcesPath}/${nested?.id}/schedules/${schedule?.id}/details`]: i18n._(
+ t`Schedule Details`
+ ),
};
this.setState({ breadcrumbConfig });
};
diff --git a/awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx b/awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx
index c9a7a730ed..ecd065a57b 100644
--- a/awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx
@@ -19,6 +19,7 @@ import {
OrganizationsAPI,
} from '../../../api';
import { TabbedCardHeader } from '../../../components/Card';
+import { Schedules } from '../../../components/Schedule';
import CardCloseButton from '../../../components/CardCloseButton';
import ContentError from '../../../components/ContentError';
import ContentLoading from '../../../components/ContentLoading';
@@ -64,6 +65,15 @@ function InventorySource({ i18n, inventory, setBreadcrumb, me }) {
}
}, [inventory, source, setBreadcrumb]);
+ const loadSchedules = params =>
+ InventorySourcesAPI.readSchedules(source?.id, params);
+
+ const createSchedule = data =>
+ InventorySourcesAPI.createSchedule(source?.id, data);
+
+ const loadScheduleOptions = () =>
+ InventorySourcesAPI.readScheduleOptions(source?.id);
+
const tabsArray = [
{
name: (
@@ -104,7 +114,9 @@ function InventorySource({ i18n, inventory, setBreadcrumb, me }) {
return (
<>
- {['edit'].some(name => location.pathname.includes(name)) ? null : (
+ {['edit', 'schedules/'].some(name =>
+ location.pathname.includes(name)
+ ) ? null : (
@@ -144,6 +156,20 @@ function InventorySource({ i18n, inventory, setBreadcrumb, me }) {
apiModel={InventorySourcesAPI}
/>
+
+
+ setBreadcrumb(inventory, source, schedule)
+ }
+ unifiedJobTemplate={source}
+ loadSchedules={loadSchedules}
+ loadScheduleOptions={loadScheduleOptions}
+ />
+