1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-30 22:21:13 +03:00

add template list websocket support

This commit is contained in:
Keith Grant 2020-07-10 15:55:12 -07:00
parent 09dcb91c09
commit 981c9527b2
2 changed files with 122 additions and 8 deletions

View File

@ -17,7 +17,7 @@ import PaginatedDataList, {
} from '../../../components/PaginatedDataList';
import useRequest, { useDeleteItems } from '../../../util/useRequest';
import { getQSConfig, parseQueryString } from '../../../util/qs';
import useWsTemplates from './useWsTemplates';
import AddDropDownButton from '../../../components/AddDropDownButton';
import TemplateListItem from './TemplateListItem';
@ -36,27 +36,27 @@ function TemplateList({ i18n }) {
const [selected, setSelected] = useState([]);
const {
result: { templates, count, jtActions, wfjtActions },
result: { results, count, jtActions, wfjtActions },
error: contentError,
isLoading,
request: fetchTemplates,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
const results = await Promise.all([
const responses = await Promise.all([
UnifiedJobTemplatesAPI.read(params),
JobTemplatesAPI.readOptions(),
WorkflowJobTemplatesAPI.readOptions(),
]);
return {
templates: results[0].data.results,
count: results[0].data.count,
jtActions: results[1].data.actions,
wfjtActions: results[2].data.actions,
results: responses[0].data.results,
count: responses[0].data.count,
jtActions: responses[1].data.actions,
wfjtActions: responses[2].data.actions,
};
}, [location]),
{
templates: [],
results: [],
count: 0,
jtActions: {},
wfjtActions: {},
@ -67,6 +67,8 @@ function TemplateList({ i18n }) {
fetchTemplates();
}, [fetchTemplates]);
const templates = useWsTemplates(results);
const isAllSelected =
selected.length === templates.length && selected.length > 0;
const {

View File

@ -0,0 +1,112 @@
import { useState, useEffect, useRef } from 'react';
export default function useWsTemplates(initialTemplates) {
const [templates, setTemplates] = useState(initialTemplates);
const [lastMessage, setLastMessage] = useState(null);
const ws = useRef(null);
useEffect(() => {
setTemplates(initialTemplates);
}, [initialTemplates]);
// x = {
// unified_job_id: 548,
// status: 'pending',
// type: 'job',
// group_name: 'jobs',
// unified_job_template_id: 26,
// };
useEffect(
function parseWsMessage() {
if (!lastMessage?.unified_job_id) {
return;
}
const index = templates.findIndex(
t => t.id === lastMessage.unified_job_template_id
);
if (index === -1) {
return;
}
const template = templates[index];
const updated = [...templates];
updated[index] = updateTemplate(template, lastMessage);
setTemplates(updated);
},
[lastMessage] // eslint-disable-line react-hooks/exhaustive-deps
);
useEffect(() => {
ws.current = new WebSocket(`wss://${window.location.host}/websocket/`);
const connect = () => {
const xrftoken = `; ${document.cookie}`
.split('; csrftoken=')
.pop()
.split(';')
.shift();
ws.current.send(
JSON.stringify({
xrftoken,
groups: {
jobs: ['status_changed'],
control: ['limit_reached_1'],
},
})
);
};
ws.current.onopen = connect;
ws.current.onmessage = e => {
setLastMessage(JSON.parse(e.data));
};
ws.current.onclose = e => {
// eslint-disable-next-line no-console
console.debug('Socket closed. Reconnecting...', e);
setTimeout(() => {
connect();
}, 1000);
};
ws.current.onerror = err => {
// eslint-disable-next-line no-console
console.debug('Socket error: ', err, 'Disconnecting...');
ws.current.close();
};
return () => {
ws.current.close();
};
}, []);
return templates;
}
function updateTemplate(template, message) {
const recentJobs = [...(template.summary_fields.recent_jobs || [])];
const job = {
id: message.unified_job_id,
status: message.status,
finished: message.finished,
type: message.type,
};
const index = recentJobs.findIndex(j => j.id === job.id);
if (index > -1) {
recentJobs[index] = {
...recentJobs[index],
...job,
};
} else {
recentJobs.unshift(job);
}
return {
...template,
summary_fields: {
...template.summary_fields,
recent_jobs: recentJobs.slice(0, 10),
},
};
}