mirror of
				https://github.com/ClusterCockpit/cc-backend
				synced 2025-11-04 09:35:07 +01:00 
			
		
		
		
	Start to fix errors with urql 4
This commit is contained in:
		@@ -9,84 +9,125 @@
 | 
			
		||||
    - update(filters?: [JobFilter])
 | 
			
		||||
 -->
 | 
			
		||||
<script>
 | 
			
		||||
    import { queryStore, gql, getContextClient , mutationStore } from '@urql/svelte'
 | 
			
		||||
    import { getContext } from 'svelte';
 | 
			
		||||
    import { Row, Table, Card, Spinner } from 'sveltestrap'
 | 
			
		||||
    import Pagination from './Pagination.svelte'
 | 
			
		||||
    import JobListRow from './Row.svelte'
 | 
			
		||||
    import { stickyHeader } from '../utils.js'
 | 
			
		||||
    import {
 | 
			
		||||
        queryStore,
 | 
			
		||||
        gql,
 | 
			
		||||
        getContextClient,
 | 
			
		||||
        mutationStore,
 | 
			
		||||
    } from "@urql/svelte";
 | 
			
		||||
    import { getContext } from "svelte";
 | 
			
		||||
    import { Row, Table, Card, Spinner } from "sveltestrap";
 | 
			
		||||
    import Pagination from "./Pagination.svelte";
 | 
			
		||||
    import JobListRow from "./Row.svelte";
 | 
			
		||||
    import { stickyHeader } from "../utils.js";
 | 
			
		||||
 | 
			
		||||
    const ccconfig = getContext('cc-config'),
 | 
			
		||||
          clusters = getContext('clusters'),
 | 
			
		||||
          initialized = getContext('initialized')
 | 
			
		||||
    const ccconfig = getContext("cc-config"),
 | 
			
		||||
        clusters = getContext("clusters"),
 | 
			
		||||
        initialized = getContext("initialized");
 | 
			
		||||
 | 
			
		||||
    export let sorting = { field: "startTime", order: "DESC" }
 | 
			
		||||
    export let matchedJobs = 0
 | 
			
		||||
    export let metrics = ccconfig.plot_list_selectedMetrics
 | 
			
		||||
    export let sorting = { field: "startTime", order: "DESC" };
 | 
			
		||||
    export let matchedJobs = 0;
 | 
			
		||||
    export let metrics = ccconfig.plot_list_selectedMetrics;
 | 
			
		||||
 | 
			
		||||
    let itemsPerPage = ccconfig.plot_list_jobsPerPage
 | 
			
		||||
    let page = 1
 | 
			
		||||
    let paging = { itemsPerPage, page }
 | 
			
		||||
    let filter = []
 | 
			
		||||
    let itemsPerPage = ccconfig.plot_list_jobsPerPage;
 | 
			
		||||
    let page = 1;
 | 
			
		||||
    let paging = { itemsPerPage, page };
 | 
			
		||||
    let filter = [];
 | 
			
		||||
 | 
			
		||||
    $: jobs = queryStore({
 | 
			
		||||
    const jobs = queryStore({
 | 
			
		||||
        client: getContextClient(),
 | 
			
		||||
        query: gql`
 | 
			
		||||
        query($filter: [JobFilter!]!, $sorting: OrderByInput!, $paging: PageRequest! ){
 | 
			
		||||
            jobs(filter: $filter, order: $sorting, page: $paging) {
 | 
			
		||||
                items {
 | 
			
		||||
                    id, jobId, user, project, jobName, cluster, subCluster, startTime,
 | 
			
		||||
                duration, numNodes, numHWThreads, numAcc, walltime, resources { hostname },
 | 
			
		||||
                SMT, exclusive, partition, arrayJobId,
 | 
			
		||||
                monitoringStatus, state,
 | 
			
		||||
                tags { id, type, name }
 | 
			
		||||
                userData { name }
 | 
			
		||||
                metaData
 | 
			
		||||
            query (
 | 
			
		||||
                $filter: [JobFilter!]!
 | 
			
		||||
                $sorting: OrderByInput!
 | 
			
		||||
                $paging: PageRequest!
 | 
			
		||||
            ) {
 | 
			
		||||
                jobs(filter: $filter, order: $sorting, page: $paging) {
 | 
			
		||||
                    items {
 | 
			
		||||
                        id
 | 
			
		||||
                        jobId
 | 
			
		||||
                        user
 | 
			
		||||
                        project
 | 
			
		||||
                        jobName
 | 
			
		||||
                        cluster
 | 
			
		||||
                        subCluster
 | 
			
		||||
                        startTime
 | 
			
		||||
                        duration
 | 
			
		||||
                        numNodes
 | 
			
		||||
                        numHWThreads
 | 
			
		||||
                        numAcc
 | 
			
		||||
                        walltime
 | 
			
		||||
                        resources {
 | 
			
		||||
                            hostname
 | 
			
		||||
                        }
 | 
			
		||||
                        SMT
 | 
			
		||||
                        exclusive
 | 
			
		||||
                        partition
 | 
			
		||||
                        arrayJobId
 | 
			
		||||
                        monitoringStatus
 | 
			
		||||
                        state
 | 
			
		||||
                        tags {
 | 
			
		||||
                            id
 | 
			
		||||
                            type
 | 
			
		||||
                            name
 | 
			
		||||
                        }
 | 
			
		||||
                        userData {
 | 
			
		||||
                            name
 | 
			
		||||
                        }
 | 
			
		||||
                        metaData
 | 
			
		||||
                    }
 | 
			
		||||
                    count
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            count
 | 
			
		||||
        }
 | 
			
		||||
    }`,
 | 
			
		||||
    variables: { paging, sorting, filter },
 | 
			
		||||
    pause: true
 | 
			
		||||
    })
 | 
			
		||||
        `,
 | 
			
		||||
        variables: { paging, sorting, filter },
 | 
			
		||||
        pause: true,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const updateConfiguration = ({ name, value }) => {
 | 
			
		||||
    result = mutationStore({
 | 
			
		||||
        client: getContextClient(),
 | 
			
		||||
        query: gql`mutation($name: String!, $value: String!) {
 | 
			
		||||
            updateConfiguration(name: $name, value: $value)
 | 
			
		||||
        }`,
 | 
			
		||||
        variables: {name, value}
 | 
			
		||||
    })
 | 
			
		||||
    }
 | 
			
		||||
        result = mutationStore({
 | 
			
		||||
            client: getContextClient(),
 | 
			
		||||
            query: gql`
 | 
			
		||||
                mutation ($name: String!, $value: String!) {
 | 
			
		||||
                    updateConfiguration(name: $name, value: $value)
 | 
			
		||||
                }
 | 
			
		||||
            `,
 | 
			
		||||
            variables: { name, value },
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // $: $jobs.variables = { ...$jobs.variables, sorting, paging }
 | 
			
		||||
    $: matchedJobs = $jobs.data != null ? $jobs.data.jobs.count : 0
 | 
			
		||||
    $: matchedJobs = $jobs.data != null ? $jobs.data.jobs.count : 0;
 | 
			
		||||
 | 
			
		||||
    // (Re-)query and optionally set new filters.
 | 
			
		||||
    export function update(filters) {
 | 
			
		||||
        if (filters != null) {
 | 
			
		||||
            let minRunningFor = ccconfig.plot_list_hideShortRunningJobs
 | 
			
		||||
            let minRunningFor = ccconfig.plot_list_hideShortRunningJobs;
 | 
			
		||||
            if (minRunningFor && minRunningFor > 0) {
 | 
			
		||||
                filters.push({ minRunningFor })
 | 
			
		||||
                filters.push({ minRunningFor });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $jobs.variables.filter = filters
 | 
			
		||||
            filter = filters;
 | 
			
		||||
            // console.log('filters:', ...filters.map(f => Object.entries(f)).flat(2))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        page = 1
 | 
			
		||||
        $jobs.variables.paging = paging = { page, itemsPerPage };
 | 
			
		||||
        $jobs.context.pause = false
 | 
			
		||||
        $jobs.reexecute({ requestPolicy: 'network-only' })
 | 
			
		||||
        page = 1;
 | 
			
		||||
        paging = paging = { page, itemsPerPage };
 | 
			
		||||
        jobs.resume();
 | 
			
		||||
        // $jobs.reexecute({ requestPolicy: 'network-only' })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let tableWidth = null
 | 
			
		||||
    let jobInfoColumnWidth = 250
 | 
			
		||||
    $: plotWidth = Math.floor((tableWidth - jobInfoColumnWidth) / metrics.length - 10)
 | 
			
		||||
    let tableWidth = null;
 | 
			
		||||
    let jobInfoColumnWidth = 250;
 | 
			
		||||
    $: plotWidth = Math.floor(
 | 
			
		||||
        (tableWidth - jobInfoColumnWidth) / metrics.length - 10
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    let headerPaddingTop = 0
 | 
			
		||||
    stickyHeader('.cc-table-wrapper > table.table >thead > tr > th.position-sticky:nth-child(1)', (x) => (headerPaddingTop = x))
 | 
			
		||||
    let headerPaddingTop = 0;
 | 
			
		||||
    stickyHeader(
 | 
			
		||||
        ".cc-table-wrapper > table.table >thead > tr > th.position-sticky:nth-child(1)",
 | 
			
		||||
        (x) => (headerPaddingTop = x)
 | 
			
		||||
    );
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<Row>
 | 
			
		||||
@@ -94,20 +135,43 @@
 | 
			
		||||
        <Table cellspacing="0px" cellpadding="0px">
 | 
			
		||||
            <thead>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <th class="position-sticky top-0" scope="col" style="width: {jobInfoColumnWidth}px; padding-top: {headerPaddingTop}px">
 | 
			
		||||
                    <th
 | 
			
		||||
                        class="position-sticky top-0"
 | 
			
		||||
                        scope="col"
 | 
			
		||||
                        style="width: {jobInfoColumnWidth}px; padding-top: {headerPaddingTop}px"
 | 
			
		||||
                    >
 | 
			
		||||
                        Job Info
 | 
			
		||||
                    </th>
 | 
			
		||||
                    {#each metrics as metric (metric)}
 | 
			
		||||
                        <th class="position-sticky top-0 text-center" scope="col" style="width: {plotWidth}px; padding-top: {headerPaddingTop}px">
 | 
			
		||||
                        <th
 | 
			
		||||
                            class="position-sticky top-0 text-center"
 | 
			
		||||
                            scope="col"
 | 
			
		||||
                            style="width: {plotWidth}px; padding-top: {headerPaddingTop}px"
 | 
			
		||||
                        >
 | 
			
		||||
                            {metric}
 | 
			
		||||
                            {#if $initialized}
 | 
			
		||||
                                ({clusters
 | 
			
		||||
                                    .map(cluster => cluster.metricConfig.find(m => m.name == metric))
 | 
			
		||||
                                    .filter(m => m != null)
 | 
			
		||||
                                    .map(m => (m.unit?.prefix?m.unit?.prefix:'') + (m.unit?.base?m.unit?.base:'')) // Build unitStr
 | 
			
		||||
                                    .reduce((arr, unitStr) => arr.includes(unitStr) ? arr : [...arr, unitStr], []) // w/o this, output would be [unitStr, unitStr]
 | 
			
		||||
                                    .join(', ')
 | 
			
		||||
                                })
 | 
			
		||||
                                    .map((cluster) =>
 | 
			
		||||
                                        cluster.metricConfig.find(
 | 
			
		||||
                                            (m) => m.name == metric
 | 
			
		||||
                                        )
 | 
			
		||||
                                    )
 | 
			
		||||
                                    .filter((m) => m != null)
 | 
			
		||||
                                    .map(
 | 
			
		||||
                                        (m) =>
 | 
			
		||||
                                            (m.unit?.prefix
 | 
			
		||||
                                                ? m.unit?.prefix
 | 
			
		||||
                                                : "") +
 | 
			
		||||
                                            (m.unit?.base ? m.unit?.base : "")
 | 
			
		||||
                                    ) // Build unitStr
 | 
			
		||||
                                    .reduce(
 | 
			
		||||
                                        (arr, unitStr) =>
 | 
			
		||||
                                            arr.includes(unitStr)
 | 
			
		||||
                                                ? arr
 | 
			
		||||
                                                : [...arr, unitStr],
 | 
			
		||||
                                        []
 | 
			
		||||
                                    ) // w/o this, output would be [unitStr, unitStr]
 | 
			
		||||
                                    .join(", ")})
 | 
			
		||||
                            {/if}
 | 
			
		||||
                        </th>
 | 
			
		||||
                    {/each}
 | 
			
		||||
@@ -116,28 +180,27 @@
 | 
			
		||||
            <tbody>
 | 
			
		||||
                {#if $jobs.error}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td colspan="{metrics.length + 1}">
 | 
			
		||||
                            <Card body color="danger" class="mb-3"><h2>{$jobs.error.message}</h2></Card>
 | 
			
		||||
                        <td colspan={metrics.length + 1}>
 | 
			
		||||
                            <Card body color="danger" class="mb-3"
 | 
			
		||||
                                ><h2>{$jobs.error.message}</h2></Card
 | 
			
		||||
                            >
 | 
			
		||||
                        </td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                {:else if $jobs.fetching || !$jobs.data}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td colspan="{metrics.length + 1}">
 | 
			
		||||
                        <td colspan={metrics.length + 1}>
 | 
			
		||||
                            <Spinner secondary />
 | 
			
		||||
                        </td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                {:else if $jobs.data && $initialized}
 | 
			
		||||
                    {#each $jobs.data.jobs.items as job (job)}
 | 
			
		||||
                        <JobListRow
 | 
			
		||||
                            job={job}
 | 
			
		||||
                            metrics={metrics}
 | 
			
		||||
                            plotWidth={plotWidth} />
 | 
			
		||||
                        <JobListRow {job} {metrics} {plotWidth} />
 | 
			
		||||
                    {:else}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td colspan="{metrics.length + 1}">
 | 
			
		||||
                            No jobs found
 | 
			
		||||
                        </td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                        <tr>
 | 
			
		||||
                            <td colspan={metrics.length + 1}>
 | 
			
		||||
                                No jobs found
 | 
			
		||||
                            </td>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                    {/each}
 | 
			
		||||
                {/if}
 | 
			
		||||
            </tbody>
 | 
			
		||||
@@ -146,24 +209,24 @@
 | 
			
		||||
</Row>
 | 
			
		||||
 | 
			
		||||
<Pagination
 | 
			
		||||
    bind:page={page}
 | 
			
		||||
    bind:page
 | 
			
		||||
    {itemsPerPage}
 | 
			
		||||
    itemText="Jobs"
 | 
			
		||||
    totalItems={matchedJobs}
 | 
			
		||||
    on:update={({ detail }) => {
 | 
			
		||||
        if (detail.itemsPerPage != itemsPerPage) {
 | 
			
		||||
            itemsPerPage = detail.itemsPerPage
 | 
			
		||||
            itemsPerPage = detail.itemsPerPage;
 | 
			
		||||
            updateConfiguration({
 | 
			
		||||
                name: "plot_list_jobsPerPage",
 | 
			
		||||
                value: itemsPerPage.toString()
 | 
			
		||||
            }).then(res => {
 | 
			
		||||
                if (res.error)
 | 
			
		||||
                    console.error(res.error);
 | 
			
		||||
            })
 | 
			
		||||
                value: itemsPerPage.toString(),
 | 
			
		||||
            }).then((res) => {
 | 
			
		||||
                if (res.error) console.error(res.error);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        paging = { itemsPerPage: detail.itemsPerPage, page: detail.page }
 | 
			
		||||
    }} />
 | 
			
		||||
        paging = { itemsPerPage: detail.itemsPerPage, page: detail.page };
 | 
			
		||||
    }}
 | 
			
		||||
/>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
    .cc-table-wrapper {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,136 +9,173 @@
 | 
			
		||||
 -->
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    import { queryStore, gql, getContextClient } from '@urql/svelte'
 | 
			
		||||
    import { getContext } from 'svelte'
 | 
			
		||||
    import { Card, Spinner } from 'sveltestrap'
 | 
			
		||||
    import MetricPlot from '../plots/MetricPlot.svelte'
 | 
			
		||||
    import JobInfo from './JobInfo.svelte'
 | 
			
		||||
    import { maxScope } from '../utils.js'
 | 
			
		||||
    import { queryStore, gql, getContextClient } from "@urql/svelte";
 | 
			
		||||
    import { getContext } from "svelte";
 | 
			
		||||
    import { Card, Spinner } from "sveltestrap";
 | 
			
		||||
    import MetricPlot from "../plots/MetricPlot.svelte";
 | 
			
		||||
    import JobInfo from "./JobInfo.svelte";
 | 
			
		||||
    import { maxScope } from "../utils.js";
 | 
			
		||||
 | 
			
		||||
    export let job
 | 
			
		||||
    export let metrics
 | 
			
		||||
    export let plotWidth
 | 
			
		||||
    export let plotHeight = 275
 | 
			
		||||
    export let job;
 | 
			
		||||
    export let metrics;
 | 
			
		||||
    export let plotWidth;
 | 
			
		||||
    export let plotHeight = 275;
 | 
			
		||||
 | 
			
		||||
    let scopes = [job.numNodes == 1 ? 'core' : 'node']
 | 
			
		||||
    let { id } = job;
 | 
			
		||||
    let scopes = [job.numNodes == 1 ? "core" : "node"];
 | 
			
		||||
 | 
			
		||||
    const cluster = getContext('clusters').find(c => c.name == job.cluster)
 | 
			
		||||
    const cluster = getContext("clusters").find((c) => c.name == job.cluster);
 | 
			
		||||
    // Get all MetricConfs which include subCluster-specific settings for this job
 | 
			
		||||
    const metricConfig = getContext('metrics')
 | 
			
		||||
    const metricConfig = getContext("metrics");
 | 
			
		||||
    const metricsQuery = queryStore({
 | 
			
		||||
        client: getContextClient(),
 | 
			
		||||
        query: gql`
 | 
			
		||||
        query($id: ID!, $metrics: [String!]!, $scopes: [MetricScope!]!) {
 | 
			
		||||
        jobMetrics(id: $id, metrics: $metrics, scopes: $scopes) {
 | 
			
		||||
            name
 | 
			
		||||
            scope
 | 
			
		||||
            metric {
 | 
			
		||||
                unit { prefix, base }, timestep
 | 
			
		||||
                statisticsSeries { min, mean, max }
 | 
			
		||||
                series {
 | 
			
		||||
                    hostname, id, data
 | 
			
		||||
                    statistics { min, avg, max }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }`,
 | 
			
		||||
    pause: true,
 | 
			
		||||
    variables: {
 | 
			
		||||
        id: job.id,
 | 
			
		||||
        metrics,
 | 
			
		||||
        scopes}
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    const selectScope = (jobMetrics) => jobMetrics.reduce(
 | 
			
		||||
        (a, b) => maxScope([a.scope, b.scope]) == a.scope
 | 
			
		||||
            ? (job.numNodes > 1 ? a : b)
 | 
			
		||||
            : (job.numNodes > 1 ? b : a), jobMetrics[0])
 | 
			
		||||
 | 
			
		||||
    const sortAndSelectScope = (jobMetrics) => metrics
 | 
			
		||||
        .map(function(name) {
 | 
			
		||||
            // Get MetricConf for this selected/requested metric
 | 
			
		||||
            let thisConfig = metricConfig(cluster, name)
 | 
			
		||||
            let thisSCIndex = thisConfig.subClusters.findIndex(sc => sc.name == job.subCluster)
 | 
			
		||||
            // Check if Subcluster has MetricConf: If not found (index == -1), no further remove flag check required
 | 
			
		||||
            if (thisSCIndex >= 0) {
 | 
			
		||||
                // SubCluster Config present: Check if remove flag is set
 | 
			
		||||
                if (thisConfig.subClusters[thisSCIndex].remove == true) {
 | 
			
		||||
                    // Return null data and informational flag
 | 
			
		||||
                    return {removed: true, data: null}
 | 
			
		||||
                } else {
 | 
			
		||||
                    // load and return metric, if data available
 | 
			
		||||
                    let thisMetric = jobMetrics.filter(jobMetric => jobMetric.name == name) // Returns Array
 | 
			
		||||
                    if (thisMetric.length > 0) {
 | 
			
		||||
                        return {removed: false, data: thisMetric}
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return {removed: false, data: null}
 | 
			
		||||
            query ($id: ID!, $metrics: [String!]!, $scopes: [MetricScope!]!) {
 | 
			
		||||
                jobMetrics(id: $id, metrics: $metrics, scopes: $scopes) {
 | 
			
		||||
                    name
 | 
			
		||||
                    scope
 | 
			
		||||
                    metric {
 | 
			
		||||
                        unit {
 | 
			
		||||
                            prefix
 | 
			
		||||
                            base
 | 
			
		||||
                        }
 | 
			
		||||
                        timestep
 | 
			
		||||
                        statisticsSeries {
 | 
			
		||||
                            min
 | 
			
		||||
                            mean
 | 
			
		||||
                            max
 | 
			
		||||
                        }
 | 
			
		||||
                        series {
 | 
			
		||||
                            hostname
 | 
			
		||||
                            id
 | 
			
		||||
                            data
 | 
			
		||||
                            statistics {
 | 
			
		||||
                                min
 | 
			
		||||
                                avg
 | 
			
		||||
                                max
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // No specific subCluster config: 'remove' flag not set, deemed false -> load and return metric, if data available
 | 
			
		||||
                let thisMetric = jobMetrics.filter(jobMetric => jobMetric.name == name) // Returns Array
 | 
			
		||||
                if (thisMetric.length > 0) {
 | 
			
		||||
                    return {removed: false, data: thisMetric}
 | 
			
		||||
            }
 | 
			
		||||
        `,
 | 
			
		||||
        pause: true,
 | 
			
		||||
        variables: {
 | 
			
		||||
            id,
 | 
			
		||||
            metrics,
 | 
			
		||||
            scopes,
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const selectScope = (jobMetrics) =>
 | 
			
		||||
        jobMetrics.reduce(
 | 
			
		||||
            (a, b) =>
 | 
			
		||||
                maxScope([a.scope, b.scope]) == a.scope
 | 
			
		||||
                    ? job.numNodes > 1
 | 
			
		||||
                        ? a
 | 
			
		||||
                        : b
 | 
			
		||||
                    : job.numNodes > 1
 | 
			
		||||
                    ? b
 | 
			
		||||
                    : a,
 | 
			
		||||
            jobMetrics[0]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    const sortAndSelectScope = (jobMetrics) =>
 | 
			
		||||
        metrics
 | 
			
		||||
            .map(function (name) {
 | 
			
		||||
                // Get MetricConf for this selected/requested metric
 | 
			
		||||
                let thisConfig = metricConfig(cluster, name);
 | 
			
		||||
                let thisSCIndex = thisConfig.subClusters.findIndex(
 | 
			
		||||
                    (sc) => sc.name == job.subCluster
 | 
			
		||||
                );
 | 
			
		||||
                // Check if Subcluster has MetricConf: If not found (index == -1), no further remove flag check required
 | 
			
		||||
                if (thisSCIndex >= 0) {
 | 
			
		||||
                    // SubCluster Config present: Check if remove flag is set
 | 
			
		||||
                    if (thisConfig.subClusters[thisSCIndex].remove == true) {
 | 
			
		||||
                        // Return null data and informational flag
 | 
			
		||||
                        return { removed: true, data: null };
 | 
			
		||||
                    } else {
 | 
			
		||||
                        // load and return metric, if data available
 | 
			
		||||
                        let thisMetric = jobMetrics.filter(
 | 
			
		||||
                            (jobMetric) => jobMetric.name == name
 | 
			
		||||
                        ); // Returns Array
 | 
			
		||||
                        if (thisMetric.length > 0) {
 | 
			
		||||
                            return { removed: false, data: thisMetric };
 | 
			
		||||
                        } else {
 | 
			
		||||
                            return { removed: false, data: null };
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    return {removed: false, data: null}
 | 
			
		||||
                    // No specific subCluster config: 'remove' flag not set, deemed false -> load and return metric, if data available
 | 
			
		||||
                    let thisMetric = jobMetrics.filter(
 | 
			
		||||
                        (jobMetric) => jobMetric.name == name
 | 
			
		||||
                    ); // Returns Array
 | 
			
		||||
                    if (thisMetric.length > 0) {
 | 
			
		||||
                        return { removed: false, data: thisMetric };
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return { removed: false, data: null };
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .map(function(jobMetrics) {
 | 
			
		||||
            if (jobMetrics.data != null && jobMetrics.data.length > 0) {
 | 
			
		||||
                return {removed: jobMetrics.removed, data: selectScope(jobMetrics.data)}
 | 
			
		||||
            } else {
 | 
			
		||||
                return jobMetrics
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
            })
 | 
			
		||||
            .map(function (jobMetrics) {
 | 
			
		||||
                if (jobMetrics.data != null && jobMetrics.data.length > 0) {
 | 
			
		||||
                    return {
 | 
			
		||||
                        removed: jobMetrics.removed,
 | 
			
		||||
                        data: selectScope(jobMetrics.data),
 | 
			
		||||
                    };
 | 
			
		||||
                } else {
 | 
			
		||||
                    return jobMetrics;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
    $: metricsQuery.variables = { id: job.id, metrics, scopes }
 | 
			
		||||
    // $: metricsQuery.variables = { id: job.id, metrics, scopes };
 | 
			
		||||
 | 
			
		||||
    if (job.monitoringStatus)
 | 
			
		||||
        $metricsQuery.resume()
 | 
			
		||||
    if (job.monitoringStatus) metricsQuery.resume();
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<tr>
 | 
			
		||||
    <td>
 | 
			
		||||
        <JobInfo job={job}/>
 | 
			
		||||
        <JobInfo {job} />
 | 
			
		||||
    </td>
 | 
			
		||||
    {#if job.monitoringStatus == 0 || job.monitoringStatus == 2}
 | 
			
		||||
        <td colspan="{metrics.length}">
 | 
			
		||||
        <td colspan={metrics.length}>
 | 
			
		||||
            <Card body color="warning">Not monitored or archiving failed</Card>
 | 
			
		||||
        </td>
 | 
			
		||||
    {:else if $metricsQuery.fetching}
 | 
			
		||||
        <td colspan="{metrics.length}" style="text-align: center;">
 | 
			
		||||
        <td colspan={metrics.length} style="text-align: center;">
 | 
			
		||||
            <Spinner secondary />
 | 
			
		||||
        </td>
 | 
			
		||||
    {:else if $metricsQuery.error}
 | 
			
		||||
        <td colspan="{metrics.length}">
 | 
			
		||||
        <td colspan={metrics.length}>
 | 
			
		||||
            <Card body color="danger" class="mb-3">
 | 
			
		||||
                {$metricsQuery.error.message.length > 500
 | 
			
		||||
                    ? $metricsQuery.error.message.substring(0, 499)+'...'
 | 
			
		||||
                    ? $metricsQuery.error.message.substring(0, 499) + "..."
 | 
			
		||||
                    : $metricsQuery.error.message}
 | 
			
		||||
            </Card>
 | 
			
		||||
        </td>
 | 
			
		||||
    {:else}
 | 
			
		||||
        {#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric || i)}
 | 
			
		||||
            <td>
 | 
			
		||||
            <!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case-->
 | 
			
		||||
            {#if metric.removed == false && metric.data != null}
 | 
			
		||||
                <MetricPlot
 | 
			
		||||
                    width={plotWidth}
 | 
			
		||||
                    height={plotHeight}
 | 
			
		||||
                    timestep={metric.data.metric.timestep}
 | 
			
		||||
                    scope={metric.data.scope}
 | 
			
		||||
                    series={metric.data.metric.series}
 | 
			
		||||
                    statisticsSeries={metric.data.metric.statisticsSeries}
 | 
			
		||||
                    metric={metric.data.name}
 | 
			
		||||
                    cluster={cluster}
 | 
			
		||||
                    subCluster={job.subCluster} />
 | 
			
		||||
            {:else if metric.removed == true && metric.data == null}
 | 
			
		||||
                <Card body color="info">Metric disabled for subcluster '{ job.subCluster }'</Card>
 | 
			
		||||
            {:else}
 | 
			
		||||
                <Card body color="warning">Missing Data</Card>
 | 
			
		||||
            {/if}
 | 
			
		||||
                <!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case-->
 | 
			
		||||
                {#if metric.removed == false && metric.data != null}
 | 
			
		||||
                    <MetricPlot
 | 
			
		||||
                        width={plotWidth}
 | 
			
		||||
                        height={plotHeight}
 | 
			
		||||
                        timestep={metric.data.metric.timestep}
 | 
			
		||||
                        scope={metric.data.scope}
 | 
			
		||||
                        series={metric.data.metric.series}
 | 
			
		||||
                        statisticsSeries={metric.data.metric.statisticsSeries}
 | 
			
		||||
                        metric={metric.data.name}
 | 
			
		||||
                        {cluster}
 | 
			
		||||
                        subCluster={job.subCluster}
 | 
			
		||||
                    />
 | 
			
		||||
                {:else if metric.removed == true && metric.data == null}
 | 
			
		||||
                    <Card body color="info"
 | 
			
		||||
                        >Metric disabled for subcluster '{job.subCluster}'</Card
 | 
			
		||||
                    >
 | 
			
		||||
                {:else}
 | 
			
		||||
                    <Card body color="warning">Missing Data</Card>
 | 
			
		||||
                {/if}
 | 
			
		||||
            </td>
 | 
			
		||||
        {/each}
 | 
			
		||||
    {/if}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user