mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2026-03-03 22:57:29 +01:00
optimize resource filter by only using range query if required, review filter component
This commit is contained in:
@@ -305,30 +305,66 @@ func buildFilterPresets(query url.Values) map[string]any {
|
|||||||
if query.Get("numNodes") != "" {
|
if query.Get("numNodes") != "" {
|
||||||
parts := strings.Split(query.Get("numNodes"), "-")
|
parts := strings.Split(query.Get("numNodes"), "-")
|
||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
a, e1 := strconv.Atoi(parts[0])
|
if parts[0] == "lessthan" {
|
||||||
b, e2 := strconv.Atoi(parts[1])
|
lt, lte := strconv.Atoi(parts[1])
|
||||||
if e1 == nil && e2 == nil {
|
if lte == nil {
|
||||||
filterPresets["numNodes"] = map[string]int{"from": a, "to": b}
|
filterPresets["numNodes"] = map[string]int{"from": 1, "to": lt}
|
||||||
|
}
|
||||||
|
} else if parts[0] == "morethan" {
|
||||||
|
mt, mte := strconv.Atoi(parts[1])
|
||||||
|
if mte == nil {
|
||||||
|
filterPresets["numNodes"] = map[string]int{"from": mt, "to": 0}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a, e1 := strconv.Atoi(parts[0])
|
||||||
|
b, e2 := strconv.Atoi(parts[1])
|
||||||
|
if e1 == nil && e2 == nil {
|
||||||
|
filterPresets["numNodes"] = map[string]int{"from": a, "to": b}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if query.Get("numHWThreads") != "" {
|
if query.Get("numHWThreads") != "" {
|
||||||
parts := strings.Split(query.Get("numHWThreads"), "-")
|
parts := strings.Split(query.Get("numHWThreads"), "-")
|
||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
a, e1 := strconv.Atoi(parts[0])
|
if parts[0] == "lessthan" {
|
||||||
b, e2 := strconv.Atoi(parts[1])
|
lt, lte := strconv.Atoi(parts[1])
|
||||||
if e1 == nil && e2 == nil {
|
if lte == nil {
|
||||||
filterPresets["numHWThreads"] = map[string]int{"from": a, "to": b}
|
filterPresets["numHWThreads"] = map[string]int{"from": 1, "to": lt}
|
||||||
|
}
|
||||||
|
} else if parts[0] == "morethan" {
|
||||||
|
mt, mte := strconv.Atoi(parts[1])
|
||||||
|
if mte == nil {
|
||||||
|
filterPresets["numHWThreads"] = map[string]int{"from": mt, "to": 0}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a, e1 := strconv.Atoi(parts[0])
|
||||||
|
b, e2 := strconv.Atoi(parts[1])
|
||||||
|
if e1 == nil && e2 == nil {
|
||||||
|
filterPresets["numHWThreads"] = map[string]int{"from": a, "to": b}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if query.Get("numAccelerators") != "" {
|
if query.Get("numAccelerators") != "" {
|
||||||
parts := strings.Split(query.Get("numAccelerators"), "-")
|
parts := strings.Split(query.Get("numAccelerators"), "-")
|
||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
a, e1 := strconv.Atoi(parts[0])
|
if parts[0] == "lessthan" {
|
||||||
b, e2 := strconv.Atoi(parts[1])
|
lt, lte := strconv.Atoi(parts[1])
|
||||||
if e1 == nil && e2 == nil {
|
if lte == nil {
|
||||||
filterPresets["numAccelerators"] = map[string]int{"from": a, "to": b}
|
filterPresets["numAccelerators"] = map[string]int{"from": 1, "to": lt}
|
||||||
|
}
|
||||||
|
} else if parts[0] == "morethan" {
|
||||||
|
mt, mte := strconv.Atoi(parts[1])
|
||||||
|
if mte == nil {
|
||||||
|
filterPresets["numAccelerators"] = map[string]int{"from": mt, "to": 0}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a, e1 := strconv.Atoi(parts[0])
|
||||||
|
b, e2 := strconv.Atoi(parts[1])
|
||||||
|
if e1 == nil && e2 == nil {
|
||||||
|
filterPresets["numAccelerators"] = map[string]int{"from": a, "to": b}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,12 +280,24 @@
|
|||||||
opts.push(`duration=morethan-${filters.duration.moreThan}`);
|
opts.push(`duration=morethan-${filters.duration.moreThan}`);
|
||||||
if (filters.tags.length != 0)
|
if (filters.tags.length != 0)
|
||||||
for (let tag of filters.tags) opts.push(`tag=${tag}`);
|
for (let tag of filters.tags) opts.push(`tag=${tag}`);
|
||||||
if (filters.numNodes.from && filters.numNodes.to)
|
if (filters.numNodes.from > 1 && filters.numNodes.to > 0)
|
||||||
opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`);
|
opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`);
|
||||||
if (filters.numHWThreads.from && filters.numHWThreads.to)
|
else if (filters.numNodes.from > 1 && filters.numNodes.to == 0)
|
||||||
|
opts.push(`numNodes=morethan-${filters.numNodes.from}`);
|
||||||
|
else if (filters.numNodes.from == 1 && filters.numNodes.to > 0)
|
||||||
|
opts.push(`numNodes=lessthan-${filters.numNodes.to}`);
|
||||||
|
if (filters.numHWThreads.from > 1 && filters.numHWThreads.to > 0)
|
||||||
opts.push(`numHWThreads=${filters.numHWThreads.from}-${filters.numHWThreads.to}`);
|
opts.push(`numHWThreads=${filters.numHWThreads.from}-${filters.numHWThreads.to}`);
|
||||||
|
else if (filters.numHWThreads.from > 1 && filters.numHWThreads.to == 0)
|
||||||
|
opts.push(`numHWThreads=morethan-${filters.numHWThreads.from}`);
|
||||||
|
else if (filters.numHWThreads.from == 1 && filters.numHWThreads.to > 0)
|
||||||
|
opts.push(`numHWThreads=lessthan-${filters.numHWThreads.to}`);
|
||||||
if (filters.numAccelerators.from && filters.numAccelerators.to)
|
if (filters.numAccelerators.from && filters.numAccelerators.to)
|
||||||
opts.push(`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`);
|
opts.push(`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`);
|
||||||
|
else if (filters.numAccelerators.from > 1 && filters.numAccelerators.to == 0)
|
||||||
|
opts.push(`numAccelerators=morethan-${filters.numAccelerators.from}`);
|
||||||
|
else if (filters.numAccelerators.from == 1 && filters.numAccelerators.to > 0)
|
||||||
|
opts.push(`numAccelerators=lessthan-${filters.numAccelerators.to}`);
|
||||||
if (filters.node) opts.push(`node=${filters.node}`);
|
if (filters.node) opts.push(`node=${filters.node}`);
|
||||||
if (filters.node && filters.nodeMatch != "eq") // "eq" is default-case
|
if (filters.node && filters.nodeMatch != "eq") // "eq" is default-case
|
||||||
opts.push(`nodeMatch=${filters.nodeMatch}`);
|
opts.push(`nodeMatch=${filters.nodeMatch}`);
|
||||||
@@ -490,21 +502,45 @@
|
|||||||
</Info>
|
</Info>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if filters.numNodes.from != null || filters.numNodes.to != null}
|
{#if filters.numNodes.from > 1 && filters.numNodes.to > 0}
|
||||||
<Info icon="hdd-stack" onclick={() => (isResourcesOpen = true)}>
|
<Info icon="hdd-stack" onclick={() => (isResourcesOpen = true)}>
|
||||||
Nodes: {filters.numNodes.from} - {filters.numNodes.to}
|
Nodes: {filters.numNodes.from} - {filters.numNodes.to}
|
||||||
|
</Info>
|
||||||
|
{:else if filters.numNodes.from > 1 && filters.numNodes.to == 0}
|
||||||
|
<Info icon="hdd-stack" onclick={() => (isResourcesOpen = true)}>
|
||||||
|
≥ {filters.numNodes.from} Node(s)
|
||||||
|
</Info>
|
||||||
|
{:else if filters.numNodes.from == 1 && filters.numNodes.to > 0}
|
||||||
|
<Info icon="hdd-stack" onclick={() => (isResourcesOpen = true)}>
|
||||||
|
≤ {filters.numNodes.to} Node(s)
|
||||||
</Info>
|
</Info>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if filters.numHWThreads.from != null || filters.numHWThreads.to != null}
|
{#if filters.numHWThreads.from > 1 && filters.numHWThreads.to > 0}
|
||||||
<Info icon="cpu" onclick={() => (isResourcesOpen = true)}>
|
<Info icon="cpu" onclick={() => (isResourcesOpen = true)}>
|
||||||
HWThreads: {filters.numHWThreads.from} - {filters.numHWThreads.to}
|
HWThreads: {filters.numHWThreads.from} - {filters.numHWThreads.to}
|
||||||
|
</Info>
|
||||||
|
{:else if filters.numHWThreads.from > 1 && filters.numHWThreads.to == 0}
|
||||||
|
<Info icon="cpu" onclick={() => (isResourcesOpen = true)}>
|
||||||
|
≥ {filters.numHWThreads.from} HWThread(s)
|
||||||
|
</Info>
|
||||||
|
{:else if filters.numHWThreads.from == 1 && filters.numHWThreads.to > 0}
|
||||||
|
<Info icon="cpu" onclick={() => (isResourcesOpen = true)}>
|
||||||
|
≤ {filters.numHWThreads.to} HWThread(s)
|
||||||
</Info>
|
</Info>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if filters.numAccelerators.from != null || filters.numAccelerators.to != null}
|
{#if filters.numAccelerators.from > 1 && filters.numAccelerators.to > 0}
|
||||||
<Info icon="gpu-card" onclick={() => (isResourcesOpen = true)}>
|
<Info icon="gpu-card" onclick={() => (isResourcesOpen = true)}>
|
||||||
Accelerators: {filters.numAccelerators.from} - {filters.numAccelerators.to}
|
Accelerators: {filters.numAccelerators.from} - {filters.numAccelerators.to}
|
||||||
|
</Info>
|
||||||
|
{:else if filters.numAccelerators.from > 1 && filters.numAccelerators.to == 0}
|
||||||
|
<Info icon="gpu-card" onclick={() => (isResourcesOpen = true)}>
|
||||||
|
≥ {filters.numAccelerators.from} Acc(s)
|
||||||
|
</Info>
|
||||||
|
{:else if filters.numAccelerators.from == 1 && filters.numAccelerators.to > 0}
|
||||||
|
<Info icon="gpu-card" onclick={() => (isResourcesOpen = true)}>
|
||||||
|
≤ {filters.numAccelerators.to} Acc(s)
|
||||||
</Info>
|
</Info>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,9 @@
|
|||||||
ModalBody,
|
ModalBody,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
Input
|
Input,
|
||||||
|
Tooltip,
|
||||||
|
Icon
|
||||||
} from "@sveltestrap/sveltestrap";
|
} from "@sveltestrap/sveltestrap";
|
||||||
import DoubleRangeSlider from "../select/DoubleRangeSlider.svelte";
|
import DoubleRangeSlider from "../select/DoubleRangeSlider.svelte";
|
||||||
|
|
||||||
@@ -42,6 +44,19 @@
|
|||||||
contains: "Contains",
|
contains: "Contains",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const findMaxNumNodes = (infos) =>
|
||||||
|
infos.reduce(
|
||||||
|
(max, cluster) =>
|
||||||
|
Math.max(
|
||||||
|
max,
|
||||||
|
cluster.subClusters.reduce(
|
||||||
|
(max, sc) => Math.max(max, sc.numberOfNodes || 0),
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
const findMaxNumAccels = (infos) =>
|
const findMaxNumAccels = (infos) =>
|
||||||
infos.reduce(
|
infos.reduce(
|
||||||
(max, cluster) =>
|
(max, cluster) =>
|
||||||
@@ -75,29 +90,46 @@
|
|||||||
|
|
||||||
/* State Init*/
|
/* State Init*/
|
||||||
// Counts
|
// Counts
|
||||||
let minNumNodes = $state(1);
|
let maxNumNodes = $state(1);
|
||||||
let maxNumNodes = $state(128);
|
let maxNumHWThreads = $state(1);
|
||||||
let maxNumHWThreads = $state(0);
|
let maxNumAccelerators = $state(1);
|
||||||
let maxNumAccelerators = $state(0);
|
|
||||||
|
|
||||||
/* Derived States */
|
/* Derived States */
|
||||||
// Pending
|
// Pending
|
||||||
let pendingNumNodes = $derived(presetNumNodes);
|
let pendingNumNodes = $derived({
|
||||||
let pendingNumHWThreads = $derived(presetNumHWThreads);
|
from: presetNumNodes.from,
|
||||||
let pendingNumAccelerators = $derived(presetNumAccelerators);
|
to: (presetNumNodes.to == 0) ? maxNumNodes : presetNumNodes.to
|
||||||
|
});
|
||||||
|
let pendingNumHWThreads = $derived({
|
||||||
|
from: presetNumHWThreads.from,
|
||||||
|
to: (presetNumHWThreads.to == 0) ? maxNumHWThreads : presetNumHWThreads.to
|
||||||
|
});
|
||||||
|
let pendingNumAccelerators = $derived({
|
||||||
|
from: presetNumAccelerators.from,
|
||||||
|
to: (presetNumAccelerators.to == 0) ? maxNumAccelerators : presetNumAccelerators.to
|
||||||
|
});
|
||||||
let pendingNamedNode = $derived(presetNamedNode);
|
let pendingNamedNode = $derived(presetNamedNode);
|
||||||
let pendingNodeMatch = $derived(presetNodeMatch);
|
let pendingNodeMatch = $derived(presetNodeMatch);
|
||||||
// Changable States
|
// Changable States
|
||||||
let nodesState = $derived(presetNumNodes);
|
let nodesState = $derived({
|
||||||
let threadState = $derived(presetNumHWThreads);
|
from: presetNumNodes.from,
|
||||||
let accState = $derived(presetNumAccelerators);
|
to: (presetNumNodes.to == 0) ? maxNumNodes : presetNumNodes.to
|
||||||
|
});
|
||||||
|
let threadState = $derived({
|
||||||
|
from: presetNumHWThreads.from,
|
||||||
|
to: (presetNumHWThreads.to == 0) ? maxNumHWThreads : presetNumHWThreads.to
|
||||||
|
});
|
||||||
|
let accState = $derived({
|
||||||
|
from: presetNumAccelerators.from,
|
||||||
|
to: (presetNumAccelerators.to == 0) ? maxNumAccelerators : presetNumAccelerators.to
|
||||||
|
});
|
||||||
|
|
||||||
const initialized = $derived(getContext("initialized") || false);
|
const initialized = $derived(getContext("initialized") || false);
|
||||||
const clusterInfos = $derived($initialized ? getContext("clusters") : null);
|
const clusterInfos = $derived($initialized ? getContext("clusters") : null);
|
||||||
// Is Selection Active
|
// Is Selection Active
|
||||||
const nodesActive = $derived(!(JSON.stringify(nodesState) === JSON.stringify({ from: 1, to: maxNumNodes })));
|
const nodesActive = $derived(!(JSON.stringify(nodesState) === JSON.stringify({ from: 1, to: maxNumNodes })));
|
||||||
const threadActive = $derived(!(JSON.stringify(threadState) === JSON.stringify({ from: 1, to: maxNumHWThreads })));
|
const threadActive = $derived(!(JSON.stringify(threadState) === JSON.stringify({ from: 1, to: maxNumHWThreads })));
|
||||||
const accActive = $derived(!(JSON.stringify(accState) === JSON.stringify({ from: 0, to: maxNumAccelerators })));
|
const accActive = $derived(!(JSON.stringify(accState) === JSON.stringify({ from: 1, to: maxNumAccelerators })));
|
||||||
// Block Apply if null
|
// Block Apply if null
|
||||||
const disableApply = $derived(
|
const disableApply = $derived(
|
||||||
nodesState.from === null || nodesState.to === null ||
|
nodesState.from === null || nodesState.to === null ||
|
||||||
@@ -110,11 +142,13 @@
|
|||||||
if ($initialized) {
|
if ($initialized) {
|
||||||
if (activeCluster != null) {
|
if (activeCluster != null) {
|
||||||
const { subClusters } = clusterInfos.find((c) => c.name == activeCluster);
|
const { subClusters } = clusterInfos.find((c) => c.name == activeCluster);
|
||||||
maxNumAccelerators = findMaxNumAccels([{ subClusters }]);
|
maxNumNodes = findMaxNumNodes([{ subClusters }]);
|
||||||
maxNumHWThreads = findMaxNumHWThreadsPerNode([{ subClusters }]);
|
maxNumHWThreads = findMaxNumHWThreadsPerNode([{ subClusters }]);
|
||||||
|
maxNumAccelerators = findMaxNumAccels([{ subClusters }]);
|
||||||
} else if (clusterInfos.length > 0) {
|
} else if (clusterInfos.length > 0) {
|
||||||
maxNumAccelerators = findMaxNumAccels(clusterInfos);
|
maxNumNodes = findMaxNumNodes(clusterInfos);
|
||||||
maxNumHWThreads = findMaxNumHWThreadsPerNode(clusterInfos);
|
maxNumHWThreads = findMaxNumHWThreadsPerNode(clusterInfos);
|
||||||
|
maxNumAccelerators = findMaxNumAccels(clusterInfos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -145,26 +179,35 @@
|
|||||||
pendingNumAccelerators.from == null &&
|
pendingNumAccelerators.from == null &&
|
||||||
pendingNumAccelerators.to == null
|
pendingNumAccelerators.to == null
|
||||||
) {
|
) {
|
||||||
accState = { from: 0, to: maxNumAccelerators };
|
accState = { from: 1, to: maxNumAccelerators };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
function setResources() {
|
function setResources() {
|
||||||
if (nodesActive) {
|
if (nodesActive) {
|
||||||
pendingNumNodes = {...nodesState};
|
pendingNumNodes = {
|
||||||
|
from: nodesState.from,
|
||||||
|
to: (nodesState.to == maxNumNodes) ? 0 : nodesState.to
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
pendingNumNodes = { from: null, to: null };
|
pendingNumNodes = { from: null, to: null};
|
||||||
};
|
};
|
||||||
if (threadActive) {
|
if (threadActive) {
|
||||||
pendingNumHWThreads = {...threadState};
|
pendingNumHWThreads = {
|
||||||
|
from: threadState.from,
|
||||||
|
to: (threadState.to == maxNumHWThreads) ? 0 : threadState.to
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
pendingNumHWThreads = { from: null, to: null };
|
pendingNumHWThreads = { from: null, to: null};
|
||||||
};
|
};
|
||||||
if (accActive) {
|
if (accActive) {
|
||||||
pendingNumAccelerators = {...accState};
|
pendingNumAccelerators = {
|
||||||
|
from: accState.from,
|
||||||
|
to: (accState.to == maxNumAccelerators) ? 0 : accState.to
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
pendingNumAccelerators = { from: null, to: null };
|
pendingNumAccelerators = { from: null, to: null};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -195,13 +238,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="mb-0"><b>Number of Nodes</b></div>
|
<div class="mb-0"><b>Number of Nodes</b>
|
||||||
|
<Icon id="numnodes-info" style="cursor:help; padding-right: 10px;" size="sm" name="info-circle"/>
|
||||||
|
</div>
|
||||||
|
<Tooltip target={`numnodes-info`} placement="right">
|
||||||
|
Preset maximum is for whole cluster.
|
||||||
|
</Tooltip>
|
||||||
<DoubleRangeSlider
|
<DoubleRangeSlider
|
||||||
changeRange={(detail) => {
|
changeRange={(detail) => {
|
||||||
nodesState.from = detail[0];
|
nodesState.from = detail[0];
|
||||||
nodesState.to = detail[1];
|
nodesState.to = detail[1];
|
||||||
}}
|
}}
|
||||||
sliderMin={minNumNodes}
|
sliderMin={1}
|
||||||
sliderMax={maxNumNodes}
|
sliderMax={maxNumNodes}
|
||||||
fromPreset={nodesState.from}
|
fromPreset={nodesState.from}
|
||||||
toPreset={nodesState.to}
|
toPreset={nodesState.to}
|
||||||
@@ -209,7 +257,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="mb-0"><b>Number of HWThreads</b> (Use for Single-Node Jobs)</div>
|
<div class="mb-0">
|
||||||
|
<b>Number of HWThreads</b>
|
||||||
|
<Icon id="numthreads-info" style="cursor:help; padding-right: 10px;" size="sm" name="info-circle"/>
|
||||||
|
</div>
|
||||||
|
<Tooltip target={`numthreads-info`} placement="right">
|
||||||
|
Presets for a single node. Can be changed to higher values.
|
||||||
|
</Tooltip>
|
||||||
<DoubleRangeSlider
|
<DoubleRangeSlider
|
||||||
changeRange={(detail) => {
|
changeRange={(detail) => {
|
||||||
threadState.from = detail[0];
|
threadState.from = detail[0];
|
||||||
@@ -223,13 +277,19 @@
|
|||||||
</div>
|
</div>
|
||||||
{#if maxNumAccelerators != null && maxNumAccelerators > 1}
|
{#if maxNumAccelerators != null && maxNumAccelerators > 1}
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-0"><b>Number of Accelerators</b></div>
|
<div class="mb-0">
|
||||||
|
<b>Number of Accelerators</b>
|
||||||
|
<Icon id="numaccs-info" style="cursor:help; padding-right: 10px;" size="sm" name="info-circle"/>
|
||||||
|
</div>
|
||||||
|
<Tooltip target={`numaccs-info`} placement="right">
|
||||||
|
Presets for a single node. Can be changed to higher values.
|
||||||
|
</Tooltip>
|
||||||
<DoubleRangeSlider
|
<DoubleRangeSlider
|
||||||
changeRange={(detail) => {
|
changeRange={(detail) => {
|
||||||
accState.from = detail[0];
|
accState.from = detail[0];
|
||||||
accState.to = detail[1];
|
accState.to = detail[1];
|
||||||
}}
|
}}
|
||||||
sliderMin={0}
|
sliderMin={1}
|
||||||
sliderMax={maxNumAccelerators}
|
sliderMax={maxNumAccelerators}
|
||||||
fromPreset={accState.from}
|
fromPreset={accState.from}
|
||||||
toPreset={accState.to}
|
toPreset={accState.to}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
let pendingValues = $derived([fromPreset, toPreset]);
|
let pendingValues = $derived([fromPreset, toPreset]);
|
||||||
let sliderFrom = $derived(Math.max(((fromPreset == null ? sliderMin : fromPreset) - sliderMin) / (sliderMax - sliderMin), 0.));
|
let sliderFrom = $derived(Math.max(((fromPreset == null ? sliderMin : fromPreset) - sliderMin) / (sliderMax - sliderMin), 0.));
|
||||||
let sliderTo = $derived(Math.min(((toPreset == null ? sliderMin : toPreset) - sliderMin) / (sliderMax - sliderMin), 1.));
|
let sliderTo = $derived(Math.min(((toPreset == null ? sliderMin : toPreset) - sliderMin) / (sliderMax - sliderMin), 1.));
|
||||||
let inputFieldFrom = $derived(fromPreset.toString());
|
let inputFieldFrom = $derived(fromPreset ? fromPreset.toString() : null);
|
||||||
let inputFieldTo = $derived(toPreset.toString());
|
let inputFieldTo = $derived(toPreset ? toPreset.toString() : null);
|
||||||
|
|
||||||
/* Var Init */
|
/* Var Init */
|
||||||
let timeoutId = null;
|
let timeoutId = null;
|
||||||
@@ -160,12 +160,26 @@
|
|||||||
<div class="double-range-container">
|
<div class="double-range-container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<input class="form-control" type="text" placeholder="from..." value={inputFieldFrom}
|
<input class="form-control" type="text" placeholder="from..." value={inputFieldFrom}
|
||||||
oninput={(e) => inputChanged(e, 'from')} />
|
oninput={(e) => {
|
||||||
|
inputChanged(e, 'from');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<span>Full Range: <b> {sliderMin} </b> - <b> {sliderMax} </b></span>
|
{#if inputFieldFrom != "1" && inputFieldTo != sliderMax?.toString() }
|
||||||
|
<span>Selected: Range <b> {inputFieldFrom} </b> - <b> {inputFieldTo} </b></span>
|
||||||
|
{:else if inputFieldFrom != "1" && inputFieldTo == sliderMax?.toString() }
|
||||||
|
<span>Selected: More than <b> {inputFieldFrom} </b> </span>
|
||||||
|
{:else if inputFieldFrom == "1" && inputFieldTo != sliderMax?.toString() }
|
||||||
|
<span>Selected: Less than <b> {inputFieldTo} </b></span>
|
||||||
|
{:else}
|
||||||
|
<span><i>No Selection</i></span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<input class="form-control" type="text" placeholder="to..." value={inputFieldTo}
|
<input class="form-control" type="text" placeholder="to..." value={inputFieldTo}
|
||||||
oninput={(e) => inputChanged(e, 'to')} />
|
oninput={(e) => {
|
||||||
|
inputChanged(e, 'to');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="slider-active" class="slider" bind:this={sliderMain}>
|
<div id="slider-active" class="slider" bind:this={sliderMain}>
|
||||||
|
|||||||
Reference in New Issue
Block a user