mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-01-13 13:09:05 +01:00
Fix: default values and new option for time filter
This commit is contained in:
parent
bf64fc5213
commit
84d6b48353
@ -1,18 +1,23 @@
|
||||
<script>
|
||||
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()
|
||||
|
||||
export let isOpen = false
|
||||
export let from = null
|
||||
export let to = null
|
||||
export let isOpen = false
|
||||
export let lessThan = 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() {
|
||||
pendingFrom = from == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(from)
|
||||
pendingTo = to == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(to)
|
||||
pendingLessThan = lessThan == null ? { hours: 0, mins: 0 } : secsToHoursAndMins(lessThan)
|
||||
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()
|
||||
@ -27,18 +32,23 @@
|
||||
function hoursAndMinsToSecs({ hours, mins }) {
|
||||
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>
|
||||
|
||||
<Modal isOpen={isOpen} toggle={() => (isOpen = !isOpen)}>
|
||||
<ModalHeader>
|
||||
Select Start Time
|
||||
Select Job Duration
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<h4>Between</h4>
|
||||
<h4>Duration more than</h4>
|
||||
<Row>
|
||||
<Col>
|
||||
<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-text">h</div>
|
||||
</div>
|
||||
@ -46,7 +56,49 @@
|
||||
</Col>
|
||||
<Col>
|
||||
<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-text">m</div>
|
||||
</div>
|
||||
@ -57,7 +109,7 @@
|
||||
<Row>
|
||||
<Col>
|
||||
<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-text">h</div>
|
||||
</div>
|
||||
@ -65,7 +117,7 @@
|
||||
</Col>
|
||||
<Col>
|
||||
<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-text">m</div>
|
||||
</div>
|
||||
@ -77,19 +129,30 @@
|
||||
<Button color="primary"
|
||||
on:click={() => {
|
||||
isOpen = false
|
||||
lessThan = hoursAndMinsToSecs(pendingLessThan)
|
||||
moreThan = hoursAndMinsToSecs(pendingMoreThan)
|
||||
from = hoursAndMinsToSecs(pendingFrom)
|
||||
to = hoursAndMinsToSecs(pendingTo)
|
||||
dispatch('update', { from, to })
|
||||
dispatch('update', { lessThan, moreThan, from, to })
|
||||
}}>
|
||||
Close & Apply
|
||||
</Button>
|
||||
<Button color="danger" on:click={() => {
|
||||
isOpen = false
|
||||
<Button color="warning" on:click={() => {
|
||||
lessThan = null
|
||||
moreThan = null
|
||||
from = null
|
||||
to = null
|
||||
reset()
|
||||
dispatch('update', { from, to })
|
||||
}}>Reset</Button>
|
||||
}}>Reset Values</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>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
|
@ -41,7 +41,7 @@
|
||||
states: filterPresets.states || filterPresets.state ? [filterPresets.state].flat() : allJobStates,
|
||||
startTime: filterPresets.startTime || { from: null, to: null },
|
||||
tags: filterPresets.tags || [],
|
||||
duration: filterPresets.duration || { from: null, to: null },
|
||||
duration: filterPresets.duration || { lessThan: null, moreThan: null, from: null, to: null },
|
||||
jobId: filterPresets.jobId || '',
|
||||
arrayJobId: filterPresets.arrayJobId || null,
|
||||
user: filterPresets.user || '',
|
||||
@ -88,6 +88,10 @@
|
||||
items.push({ tags: filters.tags })
|
||||
if (filters.duration.from || 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)
|
||||
items.push({ jobId: { [filters.jobIdMatch]: filters.jobId } })
|
||||
if (filters.arrayJobId != null)
|
||||
@ -144,6 +148,10 @@
|
||||
opts.push(`tag=${tag}`)
|
||||
if (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)
|
||||
opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`)
|
||||
if (filters.numAccelerators.from && filters.numAccelerators.to)
|
||||
@ -267,6 +275,18 @@
|
||||
</Info>
|
||||
{/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}
|
||||
<Info icon="tags" on:click={() => (isTagsOpen = true)}>
|
||||
{#each filters.tags as tagId}
|
||||
@ -325,6 +345,8 @@
|
||||
|
||||
<Duration
|
||||
bind:isOpen={isDurationOpen}
|
||||
bind:lessThan={filters.duration.lessThan}
|
||||
bind:moreThan={filters.duration.moreThan}
|
||||
bind:from={filters.duration.from}
|
||||
bind:to={filters.duration.to}
|
||||
on:update={() => update()} />
|
||||
|
@ -1,5 +1,6 @@
|
||||
<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'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
@ -11,34 +12,29 @@
|
||||
|
||||
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() {
|
||||
pendingFrom = from == null ? { date: '0000-00-00', time: '00:00' } : fromRFC3339(from)
|
||||
pendingTo = to == null ? { date: '0000-00-00', time: '00:00' } : fromRFC3339(to)
|
||||
pendingFrom = from == null ? defaultFrom : fromRFC3339(from)
|
||||
pendingTo = to == null ? defaultTo : fromRFC3339(to)
|
||||
}
|
||||
|
||||
reset()
|
||||
|
||||
function toRFC3339({ date, time }, secs = 0) {
|
||||
const dparts = date.split('-')
|
||||
const tparts = time.split(':')
|
||||
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 toRFC3339({ date, time }, secs = '00') {
|
||||
const parsedDate = parse(date+' '+time+':'+secs, 'yyyy-MM-dd HH:mm:ss', new Date())
|
||||
return parsedDate.toISOString()
|
||||
}
|
||||
|
||||
function fromRFC3339(rfc3339) {
|
||||
const d = new Date(rfc3339)
|
||||
const pad = (n) => n.toString().padStart(2, '0')
|
||||
const date = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
|
||||
const time = `${pad(d.getHours())}:${pad(d.getMinutes())}`
|
||||
return { date, time }
|
||||
const parsedDate = new Date(rfc3339)
|
||||
return { date: format(parsedDate, 'yyyy-MM-dd'), time: format(parsedDate, 'HH:mm') }
|
||||
}
|
||||
|
||||
$: 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')
|
||||
&& !(to == null && pendingTo.date == '0000-00-00' && pendingTo.time == '00:00')
|
||||
</script>
|
||||
@ -73,7 +69,7 @@
|
||||
on:click={() => {
|
||||
isOpen = false
|
||||
from = toRFC3339(pendingFrom)
|
||||
to = toRFC3339(pendingTo, 59)
|
||||
to = toRFC3339(pendingTo, '59')
|
||||
dispatch('update', { from, to })
|
||||
}}>
|
||||
Close & Apply
|
||||
|
Loading…
Reference in New Issue
Block a user