Compare commits

...

5 Commits

Author SHA1 Message Date
D. Berge
6b6f5ab511 Link from group summary to individual projects 2025-08-20 12:06:20 +02:00
D. Berge
7d8c78648d Don't request summaries in ProjectList.
Those will be populated directly by Vuex.
2025-08-20 12:05:44 +02:00
D. Berge
faf7e9c98f Try to improve responsiveness when refreshing project list 2025-08-20 12:05:05 +02:00
D. Berge
abf2709705 Expand groups router definition 2025-08-20 12:04:26 +02:00
D. Berge
f5dfafd85a Make event handler more specific 2025-08-20 12:03:53 +02:00
5 changed files with 66 additions and 41 deletions

View File

@@ -85,7 +85,9 @@ export default {
},
handleProject (context, {payload}) {
this.refreshProjects();
if (payload?.table == "public") {
this.refreshProjects();
}
},
registerNotificationHandlers () {

View File

@@ -211,7 +211,7 @@ Vue.use(VueRouter)
component: GroupList,
meta: {
breadcrumbs: [
{ text: "Groups", href: "/groups", disabled: true }
{ text: "Comparisons", href: "/groups", disabled: true }
],
appBarExtension: {
// component: DougalAppBarExtensionProjectList
@@ -230,8 +230,22 @@ Vue.use(VueRouter)
component: Group,
meta: {
breadcrumbs: [
{ text: "Groups", href: "/groups" },
{ text: "Comparisons", href: "/groups" },
{ text: (ctx) => ctx.$route.params.group }
/*
{
text: (ctx) => ctx.$store.state.project.projectName || "…",
href: (ctx) => `/projects/${ctx.$store.state.project.projectId || ctx.$route.params.project || ""}/`,
title: (ctx) => Object.entries(ctx.$store.getters.projectConfiguration?.organisations ?? {}).map( ([org, ops]) => `* ${org}: ${Object.entries(ops).filter( ([k, v]) => v ).map( ([k, v]) => k ).join(", ")}`).join("\n"),
organisations: (ctx) => ctx.$store.getters.projectConfiguration?.organisations ?? {}
}
*/
],
/*
appBarExtension: {
component: DougalAppBarExtensionGroup
}
*/
},
children: [
]

View File

@@ -5,6 +5,17 @@ import { duration_to_ms, ms_to_duration, normalise_duration, add_durations } fro
*/
async function refreshProjects ({commit, dispatch, state, rootState}) {
async function getSummary (project) {
const url = `/project/${project.pid}/summary`;
const init = {};
const summary = await dispatch('api', [url, init, null, {silent:true}]);
if (summary) {
return {...project, ...summary};
} else {
return project;
}
}
if (state.loading) {
commit('abortProjectsLoading');
}
@@ -20,23 +31,22 @@ async function refreshProjects ({commit, dispatch, state, rootState}) {
const res = await dispatch('api', [url, init, null, {silent:true}]);
if (res) {
for (let index in res) {
const project = res[index];
if (!project.pid) {
console.warn("Project has no Project ID!");
continue;
}
let projects;
const url = `/project/${project.pid}/summary`;
const init = {};
const summary = await dispatch('api', [url, init, null, {silent:true}]);
if (summary) {
res[index] = {...project, ...summary};
}
if (res.some( project => project.pid == null )) {
console.warn("At least one project found with no PID!");
projects = res.filter( project => project.pid != null );
} else {
projects = res;
}
commit('setProjects', res);
commit('setProjects', projects); // First without summaries
commit('setProjectsTimestamp', tstamp);
projects = await Promise.all(projects.map( getSummary ));
commit('setProjects', projects); // Then with summaries
}
commit('clearProjectsLoading');
dispatch('prepareGroups');

View File

@@ -48,7 +48,13 @@
</template>
<template v-slot:item.pid="{item, value}">
<v-chip label small outlined>{{ value }}</v-chip>
<v-chip
label
small
outlined
:href="`/projects/${item.pid}`"
:color="!item.archived ? 'primary' : ''"
>{{ value }}</v-chip>
</template>
<template v-slot:item.fsp="{item, value}">

View File

@@ -189,19 +189,20 @@ export default {
...mapGetters(['loading', 'projects'])
},
watch: {
async projects () {
await this.load();
}
},
methods: {
async list () {
this.items = [...this.projects];
},
async summary (item) {
const details = await this.api([`/project/${item.pid}/summary`]);
if (details) {
return Object.assign({}, details, item);
}
},
title (item) {
if (item.organisations) {
return "Access:\n" + Object.entries(item.organisations).map( org =>
@@ -212,30 +213,22 @@ export default {
},
async load () {
await this.refreshProjects();
if (!this.projects.length) {
this.refreshProjects();
}
await this.list();
const promises = [];
for (const key in this.items) {
const item = this.items[key];
const promise = this.summary(item)
.then( expanded => {
if (expanded) {
this.$set(this.items, key, expanded);
}
});
promises.push(promise);
},
handlerLoad (context, {payload}) {
if (payload?.table == "public") {
this.load();
}
},
registerNotificationHandlers () {
this.$store.dispatch('registerHandler', {
table: 'project`',
handler: (context, message) => {
if (message.payload?.table == "public") {
this.load();
}
}
handler: this.handlerLoad
});
},