diff --git a/awx/ui/src/screens/Instances/InstanceEndPointList/InstanceEndPointList.js b/awx/ui/src/screens/Instances/InstanceEndPointList/InstanceEndPointList.js
new file mode 100644
index 0000000000..e3d1131941
--- /dev/null
+++ b/awx/ui/src/screens/Instances/InstanceEndPointList/InstanceEndPointList.js
@@ -0,0 +1,188 @@
+import React, { useCallback, useEffect, useState } from 'react';
+import { t } from '@lingui/macro';
+import { CardBody } from 'components/Card';
+import PaginatedTable, {
+ getSearchableKeys,
+ HeaderCell,
+ HeaderRow,
+ ToolbarAddButton,
+} from 'components/PaginatedTable';
+import AddEndpointModal from 'components/AddEndpointModal';
+import useToast from 'hooks/useToast';
+import { getQSConfig } from 'util/qs';
+import { useParams } from 'react-router-dom';
+import useRequest from 'hooks/useRequest';
+import DataListToolbar from 'components/DataListToolbar';
+import { InstancesAPI, ReceptorAPI } from 'api';
+import useExpanded from 'hooks/useExpanded';
+import useSelected from 'hooks/useSelected';
+import InstanceEndPointListItem from './InstanceEndPointListItem';
+
+const QS_CONFIG = getQSConfig('peer', {
+ page: 1,
+ page_size: 20,
+ order_by: 'pk',
+});
+
+function InstanceEndPointList({ setBreadcrumb }) {
+ const { id } = useParams();
+ const [isAddEndpointModalOpen, setisAddEndpointModalOpen] = useState(false);
+ const { Toast, toastProps } = useToast();
+ const {
+ isLoading,
+ error: contentError,
+ request: fetchEndpoints,
+ result: { instance, endpoints, count, relatedSearchableKeys, searchableKeys },
+ } = useRequest(
+ useCallback(async () => {
+ const [
+ { data: detail },
+ {
+ data: { results },
+ },
+ actions,
+ ] = await Promise.all([
+ InstancesAPI.readDetail(id),
+ ReceptorAPI.read(),
+ InstancesAPI.readOptions(),
+ ]);
+
+ const endpoint_list = []
+
+ for(let q = 0; q < results.length; q++) {
+ const receptor = results[q];
+ if(id.toString() === receptor.instance.toString()) {
+ endpoint_list.push(receptor);
+ }
+ }
+
+ return {
+ instance: detail,
+ endpoints: endpoint_list,
+ count: endpoint_list.length,
+ relatedSearchableKeys: (actions?.data?.related_search_fields || []).map(
+ (val) => val.slice(0, -8)
+ ),
+ searchableKeys: getSearchableKeys(actions.data.actions?.GET),
+ };
+ }, [id]),
+ {
+ instance: {},
+ endpoints: [],
+ count: 0,
+ relatedSearchableKeys: [],
+ searchableKeys: [],
+ }
+ );
+
+ useEffect(() => {
+ fetchEndpoints();
+ }, [fetchEndpoints]);
+
+ useEffect(() => {
+ if (instance) {
+ setBreadcrumb(instance);
+ }
+ }, [instance, setBreadcrumb]);
+
+ const { expanded, isAllExpanded, handleExpand, expandAll } =
+ useExpanded(endpoints);
+ const { selected, isAllSelected, handleSelect, clearSelected, selectAll } =
+ useSelected(endpoints);
+
+ const handleEndpointDelete = async () => {
+ // console.log(selected)
+ // InstancesAPI.updateReceptorAddresses(instance.id, values);
+ }
+
+ const isHopNode = instance.node_type === 'hop';
+ const isExecutionNode = instance.node_type === 'execution';
+
+ return (
+
+
+ {t`Address`}
+ {t`Port`}
+
+ }
+ renderToolbar={(props) => (
+ setisAddEndpointModalOpen(true)}
+ />
+ ),
+ (isExecutionNode || isHopNode) && (
+ handleEndpointDelete()}
+ />
+ ),
+ ]}
+ />
+ )}
+ renderRow={(endpoint, index) => (
+ row.id === endpoint.id)}
+ onSelect={() => handleSelect(endpoint)}
+ isExpanded={expanded.some((row) => row.id === endpoint.id)}
+ onExpand={() => handleExpand(endpoint)}
+ key={endpoint.id}
+ peerInstance={endpoint}
+ rowIndex={index}
+ />
+ )}
+ />
+ {isAddEndpointModalOpen && (
+ setisAddEndpointModalOpen(false)}
+ title={t`New endpoint`}
+ instance={instance}
+ />
+ )}
+
+
+ );
+}
+
+export default InstanceEndPointList;
diff --git a/awx/ui/src/screens/Instances/InstanceEndPointList/InstanceEndPointListItem.js b/awx/ui/src/screens/Instances/InstanceEndPointList/InstanceEndPointListItem.js
new file mode 100644
index 0000000000..2a1fd5dddb
--- /dev/null
+++ b/awx/ui/src/screens/Instances/InstanceEndPointList/InstanceEndPointListItem.js
@@ -0,0 +1,54 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { t } from '@lingui/macro';
+import 'styled-components/macro';
+import { Tr, Td } from '@patternfly/react-table';
+
+function InstanceEndPointListItem({
+ peerInstance,
+ isSelected,
+ onSelect,
+ isExpanded,
+ onExpand,
+ rowIndex,
+}) {
+ const labelId = `check-action-${peerInstance.id}`;
+ return (
+
+ |
+
+ |
+
+
+
+ {peerInstance.address}
+
+ |
+
+
+
+ {peerInstance.port}
+
+ |
+
+
+ );
+}
+
+export default InstanceEndPointListItem;
diff --git a/awx/ui/src/screens/Instances/InstanceEndPointList/index.js b/awx/ui/src/screens/Instances/InstanceEndPointList/index.js
new file mode 100644
index 0000000000..9e5f69dd34
--- /dev/null
+++ b/awx/ui/src/screens/Instances/InstanceEndPointList/index.js
@@ -0,0 +1 @@
+export { default } from './InstanceEndPointList';
diff --git a/awx/ui/src/screens/Instances/InstancePeers/InstancePeerList.js b/awx/ui/src/screens/Instances/InstancePeers/InstancePeerList.js
index 2af9d3d43b..b56be6ba0d 100644
--- a/awx/ui/src/screens/Instances/InstancePeers/InstancePeerList.js
+++ b/awx/ui/src/screens/Instances/InstancePeers/InstancePeerList.js
@@ -47,7 +47,7 @@ function InstancePeerList({ setBreadcrumb }) {
const [
{ data: detail },
{
- data: { results, count: itemNumber },
+ data: { results },
},
actions,
instances,
@@ -72,7 +72,7 @@ function InstancePeerList({ setBreadcrumb }) {
return {
instance: detail,
peers: address_list,
- count: itemNumber,
+ count: address_list.length,
relatedSearchableKeys: (actions?.data?.related_search_fields || []).map(
(val) => val.slice(0, -8)
),
@@ -283,7 +283,7 @@ function InstancePeerList({ setBreadcrumb }) {
key="disassociate"
onDisassociate={handlePeersDiassociate}
itemsToDisassociate={selected}
- modalTitle={t`Remove instance from peers?`}
+ modalTitle={t`Remove peers?`}
/>
),
]}
diff --git a/awx/ui/src/screens/Instances/InstancePeers/InstancePeerListItem.js b/awx/ui/src/screens/Instances/InstancePeers/InstancePeerListItem.js
index 0cd6e7e6da..796f20572a 100644
--- a/awx/ui/src/screens/Instances/InstancePeers/InstancePeerListItem.js
+++ b/awx/ui/src/screens/Instances/InstancePeers/InstancePeerListItem.js
@@ -43,7 +43,6 @@ function InstancePeerListItem({
}}
dataLabel={t`Selected`}
/>
-
{peerInstance.address}
diff --git a/awx/ui/src/screens/Instances/Instances.js b/awx/ui/src/screens/Instances/Instances.js
index eefc7d2716..9836ffa290 100644
--- a/awx/ui/src/screens/Instances/Instances.js
+++ b/awx/ui/src/screens/Instances/Instances.js
@@ -25,6 +25,7 @@ function Instances() {
[`/instances/${instance.id}`]: `${instance.hostname}`,
[`/instances/${instance.id}/details`]: t`Details`,
[`/instances/${instance.id}/peers`]: t`Peers`,
+ [`/instances/${instance.id}/endpoints`]: t`Endpoints`,
[`/instances/${instance.id}/edit`]: t`Edit Instance`,
});
}, []);
|