2022-06-22 11:20:57 +02:00
< script >
import { onMount , getContext } from 'svelte'
2023-07-26 13:44:06 +02:00
import { init , convert2uplot } from './utils.js'
2023-12-01 13:22:01 +01:00
import { Table , Row , Col , Button , Icon , Card , Spinner } from 'sveltestrap'
2023-05-03 16:41:17 +02:00
import { queryStore , gql , getContextClient } from '@urql/svelte'
2022-06-22 11:20:57 +02:00
import Filters from './filters/Filters.svelte'
import JobList from './joblist/JobList.svelte'
import Sorting from './joblist/SortSelection.svelte'
import Refresher from './joblist/Refresher.svelte'
2023-08-11 13:34:30 +02:00
import Histogram from './plots/Histogram.svelte'
2022-06-22 11:20:57 +02:00
import MetricSelection from './MetricSelection.svelte'
2023-12-01 13:22:01 +01:00
import HistogramSelection from './HistogramSelection.svelte'
import PlotTable from './PlotTable.svelte'
2022-06-22 11:20:57 +02:00
import { scramble , scrambleNames } from './joblist/JobInfo.svelte'
const { query : initq } = init()
const ccconfig = getContext('cc-config')
export let user
export let filterPresets
2023-06-06 16:52:40 +02:00
let filterComponent; // see why here: https://stackoverflow.com/questions/58287729/how-can-i-export-a-function-from-a-svelte-component-that-changes-a-value-in-the
let jobList;
let jobFilters = [];
2022-06-22 11:20:57 +02:00
let sorting = { field : 'startTime' , order : 'DESC' } , isSortingOpen = false
let metrics = ccconfig.plot_list_selectedMetrics, isMetricsSelectionOpen = false
2023-12-06 12:58:03 +01:00
let w1, w2, histogramHeight = 250, isHistogramSelectionOpen = false
2023-03-31 17:18:16 +02:00
let selectedCluster = filterPresets?.cluster ? filterPresets.cluster : null
2023-11-28 09:58:36 +01:00
let showFootprint = filterPresets.cluster
? !!ccconfig[`plot_list_showFootprint:${ filterPresets . cluster } `]
: !!ccconfig.plot_list_showFootprint
2023-12-06 12:58:03 +01:00
2024-02-09 16:21:11 +01:00
$: metricsInHistograms = selectedCluster ? (ccconfig[`user_view_histogramMetrics:${ selectedCluster } `] || []) : (ccconfig.user_view_histogramMetrics || [])
2022-06-22 11:20:57 +02:00
2023-05-12 11:19:37 +02:00
const client = getContextClient();
2023-05-08 18:06:58 +02:00
$: stats = queryStore({
2023-05-12 11:19:37 +02:00
client: client,
2023-05-03 16:41:17 +02:00
query: gql`
2023-12-05 11:59:01 +01:00
query($jobFilters: [JobFilter!]!, $metricsInHistograms: [String!]) {
2023-12-01 13:22:01 +01:00
jobsStatistics(filter: $jobFilters, metrics: $metricsInHistograms) {
2023-05-12 11:19:37 +02:00
totalJobs
shortJobs
totalWalltime
totalCoreHours
histDuration { count , value }
histNumNodes { count , value }
2023-12-05 15:30:40 +01:00
histMetrics { metric , unit , data { min , max , count , bin } }
2023-05-12 11:19:37 +02:00
}}`,
2023-12-08 12:03:04 +01:00
variables: { jobFilters , metricsInHistograms }
2022-06-22 11:20:57 +02:00
})
2023-06-06 16:52:40 +02:00
onMount(() => filterComponent.update())
2022-06-22 11:20:57 +02:00
< / script >
< Row >
{ #if $initq . fetching }
< Col >
< Spinner / >
< / Col >
{ :else if $initq . error }
< Col xs = "auto" >
< Card body color = "danger" > { $initq . error . message } </ Card >
< / Col >
{ /if }
< Col xs = "auto" >
< Button
outline color="primary"
on:click={() => ( isSortingOpen = true )} >
< Icon name = "sort-up" / > Sorting
< / Button >
< Button
outline color="primary"
on:click={() => ( isMetricsSelectionOpen = true )} >
< Icon name = "graph-up" / > Metrics
< / Button >
2023-12-01 13:22:01 +01:00
2023-12-06 12:58:03 +01:00
< Button
outline color="secondary"
on:click={() => ( isHistogramSelectionOpen = true )} >
< Icon name = "bar-chart-line" / > Select Histograms
< / Button >
2022-06-22 11:20:57 +02:00
< / Col >
< Col xs = "auto" >
< Filters
filterPresets={ filterPresets }
startTimeQuickSelect={ true }
2023-06-06 16:52:40 +02:00
bind:this={ filterComponent }
2022-06-22 11:20:57 +02:00
on:update={({ detail }) => {
2023-06-06 16:52:40 +02:00
jobFilters = [...detail.filters, { user : { eq : user.username } } ]
selectedCluster = jobFilters[0]?.cluster ? jobFilters[0].cluster.eq : null
2023-03-31 17:18:16 +02:00
jobList.update(jobFilters)
2022-06-22 11:20:57 +02:00
}} />
< / Col >
< Col xs = "auto" style = "margin-left: auto;" >
2023-05-08 18:06:58 +02:00
< Refresher on:reload = {() => jobList . refresh ()} / >
2022-06-22 11:20:57 +02:00
< / Col >
< / Row >
< br / >
< Row >
{ #if $stats . error }
< Col >
< Card body color = "danger" > { $stats . error . message } </ Card >
< / Col >
{ :else if ! $stats . data }
< Col >
< Spinner secondary / >
< / Col >
{ : else }
< Col xs = "4" >
< Table >
< tbody >
< tr >
< th scope = "row" > Username< / th >
< td > { scrambleNames ? scramble ( user . username ) : user . username } </ td >
< / tr >
{ #if user . name }
< tr >
< th scope = "row" > Name< / th >
< td > { scrambleNames ? scramble ( user . name ) : user . name } </ td >
< / tr >
{ /if }
{ #if user . email }
< tr >
< th scope = "row" > Email< / th >
< td > { user . email } </ td >
< / tr >
{ /if }
< tr >
< th scope = "row" > Total Jobs< / th >
< td > { $stats . data . jobsStatistics [ 0 ]. totalJobs } </ td >
< / tr >
< tr >
< th scope = "row" > Short Jobs< / th >
< td > { $stats . data . jobsStatistics [ 0 ]. shortJobs } </ td >
< / tr >
< tr >
< th scope = "row" > Total Walltime< / th >
< td > { $stats . data . jobsStatistics [ 0 ]. totalWalltime } </ td >
< / tr >
< tr >
< th scope = "row" > Total Core Hours< / th >
< td > { $stats . data . jobsStatistics [ 0 ]. totalCoreHours } </ td >
< / tr >
< / tbody >
< / Table >
< / Col >
2023-07-26 13:44:06 +02:00
< div class = "col-4 text-center" bind:clientWidth = { w1 } >
2022-06-22 11:20:57 +02:00
{ #key $stats . data . jobsStatistics [ 0 ]. histDuration }
2023-08-11 13:34:30 +02:00
< Histogram
2023-07-26 13:44:06 +02:00
data={ convert2uplot ( $stats . data . jobsStatistics [ 0 ]. histDuration )}
2023-08-10 18:05:16 +02:00
width={ w1 - 25 } height={ histogramHeight }
2023-08-09 12:42:25 +02:00
title="Duration Distribution"
2023-07-26 13:44:06 +02:00
xlabel="Current Runtimes"
xunit="Hours"
ylabel="Number of Jobs"
yunit="Jobs"/>
2022-06-22 11:20:57 +02:00
{ /key }
< / div >
2023-07-26 13:44:06 +02:00
< div class = "col-4 text-center" bind:clientWidth = { w2 } >
2022-06-22 11:20:57 +02:00
{ #key $stats . data . jobsStatistics [ 0 ]. histNumNodes }
2023-08-11 13:34:30 +02:00
< Histogram
2023-07-26 13:44:06 +02:00
data={ convert2uplot ( $stats . data . jobsStatistics [ 0 ]. histNumNodes )}
2023-03-30 15:21:35 +02:00
width={ w2 - 25 } height={ histogramHeight }
2023-08-09 12:42:25 +02:00
title="Number of Nodes Distribution"
2023-07-26 13:44:06 +02:00
xlabel="Allocated Nodes"
xunit="Nodes"
ylabel="Number of Jobs"
yunit="Jobs"/>
2022-06-22 11:20:57 +02:00
{ /key }
< / div >
{ /if }
< / Row >
2023-12-05 11:59:01 +01:00
{ #if metricsInHistograms }
< Row >
{ #if $stats . error }
< Col >
< Card body color = "danger" > { $stats . error . message } </ Card >
< / Col >
{ :else if ! $stats . data }
< Col >
< Spinner secondary / >
< / Col >
{ : else }
< Col >
{ #key $stats . data . jobsStatistics [ 0 ]. histMetrics }
< PlotTable
let:item
let:width
2023-12-05 15:30:40 +01:00
renderFor="user"
items={ $stats . data . jobsStatistics [ 0 ]. histMetrics }
itemsPerRow={ 3 } >
2023-12-01 13:22:01 +01:00
2023-12-05 15:30:40 +01:00
< Histogram
data={ convert2uplot ( item . data )}
2023-12-13 11:58:14 +01:00
usesBins={ true }
2023-12-05 11:59:01 +01:00
width={ width } height={ 250 }
2023-12-13 11:58:14 +01:00
title="Distribution of '{ item . metric } ' averages"
xlabel={ ` ${ item . metric } bin maximum ${ item ? . unit ? ` [ $ { item . unit }] ` : `` } `}
2023-12-05 15:30:40 +01:00
xunit={ item . unit }
2023-12-06 12:58:03 +01:00
ylabel="Number of Jobs"
2023-12-05 15:30:40 +01:00
yunit="Jobs"/>
2023-12-05 11:59:01 +01:00
< / PlotTable >
{ /key }
< / Col >
{ /if }
< / Row >
{ /if }
2022-06-22 11:20:57 +02:00
< br / >
< Row >
< Col >
< JobList
bind:metrics={ metrics }
bind:sorting={ sorting }
2023-11-28 09:58:36 +01:00
bind:this={ jobList }
bind:showFootprint={ showFootprint } />
2022-06-22 11:20:57 +02:00
< / Col >
< / Row >
< Sorting
bind:sorting={ sorting }
bind:isOpen={ isSortingOpen } />
2023-03-31 17:18:16 +02:00
< MetricSelection
bind:cluster={ selectedCluster }
configName="plot_list_selectedMetrics"
2022-06-22 11:20:57 +02:00
bind:metrics={ metrics }
2023-11-28 09:58:36 +01:00
bind:isOpen={ isMetricsSelectionOpen }
bind:showFootprint={ showFootprint }
2024-02-08 12:26:07 +01:00
view='list'/>
2023-12-12 15:42:14 +01:00
< HistogramSelection
2023-12-06 12:58:03 +01:00
bind:cluster={ selectedCluster }
bind:metricsInHistograms={ metricsInHistograms }
2024-02-08 12:26:07 +01:00
bind:isOpen={ isHistogramSelectionOpen } />