Fixes and proper box settings
This commit is contained in:
parent
8bff4d083e
commit
ec690ebbcb
|
|
@ -1,4 +1,5 @@
|
||||||
import { getSensorValues } from '@/api/sensorValues'
|
import { getSensorValues } from '@/api/sensorValues'
|
||||||
|
import { DashboardGraphData } from '@/utils/parseDashboard'
|
||||||
import { useEffect, useRef } from 'preact/hooks'
|
import { useEffect, useRef } from 'preact/hooks'
|
||||||
import { useQuery } from 'react-query'
|
import { useQuery } from 'react-query'
|
||||||
import { useDashboardContext } from '../contexts/DashboardContext'
|
import { useDashboardContext } from '../contexts/DashboardContext'
|
||||||
|
|
@ -6,9 +7,10 @@ import { BoxDefinition } from '../types'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
box: BoxDefinition
|
box: BoxDefinition
|
||||||
|
data: DashboardGraphData
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BoxGraphContent = ({ box }: Props) => {
|
export const BoxGraphContent = ({ box, data }: Props) => {
|
||||||
const { filter } = useDashboardContext()
|
const { filter } = useDashboardContext()
|
||||||
|
|
||||||
const bodyRef = useRef<HTMLDivElement>(null)
|
const bodyRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
@ -27,8 +29,8 @@ export const BoxGraphContent = ({ box }: Props) => {
|
||||||
// TODO: These should be probably returned by server, could be outdated
|
// TODO: These should be probably returned by server, could be outdated
|
||||||
const from = filter.customFrom
|
const from = filter.customFrom
|
||||||
const to = filter.customTo
|
const to = filter.customTo
|
||||||
const minValue = parseFloat(box.min ?? '')
|
const minValue = parseFloat(data.min ?? '')
|
||||||
const maxValue = parseFloat(box.max ?? '')
|
const maxValue = parseFloat(data.max ?? '')
|
||||||
const customRange = !isNaN(minValue) && !isNaN(maxValue)
|
const customRange = !isNaN(minValue) && !isNaN(maxValue)
|
||||||
|
|
||||||
if (bodyRef.current && values.data) {
|
if (bodyRef.current && values.data) {
|
||||||
|
|
@ -36,19 +38,19 @@ export const BoxGraphContent = ({ box }: Props) => {
|
||||||
bodyRef.current,
|
bodyRef.current,
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
...(box.graphType === 'line' && {
|
...(data.graphType === 'line' && {
|
||||||
type: 'scatter',
|
type: 'scatter',
|
||||||
mode: 'lines',
|
mode: 'lines',
|
||||||
}),
|
}),
|
||||||
...(box.graphType === 'points' && {
|
...(data.graphType === 'points' && {
|
||||||
type: 'scatter',
|
type: 'scatter',
|
||||||
mode: 'markers',
|
mode: 'markers',
|
||||||
}),
|
}),
|
||||||
...(box.graphType === 'lineAndPoints' && {
|
...(data.graphType === 'lineAndPoints' && {
|
||||||
type: 'scatter',
|
type: 'scatter',
|
||||||
mode: 'lines+markers',
|
mode: 'lines+markers',
|
||||||
}),
|
}),
|
||||||
...(box.graphType === 'bar' && { type: 'bar' }),
|
...(data.graphType === 'bar' && { type: 'bar' }),
|
||||||
x: values.data.map((v) => new Date(v.timestamp * 1000)),
|
x: values.data.map((v) => new Date(v.timestamp * 1000)),
|
||||||
y: values.data.map((v) => v.value),
|
y: values.data.map((v) => v.value),
|
||||||
line: {
|
line: {
|
||||||
|
|
@ -60,7 +62,7 @@ export const BoxGraphContent = ({ box }: Props) => {
|
||||||
xaxis: { range: [from, to], type: 'date' },
|
xaxis: { range: [from, to], type: 'date' },
|
||||||
yaxis: {
|
yaxis: {
|
||||||
...(customRange && { range: [minValue, maxValue] }),
|
...(customRange && { range: [minValue, maxValue] }),
|
||||||
...(box.unit && { ticksuffix: ` ${box.unit}` }),
|
...(data.unit && { ticksuffix: ` ${data.unit}` }),
|
||||||
},
|
},
|
||||||
margin: {
|
margin: {
|
||||||
l: 70,
|
l: 70,
|
||||||
|
|
@ -76,7 +78,7 @@ export const BoxGraphContent = ({ box }: Props) => {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, [values.data, box])
|
}, [values.data, box, data])
|
||||||
|
|
||||||
return <div ref={bodyRef} />
|
return <div ref={bodyRef} />
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { getSensors } from '@/api/sensors'
|
import { getSensors } from '@/api/sensors'
|
||||||
import { useState } from 'preact/hooks'
|
import { useState } from 'preact/hooks'
|
||||||
import { useQuery } from 'react-query'
|
import { useQuery } from 'react-query'
|
||||||
import { BoxDefinition } from '../types'
|
import { BoxDefinition } from '../../types'
|
||||||
|
import { GraphSettings } from './components/GraphSettings'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
value: BoxDefinition
|
value: BoxDefinition
|
||||||
|
|
@ -15,12 +16,11 @@ export const BoxSettings = ({ value, onSave, onClose }: Props) => {
|
||||||
const [formState, setFormState] = useState(() => ({
|
const [formState, setFormState] = useState(() => ({
|
||||||
sensor: value.sensor,
|
sensor: value.sensor,
|
||||||
title: value.title,
|
title: value.title,
|
||||||
min: value.min,
|
type: value.data?.type ?? 'graph',
|
||||||
max: value.max,
|
|
||||||
graphType: value.graphType,
|
|
||||||
unit: value.unit,
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
const [data, setData] = useState(() => value.data)
|
||||||
|
|
||||||
const handleSave = async (e: Event) => {
|
const handleSave = async (e: Event) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
@ -29,7 +29,9 @@ export const BoxSettings = ({ value, onSave, onClose }: Props) => {
|
||||||
|
|
||||||
onSave({
|
onSave({
|
||||||
...value,
|
...value,
|
||||||
...formState,
|
sensor: formState.sensor,
|
||||||
|
title: formState.title,
|
||||||
|
data: data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,33 +83,17 @@ export const BoxSettings = ({ value, onSave, onClose }: Props) => {
|
||||||
<div className="input">
|
<div className="input">
|
||||||
<label>Type</label>
|
<label>Type</label>
|
||||||
<select
|
<select
|
||||||
name="graphType"
|
name="type"
|
||||||
value={formState.graphType || 'line'}
|
value={formState.type}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
>
|
>
|
||||||
<option value="line">Line</option>
|
<option value="graph">Graph</option>
|
||||||
<option value="points">Points</option>
|
|
||||||
<option value="lineAndPoints">Line + Points</option>
|
|
||||||
<option value="bar">Bar</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="input">
|
{formState.type === 'graph' && (
|
||||||
<label>Unit</label>
|
<GraphSettings value={data} onChange={setData} />
|
||||||
<input
|
)}
|
||||||
name="unit"
|
|
||||||
value={formState.unit}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="input">
|
|
||||||
<label>Min value</label>
|
|
||||||
<input name="min" value={formState.min} onChange={handleChange} />
|
|
||||||
</div>
|
|
||||||
<div className="input">
|
|
||||||
<label>Max value</label>
|
|
||||||
<input name="max" value={formState.max} onChange={handleChange} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<button className="cancel" onClick={onClose} type="button">
|
<button className="cancel" onClick={onClose} type="button">
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { DashboardGraphData } from '@/utils/parseDashboard'
|
||||||
|
import { useEffect, useState } from 'preact/hooks'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
value?: DashboardGraphData
|
||||||
|
onChange: (data: DashboardGraphData) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GraphSettings = ({ value, onChange }: Props) => {
|
||||||
|
const [formState, setFormState] = useState(() => ({
|
||||||
|
min: value?.min,
|
||||||
|
max: value?.max,
|
||||||
|
graphType: value?.graphType,
|
||||||
|
unit: value?.unit,
|
||||||
|
}))
|
||||||
|
|
||||||
|
const handleChange = (e: Event) => {
|
||||||
|
const target = e.target as HTMLSelectElement | HTMLInputElement
|
||||||
|
|
||||||
|
setFormState({
|
||||||
|
...formState,
|
||||||
|
[target.name]: target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onChange({ ...formState, type: 'graph' })
|
||||||
|
}, [formState])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="input">
|
||||||
|
<label>Graph Type</label>
|
||||||
|
<select
|
||||||
|
name="graphType"
|
||||||
|
value={formState.graphType || 'line'}
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
<option value="line">Line</option>
|
||||||
|
<option value="points">Points</option>
|
||||||
|
<option value="lineAndPoints">Line + Points</option>
|
||||||
|
<option value="bar">Bar</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="input">
|
||||||
|
<label>Unit</label>
|
||||||
|
<input name="unit" value={formState.unit} onChange={handleChange} />
|
||||||
|
</div>
|
||||||
|
<div className="input">
|
||||||
|
<label>Min value</label>
|
||||||
|
<input name="min" value={formState.min} onChange={handleChange} />
|
||||||
|
</div>
|
||||||
|
<div className="input">
|
||||||
|
<label>Max value</label>
|
||||||
|
<input name="max" value={formState.max} onChange={handleChange} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
import { getElementPosition } from '@/utils/getElementPosition'
|
|
||||||
import { useWindowEvent } from '@/utils/hooks/useWindowEvent'
|
import { useWindowEvent } from '@/utils/hooks/useWindowEvent'
|
||||||
import { useRef, useState } from 'preact/hooks'
|
import { useRef, useState } from 'preact/hooks'
|
||||||
import { GRID_WIDTH } from '../constants'
|
import { GRID_WIDTH } from '../constants'
|
||||||
import { ResizingMode, useResize } from '../hooks/useResize'
|
|
||||||
import { useDragging } from '../hooks/useDragging'
|
import { useDragging } from '../hooks/useDragging'
|
||||||
|
import { ResizingMode, useResize } from '../hooks/useResize'
|
||||||
import { BoxDefinition } from '../types'
|
import { BoxDefinition } from '../types'
|
||||||
import { BoxSettings } from './BoxSettings'
|
|
||||||
import { BoxGraphContent } from './BoxGraphContent'
|
import { BoxGraphContent } from './BoxGraphContent'
|
||||||
|
import { BoxSettings } from './BoxSettings/BoxSettings'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
box: BoxDefinition
|
box: BoxDefinition
|
||||||
|
|
@ -46,7 +45,10 @@ export const EditableBox = ({
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
if (!dragging.active && boxRef.current) {
|
if (!dragging.active && boxRef.current) {
|
||||||
const pos = getElementPosition(boxRef.current)
|
const pos = {
|
||||||
|
top: boxRef.current.offsetTop,
|
||||||
|
left: boxRef.current.offsetLeft,
|
||||||
|
}
|
||||||
|
|
||||||
setDragging({
|
setDragging({
|
||||||
active: true,
|
active: true,
|
||||||
|
|
@ -115,7 +117,9 @@ export const EditableBox = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="body">
|
<div className="body">
|
||||||
{box.sensor && <BoxGraphContent box={box} />}
|
{box.sensor && box.data?.type === 'graph' && (
|
||||||
|
<BoxGraphContent box={box} data={box.data} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ export type DashboardContentBox = {
|
||||||
h: number
|
h: number
|
||||||
sensor?: string
|
sensor?: string
|
||||||
title?: string
|
title?: string
|
||||||
|
data?: DashboardGraphData
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DashboardGraphData = {
|
||||||
|
type: 'graph'
|
||||||
min?: string
|
min?: string
|
||||||
max?: string
|
max?: string
|
||||||
unit?: string
|
unit?: string
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue