Add project group info to Vuex

This commit is contained in:
D. Berge
2025-08-18 13:50:49 +02:00
parent 9072bbe389
commit 7c52ada922
4 changed files with 113 additions and 5 deletions

View File

@@ -1,3 +1,5 @@
import * as d3a from 'd3-array';
import { duration_to_ms, ms_to_duration, normalise_duration, add_durations } from '@/lib/durations';
/** Fetch projects from server /** Fetch projects from server
*/ */
@@ -8,6 +10,7 @@ async function refreshProjects ({commit, dispatch, state, rootState}) {
} }
commit('setProjectsLoading'); commit('setProjectsLoading');
const tstamp = new Date();
const pid = rootState.project.projectId; const pid = rootState.project.projectId;
const url = `/project`; const url = `/project`;
const init = { const init = {
@@ -17,10 +20,26 @@ async function refreshProjects ({commit, dispatch, state, rootState}) {
const res = await dispatch('api', [url, init, null, {silent:true}]); const res = await dispatch('api', [url, init, null, {silent:true}]);
if (res) { if (res) {
for (let index in res) {
const project = res[index];
if (!project.pid) {
console.warn("Project has no Project ID!");
continue;
}
const url = `/project/${project.pid}/summary`;
const init = {};
const summary = await dispatch('api', [url, init, null, {silent:true}]);
if (summary) {
res[index] = {...project, ...summary};
}
}
commit('setProjects', res); commit('setProjects', res);
commit('setProjectsTimestamp'); commit('setProjectsTimestamp', tstamp);
} }
commit('clearProjectsLoading'); commit('clearProjectsLoading');
dispatch('prepareGroups');
} }
/** Return a subset of projects from state.projects /** Return a subset of projects from state.projects
@@ -118,4 +137,83 @@ async function getProjects ({commit, dispatch, state}, [{pid, name, schema, grou
return {projects: filteredProjects, count}; return {projects: filteredProjects, count};
} }
export default { refreshProjects, getProjects };
async function prepareGroups ({commit, dispatch, state, rootState}) {
const groups = {};
for (const project of state.projects) {
if (!project.prod_distance) {
// This project has no production data (either not started yet
// or production data has not been imported) so we skip it.
continue;
}
if (!project.prod_duration.days) {
project.prod_duration = normalise_duration(project.prod_duration);
}
for (const name of project.groups) {
if (!(name in groups)) {
groups[name] = {
group: name,
num_projects: 0,
lines: 0,
points: 0,
sequences: 0,
// Shots:
prime: 0,
other: 0,
ntba: 0,
prod_duration: {
days: 0,
hours: 0,
minutes: 0,
seconds: 0,
milliseconds: 0
},
prod_distance: 0,
shooting_rate: [],
projects: []
};
}
const group = groups[name];
group.num_projects++;
group.lines = Math.max(group.lines, project.lines); // In case preplots changed
group.points = Math.max(group.points, project.total); // Idem
group.sequences += project.seq_final;
group.prime += project.prime;
group.other += project.other;
//group.ntba += project.ntba;
group.prod_duration = add_durations(group.prod_duration, project.prod_duration);
group.prod_distance += project.prod_distance;
group.shooting_rate.push(project.shooting_rate);
group.projects.push(project);
}
}
const grouplist = [];
for (const group of Object.values(groups)) {
group.shooting_rate_mean = d3a.mean(group.shooting_rate);
group.shooting_rate_sd = d3a.deviation(group.shooting_rate);
delete group.shooting_rate;
grouplist.push(group);
}
commit('setGroups', grouplist);
}
async function getGroups({commit, dispatch, state, rootState}) {
if (!state.groups.length) {
await dispatch('refreshProjects');
}
return state.groups;
}
export default { refreshProjects, getProjects, prepareGroups, getGroups };

View File

@@ -3,7 +3,7 @@ function projects (state) {
return state.projects; return state.projects;
} }
function projectGroups (state) { function projectGroupNames (state) {
return [...new Set(state.projects.map(i => i.groups).flat())].sort(); return [...new Set(state.projects.map(i => i.groups).flat())].sort();
} }
@@ -15,4 +15,8 @@ function projectsLoading (state) {
return !!state.loading; return !!state.loading;
} }
export default { projects, projectGroups, projectCount, projectsLoading }; function groups (state) {
return state.groups;
}
export default { projects, projectGroupNames, projectCount, projectsLoading, groups };

View File

@@ -39,10 +39,15 @@ function abortProjectsLoading (state) {
state.loading = null; state.loading = null;
} }
function setGroups (state, groups) {
state.groups = Object.freeze(groups);
}
export default { export default {
setProjects, setProjects,
setProjectsLoading, setProjectsLoading,
clearProjectsLoading, clearProjectsLoading,
setProjectsTimestamp, setProjectsTimestamp,
setProjectsETag setProjectsETag,
setGroups
}; };

View File

@@ -1,5 +1,6 @@
const state = () => ({ const state = () => ({
projects: Object.freeze([]), projects: Object.freeze([]),
groups: Object.freeze([]),
loading: null, loading: null,
timestamp: null, timestamp: null,
etag: null, etag: null,