mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 13:29:05 +01:00
feat: persist analysis and status pie selections
This commit is contained in:
parent
9533f06eaf
commit
b623092721
@ -26,21 +26,25 @@ var Keys schema.ProgramConfig = schema.ProgramConfig{
|
|||||||
StopJobsExceedingWalltime: 0,
|
StopJobsExceedingWalltime: 0,
|
||||||
ShortRunningJobsDuration: 5 * 60,
|
ShortRunningJobsDuration: 5 * 60,
|
||||||
UiDefaults: map[string]interface{}{
|
UiDefaults: map[string]interface{}{
|
||||||
"analysis_view_histogramMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
"analysis_view_histogramMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
||||||
"analysis_view_scatterPlotMetrics": [][]string{{"flops_any", "mem_bw"}, {"flops_any", "cpu_load"}, {"cpu_load", "mem_bw"}},
|
"analysis_view_scatterPlotMetrics": [][]string{{"flops_any", "mem_bw"}, {"flops_any", "cpu_load"}, {"cpu_load", "mem_bw"}},
|
||||||
"job_view_nodestats_selectedMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
"job_view_nodestats_selectedMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
||||||
"job_view_polarPlotMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
"job_view_polarPlotMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
||||||
"job_view_selectedMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
"job_view_selectedMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
||||||
"plot_general_colorBackground": true,
|
"plot_general_colorBackground": true,
|
||||||
"plot_general_colorscheme": []string{"#00bfff", "#0000ff", "#ff00ff", "#ff0000", "#ff8000", "#ffff00", "#80ff00"},
|
"plot_general_colorscheme": []string{"#00bfff", "#0000ff", "#ff00ff", "#ff0000", "#ff8000", "#ffff00", "#80ff00"},
|
||||||
"plot_general_lineWidth": 3,
|
"plot_general_lineWidth": 3,
|
||||||
"plot_list_jobsPerPage": 50,
|
"plot_list_jobsPerPage": 50,
|
||||||
"plot_list_selectedMetrics": []string{"cpu_load", "mem_used", "flops_any", "mem_bw"},
|
"plot_list_selectedMetrics": []string{"cpu_load", "mem_used", "flops_any", "mem_bw"},
|
||||||
"plot_view_plotsPerRow": 3,
|
"plot_view_plotsPerRow": 3,
|
||||||
"plot_view_showPolarplot": true,
|
"plot_view_showPolarplot": true,
|
||||||
"plot_view_showRoofline": true,
|
"plot_view_showRoofline": true,
|
||||||
"plot_view_showStatTable": true,
|
"plot_view_showStatTable": true,
|
||||||
"system_view_selectedMetric": "cpu_load",
|
"system_view_selectedMetric": "cpu_load",
|
||||||
|
"analysis_view_selectedTopEntity": "user",
|
||||||
|
"analysis_view_selectedTopCategory": "totalWalltime",
|
||||||
|
"status_view_selectedTopUserCategory": "totalJobs",
|
||||||
|
"status_view_selectedTopProjectCategory": "totalJobs",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { init, convert2uplot } from './utils.js'
|
import { init, convert2uplot } from './utils.js'
|
||||||
import { getContext, onMount } from 'svelte'
|
import { getContext, onMount } from 'svelte'
|
||||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
import { queryStore, gql, getContextClient, mutationStore } from '@urql/svelte'
|
||||||
import { Row, Col, Spinner, Card, Table, Icon } from 'sveltestrap'
|
import { Row, Col, Spinner, Card, Table, Icon } from 'sveltestrap'
|
||||||
import Filters from './filters/Filters.svelte'
|
import Filters from './filters/Filters.svelte'
|
||||||
import PlotSelection from './PlotSelection.svelte'
|
import PlotSelection from './PlotSelection.svelte'
|
||||||
@ -49,11 +49,12 @@
|
|||||||
{key: 'totalAccHours', label: 'Accelerator Hours'}
|
{key: 'totalAccHours', label: 'Accelerator Hours'}
|
||||||
]
|
]
|
||||||
const groupOptions = [
|
const groupOptions = [
|
||||||
{key: 'User', label: 'User Name'},
|
{key: 'user', label: 'User Name'},
|
||||||
{key: 'Project', label: 'Project ID'}
|
{key: 'project', label: 'Project ID'}
|
||||||
]
|
]
|
||||||
let sortSelection = sortOptions[0] // Default: Walltime
|
|
||||||
let groupSelection = groupOptions[0] // Default: Users
|
let sortSelection = sortOptions.find((option) => option.key == ccconfig[`analysis_view_selectedTopCategory:${filterPresets.cluster}`]) || sortOptions.find((option) => option.key == ccconfig.analysis_view_selectedTopCategory)
|
||||||
|
let groupSelection = groupOptions.find((option) => option.key == ccconfig[`analysis_view_selectedTopEntity:${filterPresets.cluster}`]) || groupOptions.find((option) => option.key == ccconfig.analysis_view_selectedTopEntity)
|
||||||
|
|
||||||
getContext('on-init')(({ data }) => {
|
getContext('on-init')(({ data }) => {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
@ -126,6 +127,53 @@
|
|||||||
variables: { jobFilters, rows: 50, cols: 50, minX: 0.01, minY: 1., maxX: 1000., maxY }
|
variables: { jobFilters, rows: 50, cols: 50, minX: 0.01, minY: 1., maxX: 1000., maxY }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const updateConfigurationMutation = ({ name, value }) => {
|
||||||
|
return mutationStore({
|
||||||
|
client: client,
|
||||||
|
query: gql`
|
||||||
|
mutation ($name: String!, $value: String!) {
|
||||||
|
updateConfiguration(name: $name, value: $value)
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: { name, value }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateEntityConfiguration(select) {
|
||||||
|
if (ccconfig[`analysis_view_selectedTopEntity:${filterPresets.cluster}`] != select) {
|
||||||
|
updateConfigurationMutation({ name: `analysis_view_selectedTopEntity:${filterPresets.cluster}`, value: JSON.stringify(select) })
|
||||||
|
.subscribe(res => {
|
||||||
|
if (res.fetching === false && !res.error) {
|
||||||
|
// console.log(`analysis_view_selectedTopEntity:${filterPresets.cluster}` + ' -> Updated!')
|
||||||
|
} else if (res.fetching === false && res.error) {
|
||||||
|
throw res.error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// console.log('No Mutation Required: Entity')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function updateCategoryConfiguration(select) {
|
||||||
|
if (ccconfig[`analysis_view_selectedTopCategory:${filterPresets.cluster}`] != select) {
|
||||||
|
updateConfigurationMutation({ name: `analysis_view_selectedTopCategory:${filterPresets.cluster}`, value: JSON.stringify(select) })
|
||||||
|
.subscribe(res => {
|
||||||
|
if (res.fetching === false && !res.error) {
|
||||||
|
// console.log(`analysis_view_selectedTopCategory:${filterPresets.cluster}` + ' -> Updated!')
|
||||||
|
} else if (res.fetching === false && res.error) {
|
||||||
|
throw res.error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// console.log('No Mutation Required: Category')
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$: updateEntityConfiguration(groupSelection.key)
|
||||||
|
$: updateCategoryConfiguration(sortSelection.key)
|
||||||
|
|
||||||
onMount(() => filterComponent.update())
|
onMount(() => filterComponent.update())
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -200,7 +248,7 @@
|
|||||||
<select class="p-0" bind:value={groupSelection}>
|
<select class="p-0" bind:value={groupSelection}>
|
||||||
{#each groupOptions as option}
|
{#each groupOptions as option}
|
||||||
<option value={option}>
|
<option value={option}>
|
||||||
{option.key}s
|
{option.key.charAt(0).toUpperCase() + option.key.slice(1)}s
|
||||||
</option>
|
</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { getContext } from 'svelte'
|
||||||
import Refresher from './joblist/Refresher.svelte'
|
import Refresher from './joblist/Refresher.svelte'
|
||||||
import Roofline, { transformPerNodeData } from './plots/Roofline.svelte'
|
import Roofline, { transformPerNodeData } from './plots/Roofline.svelte'
|
||||||
import Pie, { colors } from './plots/Pie.svelte'
|
import Pie, { colors } from './plots/Pie.svelte'
|
||||||
@ -6,9 +7,10 @@
|
|||||||
import { Row, Col, Spinner, Card, CardHeader, CardTitle, CardBody, Table, Progress, Icon } from 'sveltestrap'
|
import { Row, Col, Spinner, Card, CardHeader, CardTitle, CardBody, Table, Progress, Icon } from 'sveltestrap'
|
||||||
import { init, convert2uplot } from './utils.js'
|
import { init, convert2uplot } from './utils.js'
|
||||||
import { scaleNumbers } from './units.js'
|
import { scaleNumbers } from './units.js'
|
||||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
import { queryStore, gql, getContextClient, mutationStore } from '@urql/svelte'
|
||||||
|
|
||||||
const { query: initq } = init()
|
const { query: initq } = init()
|
||||||
|
const ccconfig = getContext("cc-config")
|
||||||
|
|
||||||
export let cluster
|
export let cluster
|
||||||
|
|
||||||
@ -20,8 +22,9 @@
|
|||||||
{key: 'totalCores', label: 'Cores'},
|
{key: 'totalCores', label: 'Cores'},
|
||||||
{key: 'totalAccs', label: 'Accelerators'},
|
{key: 'totalAccs', label: 'Accelerators'},
|
||||||
]
|
]
|
||||||
let topProjectSelection = topOptions[0] // Default: Jobs
|
|
||||||
let topUserSelection = topOptions[0] // Default: Jobs
|
let topProjectSelection = topOptions.find((option) => option.key == ccconfig[`status_view_selectedTopProjectCategory:${cluster}`]) || topOptions.find((option) => option.key == ccconfig.status_view_selectedTopProjectCategory)
|
||||||
|
let topUserSelection = topOptions.find((option) => option.key == ccconfig[`status_view_selectedTopUserCategory:${cluster}`]) || topOptions.find((option) => option.key == ccconfig.status_view_selectedTopUserCategory)
|
||||||
|
|
||||||
const client = getContextClient();
|
const client = getContextClient();
|
||||||
$: mainQuery = queryStore({
|
$: mainQuery = queryStore({
|
||||||
@ -107,6 +110,51 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateConfigurationMutation = ({ name, value }) => {
|
||||||
|
return mutationStore({
|
||||||
|
client: client,
|
||||||
|
query: gql`
|
||||||
|
mutation ($name: String!, $value: String!) {
|
||||||
|
updateConfiguration(name: $name, value: $value)
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: { name, value }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTopUserConfiguration(select) {
|
||||||
|
if (ccconfig[`status_view_selectedTopUserCategory:${cluster}`] != select) {
|
||||||
|
updateConfigurationMutation({ name: `status_view_selectedTopUserCategory:${cluster}`, value: JSON.stringify(select) })
|
||||||
|
.subscribe(res => {
|
||||||
|
if (res.fetching === false && !res.error) {
|
||||||
|
// console.log(`status_view_selectedTopUserCategory:${cluster}` + ' -> Updated!')
|
||||||
|
} else if (res.fetching === false && res.error) {
|
||||||
|
throw res.error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// console.log('No Mutation Required: Top User')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTopProjectConfiguration(select) {
|
||||||
|
if (ccconfig[`status_view_selectedTopProjectCategory:${cluster}`] != select) {
|
||||||
|
updateConfigurationMutation({ name: `status_view_selectedTopProjectCategory:${cluster}`, value: JSON.stringify(select) })
|
||||||
|
.subscribe(res => {
|
||||||
|
if (res.fetching === false && !res.error) {
|
||||||
|
// console.log(`status_view_selectedTopProjectCategory:${cluster}` + ' -> Updated!')
|
||||||
|
} else if (res.fetching === false && res.error) {
|
||||||
|
throw res.error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// console.log('No Mutation Required: Top Project')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$: updateTopUserConfiguration(topUserSelection.key)
|
||||||
|
$: updateTopProjectConfiguration(topProjectSelection.key)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Loading indicator & Refresh -->
|
<!-- Loading indicator & Refresh -->
|
||||||
|
Loading…
Reference in New Issue
Block a user