add ProjectList websocket support

This commit is contained in:
Keith Grant 2020-07-02 09:29:56 -07:00
parent bdb97c173b
commit 9657117941
2 changed files with 91 additions and 3 deletions

View File

@ -13,6 +13,7 @@ import PaginatedDataList, {
ToolbarAddButton,
ToolbarDeleteButton,
} from '../../../components/PaginatedDataList';
import useWsProjects from './useWsProjects';
import { getQSConfig, parseQueryString } from '../../../util/qs';
import ProjectListItem from './ProjectListItem';
@ -29,7 +30,7 @@ function ProjectList({ i18n }) {
const [selected, setSelected] = useState([]);
const {
result: { projects, itemCount, actions },
result: { results, itemCount, actions },
error: contentError,
isLoading,
request: fetchProjects,
@ -41,13 +42,13 @@ function ProjectList({ i18n }) {
ProjectsAPI.readOptions(),
]);
return {
projects: response.data.results,
results: response.data.results,
itemCount: response.data.count,
actions: actionsResponse.data.actions,
};
}, [location]),
{
projects: [],
results: [],
itemCount: 0,
actions: {},
}
@ -57,6 +58,8 @@ function ProjectList({ i18n }) {
fetchProjects();
}, [fetchProjects]);
const projects = useWsProjects(results);
const isAllSelected =
selected.length === projects.length && selected.length > 0;
const {

View File

@ -0,0 +1,85 @@
import { useState, useEffect, useRef } from 'react';
export default function useWsProjects(initialProjects) {
const [projects, setProjects] = useState(initialProjects);
const [lastMessage, setLastMessage] = useState(null);
const ws = useRef(null);
useEffect(() => {
setProjects(initialProjects);
}, [initialProjects]);
useEffect(() => {
if (!lastMessage?.unified_job_id || lastMessage.type !== 'project_update') {
return;
}
const index = projects.findIndex(p => p.id === lastMessage.project_id);
if (index === -1) {
return;
}
const project = projects[index];
const updatedProject = {
...project,
summary_fields: {
...project.summary_fields,
last_job: {
id: lastMessage.unified_job_id,
status: lastMessage.status,
finished: lastMessage.finished,
},
},
};
setProjects([
...projects.slice(0, index),
updatedProject,
...projects.slice(index + 1),
]);
}, [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 projects;
}