Fix continuous scroll in sv5 joblist, rework joblist logic

This commit is contained in:
Christoph Kluge 2025-06-27 18:42:18 +02:00
parent 805ea91fc2
commit b8c30b5703
3 changed files with 49 additions and 64 deletions

View File

@ -14,7 +14,7 @@
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext, untrack } from "svelte";
import { import {
queryStore, queryStore,
gql, gql,
@ -94,16 +94,12 @@
} }
`; `;
/* Var Init */
let lastFilter = [];
let lastSorting = null;
/* State Init */ /* State Init */
let headerPaddingTop = $state(0); let headerPaddingTop = $state(0);
let jobs = $state([]); let jobs = $state([]);
let filter = $state([...filterBuffer]); let filter = $state([...filterBuffer]);
let page = $state(1); let page = $state(1);
let itemsPerPage = $state(usePaging ? (ccconfig?.plot_list_jobsPerPag || 10) : 10); let itemsPerPage = $state(usePaging ? (ccconfig?.plot_list_jobsPerPage || 10) : 10);
let triggerMetricRefresh = $state(false); let triggerMetricRefresh = $state(false);
let tableWidth = $state(0); let tableWidth = $state(0);
@ -118,18 +114,11 @@
client: client, client: client,
query: query, query: query,
variables: { paging, sorting, filter }, variables: { paging, sorting, filter },
requestPolicy: "network-only",
}) })
); );
/* Effects */ /* Effects */
$effect(() => {
if ($jobsStore?.data) {
matchedListJobs = $jobsStore.data.jobs.count;
} else {
matchedListJobs = -1
}
});
$effect(() => { $effect(() => {
if (!usePaging) { if (!usePaging) {
window.addEventListener('scroll', () => { window.addEventListener('scroll', () => {
@ -148,56 +137,32 @@
}); });
$effect(() => { $effect(() => {
// Triggers (Except Paging) //Triggers
sorting
filter filter
// Continous Scroll: Reset jobs and paging if parameters change: Existing entries will not match new selections sorting
// Reset Continous Jobs
if (!usePaging) { if (!usePaging) {
jobs = [];
page = 1; page = 1;
} }
}); });
$effect(() => { $effect(() => {
if ($initialized && $jobsStore?.data) { if ($jobsStore?.data) {
if (usePaging) { untrack(() => {
jobs = [...$jobsStore.data.jobs.items] handleJobs($jobsStore.data.jobs.items);
} else { // Prevents jump to table head in continiuous mode, only if no change in sort or filter });
if (equalsCheck(filter, lastFilter) && equalsCheck(sorting, lastSorting)) {
// console.log('Both Equal: Continuous Addition ... Set None')
jobs = jobs.concat([...$jobsStore.data.jobs.items])
} else if (equalsCheck(filter, lastFilter)) {
// console.log('Filter Equal: Continuous Reset ... Set lastSorting')
lastSorting = { ...sorting }
jobs = [...$jobsStore.data.jobs.items]
} else if (equalsCheck(sorting, lastSorting)) {
// console.log('Sorting Equal: Continuous Reset ... Set lastFilter')
lastFilter = [ ...filter ]
jobs = [...$jobsStore.data.jobs.items]
} else {
// console.log('None Equal: Continuous Reset ... Set lastBoth')
lastSorting = { ...sorting }
lastFilter = [ ...filter ]
jobs = [...$jobsStore.data.jobs.items]
}
}
}; };
}); });
/* Functions */ /* Functions */
// Force refresh list with existing unchanged variables (== usually would not trigger reactivity) // Force refresh list with existing unchanged variables
export function refreshJobs() { export function refreshJobs() {
if (!usePaging) { if (usePaging) {
jobs = []; // Empty Joblist before refresh, prevents infinite buildup paging = {...paging}
} else {
page = 1; page = 1;
} }
jobsStore = queryStore({ };
client: client,
query: query,
variables: { paging, sorting, filter },
requestPolicy: "network-only",
});
}
export function refreshAllMetrics() { export function refreshAllMetrics() {
// Refresh Job Metrics (Downstream will only query for running jobs) // Refresh Job Metrics (Downstream will only query for running jobs)
@ -214,19 +179,38 @@
if (minRunningFor && minRunningFor > 0) { if (minRunningFor && minRunningFor > 0) {
filters.push({ minRunningFor }); filters.push({ minRunningFor });
} }
filter = filters; filter = [...filters];
}
};
function handleJobs(newJobs) {
if (newJobs) {
if (usePaging) {
console.log('New Paging', $state.snapshot(paging))
jobs = [...newJobs]
} else {
if ($state.snapshot(page) == 1) {
console.log('Page 1 Reset', [...newJobs])
jobs = [...newJobs]
} else {
console.log('Add Jobs', $state.snapshot(jobs), [...newJobs])
jobs = jobs.concat([...newJobs])
}
}
matchedListJobs = $jobsStore.data.jobs.count;
} else {
matchedListJobs = -1
} }
page = 1;
}; };
function updateConfiguration(value, newPage) { function updateConfiguration(value, newPage) {
updateConfigurationMutation({ updateConfigurationMutation({
name: "plot_list_jobsPerPage", name: "plot_list_jobsPerPage",
value: value, value: value.toString(),
}).subscribe((res) => { }).subscribe((res) => {
if (res.fetching === false && !res.error) { if (res.fetching === false && !res.error) {
jobs = [] // Empty List itemsPerPage = value
paging = { itemsPerPage: value, page: newPage }; // Trigger reload of jobList page = newPage // Trigger reload of jobList
} else if (res.fetching === false && res.error) { } else if (res.fetching === false && res.error) {
throw res.error; throw res.error;
} }
@ -307,7 +291,7 @@
</tr> </tr>
{:else} {:else}
{#each jobs as job (job.id)} {#each jobs as job (job.id)}
<JobListRow bind:triggerMetricRefresh {job} {metrics} {plotWidth} {showFootprint} previousSelect={selectedJobs.includes(job.id)} <JobListRow {triggerMetricRefresh} {job} {metrics} {plotWidth} {showFootprint} previousSelect={selectedJobs.includes(job.id)}
selectJob={(detail) => selectedJobs = [...selectedJobs, detail]} selectJob={(detail) => selectedJobs = [...selectedJobs, detail]}
unselectJob={(detail) => selectedJobs = selectedJobs.filter(item => item !== detail)} unselectJob={(detail) => selectedJobs = selectedJobs.filter(item => item !== detail)}
/> />
@ -339,10 +323,10 @@
totalItems={matchedListJobs} totalItems={matchedListJobs}
updatePaging={(detail) => { updatePaging={(detail) => {
if (detail.itemsPerPage != itemsPerPage) { if (detail.itemsPerPage != itemsPerPage) {
updateConfiguration(detail.itemsPerPage.toString(), detail.page); updateConfiguration(detail.itemsPerPage, detail.page);
} else { } else {
jobs = [] itemsPerPage = detail.itemsPerPage
paging = { itemsPerPage: detail.itemsPerPage, page: detail.page }; page = detail.page
} }
}} }}
/> />

View File

@ -21,7 +21,7 @@
/* Svelte 5 Props */ /* Svelte 5 Props */
let { let {
triggerMetricRefresh = $bindable(false), triggerMetricRefresh = false,
job, job,
metrics, metrics,
plotWidth, plotWidth,
@ -35,7 +35,7 @@
/* Const Init */ /* Const Init */
const client = getContextClient(); const client = getContextClient();
const jobId = job.id; const jobId = job.id;
const cluster = getContext("clusters").find((c) => c.name == job.cluster); const cluster = getContext("clusters");
const scopes = (job.numNodes == 1) const scopes = (job.numNodes == 1)
? (job.numAcc >= 1) ? (job.numAcc >= 1)
? ["core", "accelerator"] ? ["core", "accelerator"]
@ -151,6 +151,7 @@
.map((jobMetric) => { .map((jobMetric) => {
if (jobMetric.data) { if (jobMetric.data) {
return { return {
name: jobMetric.data.name,
disabled: checkMetricDisabled( disabled: checkMetricDisabled(
jobMetric.data.name, jobMetric.data.name,
job.cluster, job.cluster,
@ -195,7 +196,7 @@
/> />
</td> </td>
{/if} {/if}
{#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric || i)} {#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric?.name || i)}
<td> <td>
<!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case--> <!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case-->
{#if metric.disabled == false && metric.data} {#if metric.disabled == false && metric.data}
@ -207,7 +208,7 @@
series={metric.data.metric.series} series={metric.data.metric.series}
statisticsSeries={metric.data.metric.statisticsSeries} statisticsSeries={metric.data.metric.statisticsSeries}
metric={metric.data.name} metric={metric.data.name}
{cluster} cluster={cluster.find((c) => c.name == job.cluster)}
subCluster={job.subCluster} subCluster={job.subCluster}
isShared={job.exclusive != 1} isShared={job.exclusive != 1}
numhwthreads={job.numHWThreads} numhwthreads={job.numHWThreads}