Fix: default values and new option for time filter

This commit is contained in:
Christoph Kluge 2023-11-15 15:03:58 +01:00
parent bf64fc5213
commit 84d6b48353
3 changed files with 120 additions and 39 deletions

View File

@ -1,18 +1,23 @@
<script> <script>
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { Row, Col, Button, Modal, ModalBody, ModalHeader, ModalFooter, FormGroup } from 'sveltestrap' import { Row, Col, Button, Modal, ModalBody, ModalHeader, ModalFooter } from 'sveltestrap'
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
export let isOpen = false export let isOpen = false
export let from = null export let lessThan = null
export let to = null export let moreThan = null
export let from = null
export let to = null
let pendingFrom, pendingTo let pendingLessThan, pendingMoreThan, pendingFrom, pendingTo
let lessDisabled = false, moreDisabled = false, betweenDisabled = false
function reset() { function reset() {
pendingFrom = from == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(from) pendingLessThan = lessThan == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(lessThan)
pendingTo = to == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(to) pendingMoreThan = moreThan == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(moreThan)
pendingFrom = from == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(from)
pendingTo = to == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(to)
} }
reset() reset()
@ -27,18 +32,23 @@
function hoursAndMinsToSecs({ hours, mins }) { function hoursAndMinsToSecs({ hours, mins }) {
return hours * 3600 + mins * 60 return hours * 3600 + mins * 60
} }
$: lessDisabled = pendingMoreThan.hours !== 0 || pendingMoreThan.mins !== 0 || pendingFrom.hours !== 0 || pendingFrom.mins !== 0 || pendingTo.hours !== 0 || pendingTo.mins !== 0
$: moreDisabled = pendingLessThan.hours !== 0 || pendingLessThan.mins !== 0 || pendingFrom.hours !== 0 || pendingFrom.mins !== 0 || pendingTo.hours !== 0 || pendingTo.mins !== 0
$: betweenDisabled = pendingMoreThan.hours !== 0 || pendingMoreThan.mins !== 0 || pendingLessThan.hours !== 0 || pendingLessThan.mins !== 0
</script> </script>
<Modal isOpen={isOpen} toggle={() => (isOpen = !isOpen)}> <Modal isOpen={isOpen} toggle={() => (isOpen = !isOpen)}>
<ModalHeader> <ModalHeader>
Select Start Time Select Job Duration
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
<h4>Between</h4> <h4>Duration more than</h4>
<Row> <Row>
<Col> <Col>
<div class="input-group mb-2 mr-sm-2"> <div class="input-group mb-2 mr-sm-2">
<input type="number" class="form-control" bind:value={pendingFrom.hours}> <input type="number" min="0" class="form-control" bind:value={pendingMoreThan.hours} disabled={moreDisabled}>
<div class="input-group-append"> <div class="input-group-append">
<div class="input-group-text">h</div> <div class="input-group-text">h</div>
</div> </div>
@ -46,7 +56,49 @@
</Col> </Col>
<Col> <Col>
<div class="input-group mb-2 mr-sm-2"> <div class="input-group mb-2 mr-sm-2">
<input type="number" class="form-control" bind:value={pendingFrom.mins}> <input type="number" min="0" max="59" class="form-control" bind:value={pendingMoreThan.mins} disabled={moreDisabled}>
<div class="input-group-append">
<div class="input-group-text">m</div>
</div>
</div>
</Col>
</Row>
<hr/>
<h4>Duration less than</h4>
<Row>
<Col>
<div class="input-group mb-2 mr-sm-2">
<input type="number" min="0" class="form-control" bind:value={pendingLessThan.hours} disabled={lessDisabled}>
<div class="input-group-append">
<div class="input-group-text">h</div>
</div>
</div>
</Col>
<Col>
<div class="input-group mb-2 mr-sm-2">
<input type="number" min="0" max="59" class="form-control" bind:value={pendingLessThan.mins} disabled={lessDisabled}>
<div class="input-group-append">
<div class="input-group-text">m</div>
</div>
</div>
</Col>
</Row>
<hr/>
<h4>Duration between</h4>
<Row>
<Col>
<div class="input-group mb-2 mr-sm-2">
<input type="number" min="0" class="form-control" bind:value={pendingFrom.hours} disabled={betweenDisabled}>
<div class="input-group-append">
<div class="input-group-text">h</div>
</div>
</div>
</Col>
<Col>
<div class="input-group mb-2 mr-sm-2">
<input type="number" min="0" max="59" class="form-control" bind:value={pendingFrom.mins} disabled={betweenDisabled}>
<div class="input-group-append"> <div class="input-group-append">
<div class="input-group-text">m</div> <div class="input-group-text">m</div>
</div> </div>
@ -57,7 +109,7 @@
<Row> <Row>
<Col> <Col>
<div class="input-group mb-2 mr-sm-2"> <div class="input-group mb-2 mr-sm-2">
<input type="number" class="form-control" bind:value={pendingTo.hours}> <input type="number" min="0" class="form-control" bind:value={pendingTo.hours} disabled={betweenDisabled}>
<div class="input-group-append"> <div class="input-group-append">
<div class="input-group-text">h</div> <div class="input-group-text">h</div>
</div> </div>
@ -65,7 +117,7 @@
</Col> </Col>
<Col> <Col>
<div class="input-group mb-2 mr-sm-2"> <div class="input-group mb-2 mr-sm-2">
<input type="number" class="form-control" bind:value={pendingTo.mins}> <input type="number" min="0" max="59" class="form-control" bind:value={pendingTo.mins} disabled={betweenDisabled}>
<div class="input-group-append"> <div class="input-group-append">
<div class="input-group-text">m</div> <div class="input-group-text">m</div>
</div> </div>
@ -77,19 +129,30 @@
<Button color="primary" <Button color="primary"
on:click={() => { on:click={() => {
isOpen = false isOpen = false
lessThan = hoursAndMinsToSecs(pendingLessThan)
moreThan = hoursAndMinsToSecs(pendingMoreThan)
from = hoursAndMinsToSecs(pendingFrom) from = hoursAndMinsToSecs(pendingFrom)
to = hoursAndMinsToSecs(pendingTo) to = hoursAndMinsToSecs(pendingTo)
dispatch('update', { from, to }) dispatch('update', { lessThan, moreThan, from, to })
}}> }}>
Close & Apply Close & Apply
</Button> </Button>
<Button color="danger" on:click={() => { <Button color="warning" on:click={() => {
isOpen = false lessThan = null
moreThan = null
from = null from = null
to = null to = null
reset() reset()
dispatch('update', { from, to }) }}>Reset Values</Button>
}}>Reset</Button> <Button color="danger" on:click={() => {
isOpen = false
lessThan = null
moreThan = null
from = null
to = null
reset()
dispatch('update', { lessThan, moreThan, from, to })
}}>Reset Filter</Button>
<Button on:click={() => (isOpen = false)}>Close</Button> <Button on:click={() => (isOpen = false)}>Close</Button>
</ModalFooter> </ModalFooter>
</Modal> </Modal>

View File

@ -41,7 +41,7 @@
states: filterPresets.states || filterPresets.state ? [filterPresets.state].flat() : allJobStates, states: filterPresets.states || filterPresets.state ? [filterPresets.state].flat() : allJobStates,
startTime: filterPresets.startTime || { from: null, to: null }, startTime: filterPresets.startTime || { from: null, to: null },
tags: filterPresets.tags || [], tags: filterPresets.tags || [],
duration: filterPresets.duration || { from: null, to: null }, duration: filterPresets.duration || { lessThan: null, moreThan: null, from: null, to: null },
jobId: filterPresets.jobId || '', jobId: filterPresets.jobId || '',
arrayJobId: filterPresets.arrayJobId || null, arrayJobId: filterPresets.arrayJobId || null,
user: filterPresets.user || '', user: filterPresets.user || '',
@ -88,6 +88,10 @@
items.push({ tags: filters.tags }) items.push({ tags: filters.tags })
if (filters.duration.from || filters.duration.to) if (filters.duration.from || filters.duration.to)
items.push({ duration: { from: filters.duration.from, to: filters.duration.to } }) items.push({ duration: { from: filters.duration.from, to: filters.duration.to } })
if (filters.duration.lessThan)
items.push({ duration: { from: 0, to: filters.duration.lessThan } })
if (filters.duration.moreThan)
items.push({ duration: { from: filters.duration.moreThan, to: 604800 } }) // 7 days to include special jobs with long runtimes
if (filters.jobId) if (filters.jobId)
items.push({ jobId: { [filters.jobIdMatch]: filters.jobId } }) items.push({ jobId: { [filters.jobIdMatch]: filters.jobId } })
if (filters.arrayJobId != null) if (filters.arrayJobId != null)
@ -144,6 +148,10 @@
opts.push(`tag=${tag}`) opts.push(`tag=${tag}`)
if (filters.duration.from && filters.duration.to) if (filters.duration.from && filters.duration.to)
opts.push(`duration=${filters.duration.from}-${filters.duration.to}`) opts.push(`duration=${filters.duration.from}-${filters.duration.to}`)
if (filters.duration.lessThan)
opts.push(`duration=0-${filters.duration.lessThan}`)
if (filters.duration.moreThan)
opts.push(`duration=${filters.duration.moreThan}-604800`)
if (filters.numNodes.from && filters.numNodes.to) if (filters.numNodes.from && filters.numNodes.to)
opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`) opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`)
if (filters.numAccelerators.from && filters.numAccelerators.to) if (filters.numAccelerators.from && filters.numAccelerators.to)
@ -267,6 +275,18 @@
</Info> </Info>
{/if} {/if}
{#if filters.duration.lessThan}
<Info icon="stopwatch" on:click={() => (isDurationOpen = true)}>
Duration less than {Math.floor(filters.duration.lessThan / 3600)}h:{Math.floor(filters.duration.lessThan % 3600 / 60)}m
</Info>
{/if}
{#if filters.duration.moreThan}
<Info icon="stopwatch" on:click={() => (isDurationOpen = true)}>
Duration more than {Math.floor(filters.duration.moreThan / 3600)}h:{Math.floor(filters.duration.moreThan % 3600 / 60)}m
</Info>
{/if}
{#if filters.tags.length != 0} {#if filters.tags.length != 0}
<Info icon="tags" on:click={() => (isTagsOpen = true)}> <Info icon="tags" on:click={() => (isTagsOpen = true)}>
{#each filters.tags as tagId} {#each filters.tags as tagId}
@ -325,6 +345,8 @@
<Duration <Duration
bind:isOpen={isDurationOpen} bind:isOpen={isDurationOpen}
bind:lessThan={filters.duration.lessThan}
bind:moreThan={filters.duration.moreThan}
bind:from={filters.duration.from} bind:from={filters.duration.from}
bind:to={filters.duration.to} bind:to={filters.duration.to}
on:update={() => update()} /> on:update={() => update()} />

View File

@ -1,5 +1,6 @@
<script> <script>
import { createEventDispatcher, getContext } from 'svelte' import { createEventDispatcher } from 'svelte'
import { parse, format, sub } from 'date-fns'
import { Row, Button, Input, Modal, ModalBody, ModalHeader, ModalFooter, FormGroup } from 'sveltestrap' import { Row, Button, Input, Modal, ModalBody, ModalHeader, ModalFooter, FormGroup } from 'sveltestrap'
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -11,34 +12,29 @@
let pendingFrom, pendingTo let pendingFrom, pendingTo
const now = new Date(Date.now())
const ago = sub(now, {months: 1})
const defaultFrom = {date: format(ago, 'yyyy-MM-dd'), time: format(ago, 'HH:mm')}
const defaultTo = {date: format(now, 'yyyy-MM-dd'), time: format(now, 'HH:mm')}
function reset() { function reset() {
pendingFrom = from == null ? { date: '0000-00-00', time: '00:00' } : fromRFC3339(from) pendingFrom = from == null ? defaultFrom : fromRFC3339(from)
pendingTo = to == null ? { date: '0000-00-00', time: '00:00' } : fromRFC3339(to) pendingTo = to == null ? defaultTo : fromRFC3339(to)
} }
reset() reset()
function toRFC3339({ date, time }, secs = 0) { function toRFC3339({ date, time }, secs = '00') {
const dparts = date.split('-') const parsedDate = parse(date+' '+time+':'+secs, 'yyyy-MM-dd HH:mm:ss', new Date())
const tparts = time.split(':') return parsedDate.toISOString()
const d = new Date(
Number.parseInt(dparts[0]),
Number.parseInt(dparts[1]) - 1,
Number.parseInt(dparts[2]),
Number.parseInt(tparts[0]),
Number.parseInt(tparts[1]), secs)
return d.toISOString()
} }
function fromRFC3339(rfc3339) { function fromRFC3339(rfc3339) {
const d = new Date(rfc3339) const parsedDate = new Date(rfc3339)
const pad = (n) => n.toString().padStart(2, '0') return { date: format(parsedDate, 'yyyy-MM-dd'), time: format(parsedDate, 'HH:mm') }
const date = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
const time = `${pad(d.getHours())}:${pad(d.getMinutes())}`
return { date, time }
} }
$: isModified = (from != toRFC3339(pendingFrom) || to != toRFC3339(pendingTo, 59)) $: isModified = (from != toRFC3339(pendingFrom) || to != toRFC3339(pendingTo, '59'))
&& !(from == null && pendingFrom.date == '0000-00-00' && pendingFrom.time == '00:00') && !(from == null && pendingFrom.date == '0000-00-00' && pendingFrom.time == '00:00')
&& !(to == null && pendingTo.date == '0000-00-00' && pendingTo.time == '00:00') && !(to == null && pendingTo.date == '0000-00-00' && pendingTo.time == '00:00')
</script> </script>
@ -73,7 +69,7 @@
on:click={() => { on:click={() => {
isOpen = false isOpen = false
from = toRFC3339(pendingFrom) from = toRFC3339(pendingFrom)
to = toRFC3339(pendingTo, 59) to = toRFC3339(pendingTo, '59')
dispatch('update', { from, to }) dispatch('update', { from, to })
}}> }}>
Close & Apply Close & Apply