diff --git a/internal/repository/jobQuery.go b/internal/repository/jobQuery.go index 36c5892e..5256bacb 100644 --- a/internal/repository/jobQuery.go +++ b/internal/repository/jobQuery.go @@ -280,11 +280,11 @@ func BuildWhereClause(filter *model.JobFilter, query sq.SelectBuilder) sq.Select // buildIntCondition creates clauses for integer range filters, using BETWEEN only if required. func buildIntCondition(field string, cond *config.IntRange, query sq.SelectBuilder) sq.SelectBuilder { - if cond.From != 1 && cond.To != 0 { + if cond.From > 0 && cond.To > 0 { return query.Where(field+" BETWEEN ? AND ?", cond.From, cond.To) - } else if cond.From != 1 && cond.To == 0 { + } else if cond.From > 0 && cond.To == 0 { return query.Where(field+" >= ?", cond.From) - } else if cond.From == 1 && cond.To != 0 { + } else if cond.From == 0 && cond.To > 0 { return query.Where(field+" <= ?", cond.To) } else { return query @@ -293,11 +293,11 @@ func buildIntCondition(field string, cond *config.IntRange, query sq.SelectBuild // buildFloatCondition creates a clauses for float range filters, using BETWEEN only if required. func buildFloatCondition(field string, cond *model.FloatRange, query sq.SelectBuilder) sq.SelectBuilder { - if cond.From != 1.0 && cond.To != 0.0 { + if cond.From > 0.0 && cond.To > 0.0 { return query.Where(field+" BETWEEN ? AND ?", cond.From, cond.To) - } else if cond.From != 1.0 && cond.To == 0.0 { + } else if cond.From > 0.0 && cond.To == 0.0 { return query.Where(field+" >= ?", cond.From) - } else if cond.From == 1.0 && cond.To != 0.0 { + } else if cond.From == 0.0 && cond.To > 0.0 { return query.Where(field+" <= ?", cond.To) } else { return query @@ -339,11 +339,11 @@ func buildTimeCondition(field string, cond *config.TimeRange, query sq.SelectBui // buildFloatJSONCondition creates a filter on a numeric field within the footprint JSON column, using BETWEEN only if required. func buildFloatJSONCondition(jsonField string, cond *model.FloatRange, query sq.SelectBuilder) sq.SelectBuilder { query = query.Where("JSON_VALID(footprint)") - if cond.From != 1.0 && cond.To != 0.0 { + if cond.From > 0.0 && cond.To > 0.0 { return query.Where("JSON_EXTRACT(footprint, \"$."+jsonField+"\") BETWEEN ? AND ?", cond.From, cond.To) - } else if cond.From != 1.0 && cond.To == 0.0 { + } else if cond.From > 0.0 && cond.To == 0.0 { return query.Where("JSON_EXTRACT(footprint, \"$."+jsonField+"\") >= ?", cond.From) - } else if cond.From == 1.0 && cond.To != 0.0 { + } else if cond.From == 0.0 && cond.To > 0.0 { return query.Where("JSON_EXTRACT(footprint, \"$."+jsonField+"\") <= ?", cond.To) } else { return query diff --git a/internal/routerConfig/routes.go b/internal/routerConfig/routes.go index e24038e2..78bab931 100644 --- a/internal/routerConfig/routes.go +++ b/internal/routerConfig/routes.go @@ -308,7 +308,7 @@ func buildFilterPresets(query url.Values) map[string]any { if parts[0] == "lessthan" { lt, lte := strconv.Atoi(parts[1]) if lte == nil { - filterPresets["numNodes"] = map[string]int{"from": 1, "to": lt} + filterPresets["numNodes"] = map[string]int{"from": 0, "to": lt} } } else if parts[0] == "morethan" { mt, mte := strconv.Atoi(parts[1]) @@ -330,7 +330,7 @@ func buildFilterPresets(query url.Values) map[string]any { if parts[0] == "lessthan" { lt, lte := strconv.Atoi(parts[1]) if lte == nil { - filterPresets["numHWThreads"] = map[string]int{"from": 1, "to": lt} + filterPresets["numHWThreads"] = map[string]int{"from": 0, "to": lt} } } else if parts[0] == "morethan" { mt, mte := strconv.Atoi(parts[1]) @@ -352,7 +352,7 @@ func buildFilterPresets(query url.Values) map[string]any { if parts[0] == "lessthan" { lt, lte := strconv.Atoi(parts[1]) if lte == nil { - filterPresets["numAccelerators"] = map[string]int{"from": 1, "to": lt} + filterPresets["numAccelerators"] = map[string]int{"from": 0, "to": lt} } } else if parts[0] == "morethan" { mt, mte := strconv.Atoi(parts[1]) @@ -408,7 +408,7 @@ func buildFilterPresets(query url.Values) map[string]any { if parts[0] == "lessthan" { lt, lte := strconv.Atoi(parts[1]) if lte == nil { - filterPresets["energy"] = map[string]int{"from": 1, "to": lt} + filterPresets["energy"] = map[string]int{"from": 0, "to": lt} } } else if parts[0] == "morethan" { mt, mte := strconv.Atoi(parts[1]) @@ -434,7 +434,7 @@ func buildFilterPresets(query url.Values) map[string]any { if lte == nil { statEntry := map[string]any{ "field": parts[0], - "from": 1, + "from": 0, "to": lt, } statList = append(statList, statEntry) diff --git a/web/frontend/src/generic/Filters.svelte b/web/frontend/src/generic/Filters.svelte index 02f801a0..3c0091ad 100644 --- a/web/frontend/src/generic/Filters.svelte +++ b/web/frontend/src/generic/Filters.svelte @@ -166,12 +166,12 @@ items.push({ project: { [filters.projectMatch]: filters.project } }); if (filters.user) items.push({ user: { [filters.userMatch]: filters.user } }); - if (filters.numNodes.from != null || filters.numNodes.to != null) { + if (filters.numNodes.from != null && filters.numNodes.to != null) { items.push({ numNodes: { from: filters.numNodes.from, to: filters.numNodes.to }, }); } - if (filters.numAccelerators.from != null || filters.numAccelerators.to != null) { + if (filters.numAccelerators.from != null && filters.numAccelerators.to != null) { items.push({ numAccelerators: { from: filters.numAccelerators.from, @@ -179,7 +179,7 @@ }, }); } - if (filters.numHWThreads.from != null || filters.numHWThreads.to != null) { + if (filters.numHWThreads.from != null && filters.numHWThreads.to != null) { items.push({ numHWThreads: { from: filters.numHWThreads.from, @@ -206,14 +206,21 @@ items.push({ duration: { to: filters.duration.lessThan, from: 0 } }); if (filters.duration.moreThan) items.push({ duration: { to: 0, from: filters.duration.moreThan } }); - if (filters.energy.from != null || filters.energy.to != null) + if (filters.energy.from != null && filters.energy.to != null) items.push({ energy: { from: filters.energy.from, to: filters.energy.to }, }); if (filters.jobId) items.push({ jobId: { [filters.jobIdMatch]: filters.jobId } }); - if (filters.stats.length != 0) - items.push({ metricStats: filters.stats.map((st) => { return { metricName: st.field, range: { from: st.from, to: st.to }} }) }); + if (filters.stats.length != 0) { + const metricStats = []; + filters.stats.forEach((st) => { + if (st.from != null && st.to != null) + metricStats.push({ metricName: st.field, range: { from: st.from, to: st.to }}); + }); + if (metricStats.length != 0) + items.push({metricStats}) + }; if (filters.node) items.push({ node: { [filters.nodeMatch]: filters.node } }); if (filters.jobName) items.push({ jobName: { contains: filters.jobName } }); if (filters.schedule) items.push({ schedule: filters.schedule }); @@ -280,40 +287,40 @@ opts.push(`duration=morethan-${filters.duration.moreThan}`); if (filters.tags.length != 0) for (let tag of filters.tags) opts.push(`tag=${tag}`); - if (filters.numNodes.from > 1 && filters.numNodes.to > 0) + if (filters.numNodes.from > 0 && filters.numNodes.to > 0) opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`); - else if (filters.numNodes.from > 1 && filters.numNodes.to == 0) + else if (filters.numNodes.from > 0 && filters.numNodes.to == 0) opts.push(`numNodes=morethan-${filters.numNodes.from}`); - else if (filters.numNodes.from == 1 && filters.numNodes.to > 0) + else if (filters.numNodes.from == 0 && filters.numNodes.to > 0) opts.push(`numNodes=lessthan-${filters.numNodes.to}`); - if (filters.numHWThreads.from > 1 && filters.numHWThreads.to > 0) + if (filters.numHWThreads.from > 0 && filters.numHWThreads.to > 0) opts.push(`numHWThreads=${filters.numHWThreads.from}-${filters.numHWThreads.to}`); - else if (filters.numHWThreads.from > 1 && filters.numHWThreads.to == 0) + else if (filters.numHWThreads.from > 0 && filters.numHWThreads.to == 0) opts.push(`numHWThreads=morethan-${filters.numHWThreads.from}`); - else if (filters.numHWThreads.from == 1 && filters.numHWThreads.to > 0) + else if (filters.numHWThreads.from == 0 && filters.numHWThreads.to > 0) opts.push(`numHWThreads=lessthan-${filters.numHWThreads.to}`); - if (filters.numAccelerators.from && filters.numAccelerators.to) + if (filters.numAccelerators.from > 0 && filters.numAccelerators.to > 0) opts.push(`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`); - else if (filters.numAccelerators.from > 1 && filters.numAccelerators.to == 0) + else if (filters.numAccelerators.from > 0 && filters.numAccelerators.to == 0) opts.push(`numAccelerators=morethan-${filters.numAccelerators.from}`); - else if (filters.numAccelerators.from == 1 && filters.numAccelerators.to > 0) + else if (filters.numAccelerators.from == 0 && filters.numAccelerators.to > 0) opts.push(`numAccelerators=lessthan-${filters.numAccelerators.to}`); if (filters.node) opts.push(`node=${filters.node}`); if (filters.node && filters.nodeMatch != "eq") // "eq" is default-case opts.push(`nodeMatch=${filters.nodeMatch}`); - if (filters.energy.from > 1 && filters.energy.to > 0) + if (filters.energy.from > 0 && filters.energy.to > 0) opts.push(`energy=${filters.energy.from}-${filters.energy.to}`); - else if (filters.energy.from > 1 && filters.energy.to == 0) + else if (filters.energy.from > 0 && filters.energy.to == 0) opts.push(`energy=morethan-${filters.energy.from}`); - else if (filters.energy.from == 1 && filters.energy.to > 0) + else if (filters.energy.from == 0 && filters.energy.to > 0) opts.push(`energy=lessthan-${filters.energy.to}`); if (filters.stats.length > 0) for (let stat of filters.stats) { - if (stat.from > 1 && stat.to > 0) + if (stat.from > 0 && stat.to > 0) opts.push(`stat=${stat.field}-${stat.from}-${stat.to}`); - else if (stat.from > 1 && stat.to == 0) + else if (stat.from > 0 && stat.to == 0) opts.push(`stat=${stat.field}-morethan-${stat.from}`); - else if (stat.from == 1 && stat.to > 0) + else if (stat.from == 0 && stat.to > 0) opts.push(`stat=${stat.field}-lessthan-${stat.to}`); } // Build && Return @@ -511,43 +518,43 @@ {/if} - {#if filters.numNodes.from > 1 && filters.numNodes.to > 0} + {#if filters.numNodes.from > 0 && filters.numNodes.to > 0} (isResourcesOpen = true)}> Nodes: {filters.numNodes.from} - {filters.numNodes.to} - {:else if filters.numNodes.from > 1 && filters.numNodes.to == 0} + {:else if filters.numNodes.from > 0 && filters.numNodes.to == 0} (isResourcesOpen = true)}>  ≥ {filters.numNodes.from} Node(s) - {:else if filters.numNodes.from == 1 && filters.numNodes.to > 0} + {:else if filters.numNodes.from == 0 && filters.numNodes.to > 0} (isResourcesOpen = true)}>  ≤ {filters.numNodes.to} Node(s) {/if} - {#if filters.numHWThreads.from > 1 && filters.numHWThreads.to > 0} + {#if filters.numHWThreads.from > 0 && filters.numHWThreads.to > 0} (isResourcesOpen = true)}> HWThreads: {filters.numHWThreads.from} - {filters.numHWThreads.to} - {:else if filters.numHWThreads.from > 1 && filters.numHWThreads.to == 0} + {:else if filters.numHWThreads.from > 0 && filters.numHWThreads.to == 0} (isResourcesOpen = true)}>  ≥ {filters.numHWThreads.from} HWThread(s) - {:else if filters.numHWThreads.from == 1 && filters.numHWThreads.to > 0} + {:else if filters.numHWThreads.from == 0 && filters.numHWThreads.to > 0} (isResourcesOpen = true)}>  ≤ {filters.numHWThreads.to} HWThread(s) {/if} - {#if filters.numAccelerators.from > 1 && filters.numAccelerators.to > 0} + {#if filters.numAccelerators.from > 0 && filters.numAccelerators.to > 0} (isResourcesOpen = true)}> Accelerators: {filters.numAccelerators.from} - {filters.numAccelerators.to} - {:else if filters.numAccelerators.from > 1 && filters.numAccelerators.to == 0} + {:else if filters.numAccelerators.from > 0 && filters.numAccelerators.to == 0} (isResourcesOpen = true)}>  ≥ {filters.numAccelerators.from} Acc(s) - {:else if filters.numAccelerators.from == 1 && filters.numAccelerators.to > 0} + {:else if filters.numAccelerators.from == 0 && filters.numAccelerators.to > 0} (isResourcesOpen = true)}>  ≤ {filters.numAccelerators.to} Acc(s) @@ -559,15 +566,15 @@ {/if} - {#if filters.energy.from > 1 && filters.energy.to > 0} + {#if filters.energy.from > 0 && filters.energy.to > 0} (isEnergyOpen = true)}> Total Energy: {filters.energy.from} - {filters.energy.to} kWh - {:else if filters.energy.from > 1 && filters.energy.to == 0} + {:else if filters.energy.from > 0 && filters.energy.to == 0} (isEnergyOpen = true)}> Total Energy ≥ {filters.energy.from} kWh - {:else if filters.energy.from == 1 && filters.energy.to > 0} + {:else if filters.energy.from == 0 && filters.energy.to > 0} (isEnergyOpen = true)}> Total Energy ≤ {filters.energy.to} kWh @@ -575,15 +582,15 @@ {#if filters.stats.length > 0} {#each filters.stats as stat} - {#if stat.from > 1 && stat.to > 0} + {#if stat.from > 0 && stat.to > 0} (isStatsOpen = true)}> {stat.field}: {stat.from} - {stat.to} {stat.unit}   - {:else if stat.from > 1 && stat.to == 0} + {:else if stat.from > 0 && stat.to == 0} (isStatsOpen = true)}> {stat.field} ≥ {stat.from} {stat.unit}   - {:else if stat.from == 1 && stat.to > 0} + {:else if stat.from == 0 && stat.to > 0} (isStatsOpen = true)}> {stat.field} ≤ {stat.to} {stat.unit}   diff --git a/web/frontend/src/generic/filters/Energy.svelte b/web/frontend/src/generic/filters/Energy.svelte index dc532c86..c8013b1b 100644 --- a/web/frontend/src/generic/filters/Energy.svelte +++ b/web/frontend/src/generic/filters/Energy.svelte @@ -28,31 +28,29 @@ } = $props(); /* Const */ - const minEnergyPreset = 1; + const minEnergyPreset = 0; const maxEnergyPreset = 100; /* Derived */ // Pending let pendingEnergyState = $derived({ - from: presetEnergy?.from ? presetEnergy.from : minEnergyPreset, - to: !(presetEnergy.to == null || presetEnergy.to == 0) ? presetEnergy.to : maxEnergyPreset, + from: presetEnergy?.from || minEnergyPreset, + to: (presetEnergy.to == 0) ? null : presetEnergy.to, }); // Changable let energyState = $derived({ - from: presetEnergy?.from ? presetEnergy.from : minEnergyPreset, - to: !(presetEnergy.to == null || presetEnergy.to == 0) ? presetEnergy.to : maxEnergyPreset, + from: presetEnergy?.from || minEnergyPreset, + to: (presetEnergy.to == 0) ? null : presetEnergy.to, }); - const energyActive = $derived(!(JSON.stringify(energyState) === JSON.stringify({ from: minEnergyPreset, to: maxEnergyPreset }))); - // Block Apply if null - const disableApply = $derived(energyState.from === null || energyState.to === null); + const energyActive = $derived(!(JSON.stringify(energyState) === JSON.stringify({ from: minEnergyPreset, to: null }))); /* Function */ function setEnergy() { if (energyActive) { pendingEnergyState = { - from: energyState.from, - to: (energyState.to == maxEnergyPreset) ? 0 : energyState.to + from: (!energyState?.from) ? 0 : energyState.from, + to: (energyState.to === null) ? 0 : energyState.to }; } else { pendingEnergyState = { from: null, to: null}; @@ -86,7 +84,6 @@