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