Pick first dashboard if there's any, dashboards are now deletable

This commit is contained in:
Jan Zípek 2022-09-03 21:59:37 +02:00
parent 4173629693
commit c7d430805a
Signed by: kamen
GPG Key ID: A17882625B33AC31
8 changed files with 94 additions and 8 deletions

View File

@ -41,3 +41,12 @@ export const updateDashboard = ({
contents: JSON.stringify(body.contents),
}),
})
export const deleteDashboard = (id: number) =>
request<DashboardInfo>(
`/api/dashboards/${id}`,
{
method: 'DELETE',
},
'void'
)

View File

@ -66,6 +66,8 @@ export const DashboardHeader = () => {
<CancelIcon />
</div>
<DashboardSwitch />
<DashboardFilters />
</div>
</div>

View File

@ -1,9 +1,12 @@
import {
createDashboard,
DashboardInfo,
deleteDashboard,
updateDashboard,
} from '@/api/dashboards'
import { Modal } from '@/components/Modal'
import { useConfirmModal } from '@/contexts/ConfirmModalsContext'
import { useDashboardContext } from '@/pages/dashboard/contexts/DashboardContext'
import { createDashboardContent } from '@/utils/createDashboardContent'
import { useForm } from '@/utils/hooks/useForm'
import { useMutation, useQueryClient } from 'react-query'
@ -13,17 +16,40 @@ type Props = {
onClose: () => void
}
export const DashboardModal = ({ dashboard, onClose }: Props) => {
export const DashboardSettings = ({ dashboard, onClose }: Props) => {
const { setDashboardId, dashboardId } = useDashboardContext()
const queryClient = useQueryClient()
const createMutation = useMutation(createDashboard)
const updateMutation = useMutation(updateDashboard)
const deleteMutation = useMutation(deleteDashboard, {
onSuccess: () => {
queryClient.invalidateQueries(['/dashboards'])
onClose()
if (dashboardId === dashboard?.id) {
setDashboardId(-1)
}
},
})
const isLoading =
deleteMutation.isLoading ||
updateMutation.isLoading ||
createMutation.isLoading
const deleteConfirm = useConfirmModal({
content: `Are you sure you want to delete ${dashboard?.name} dashboard?`,
onConfirm: () => !isLoading && deleteMutation.mutate(dashboard?.id ?? 1),
})
const { handleSubmit, register } = useForm({
defaultValue: () => ({
name: dashboard?.name ?? '',
}),
onSubmit: async (v) => {
if (updateMutation.isLoading || createMutation.isLoading) {
if (isLoading) {
return
}
@ -54,6 +80,10 @@ export const DashboardModal = ({ dashboard, onClose }: Props) => {
</div>
<div className="actions">
<button className="remove" type="button" onClick={deleteConfirm.show}>
Remove
</button>
<button className="cancel" onClick={onClose} type="button">
Cancel
</button>

View File

@ -3,7 +3,7 @@ import { EditIcon, PlusIcon } from '@/icons'
import { useDashboardContext } from '@/pages/dashboard/contexts/DashboardContext'
import { useState } from 'preact/hooks'
import { useQuery } from 'react-query'
import { DashboardModal } from './DashboardModal'
import { DashboardSettings } from './DashboardSettings'
export const DashboardSwitch = () => {
const { dashboardId, setDashboardId, dashboard } = useDashboardContext()
@ -26,16 +26,16 @@ export const DashboardSwitch = () => {
</select>
<button onClick={() => setEdited(dashboard)}>
<EditIcon /> Edit
<EditIcon />
</button>
<button onClick={() => setShowNew(true)}>
<PlusIcon /> Add
<PlusIcon />
</button>
{showNew && <DashboardModal onClose={() => setShowNew(false)} />}
{showNew && <DashboardSettings onClose={() => setShowNew(false)} />}
{edited && (
<DashboardModal
<DashboardSettings
dashboard={edited}
onClose={() => setEdited(undefined)}
/>

View File

@ -1,4 +1,9 @@
import { DashboardInfo, getDashboard, updateDashboard } from '@/api/dashboards'
import {
DashboardInfo,
getDashboard,
getDashboards,
updateDashboard,
} from '@/api/dashboards'
import { parseDashboard } from '@/utils/dashboard/parseDashboard'
import { useViewportSize } from '@/utils/hooks/useViewportSize'
import { intervalToRange } from '@/utils/intervalToRange'
@ -40,6 +45,8 @@ export const DashboardContextProvider = ({
const [dashboardId, setDashboardId] = useState(-1)
const isDashboardSelected = !isNaN(dashboardId) && dashboardId >= 0
const dashboards = useQuery(['/dashboards'], getDashboards)
const dashboard = useQuery(
['/dashboards', dashboardId],
() => getDashboard(dashboardId),
@ -77,6 +84,12 @@ export const DashboardContextProvider = ({
setBoxes(dashboardContent?.boxes ?? [])
}, [dashboardContent])
useEffect(() => {
if (dashboards.data && !dashboards.isFetching && !isDashboardSelected) {
setDashboardId(dashboards.data[0]?.id)
}
}, [dashboards.data, isDashboardSelected])
const [filter, setFilter] = useState<FilterValue>(() => {
const range = intervalToRange('week', new Date(), new Date())

View File

@ -51,6 +51,7 @@ func main() {
loginProtected.POST("/api/dashboards", routes.PostDashboard(server))
loginProtected.GET("/api/dashboards/:id", routes.GetDashboardById(server))
loginProtected.PUT("/api/dashboards/:id", routes.PutDashboard(server))
loginProtected.DELETE("/api/dashboards/:id", routes.DeleteDashboard(server))
loginProtected.POST("/api/logout", routes.Logout(server))
// Routes accessible using auth key

View File

@ -2,6 +2,7 @@ package routes
import (
"basic-sensor-receiver/app"
"database/sql"
"net/http"
"strconv"
@ -42,6 +43,11 @@ func GetDashboardById(s *app.Server) gin.HandlerFunc {
item, err := s.Services.Dashboards.GetById(id)
if err == sql.ErrNoRows {
c.Status(404)
return
}
if err != nil {
c.AbortWithError(500, err)
return
@ -97,6 +103,25 @@ func PutDashboard(s *app.Server) gin.HandlerFunc {
}
}
func DeleteDashboard(s *app.Server) gin.HandlerFunc {
return func(c *gin.Context) {
id, err := getIntParam(c, "id")
if err != nil {
c.AbortWithError(400, err)
return
}
err = s.Services.Dashboards.Delete(id)
if err != nil {
c.AbortWithError(500, err)
return
}
c.Status(http.StatusOK)
}
}
func getIntParam(c *gin.Context, key string) (int64, error) {
value := c.Param(key)

View File

@ -72,6 +72,12 @@ func (s *DashboardsService) Update(id int64, name string, contents string) (*Das
return &item, nil
}
func (s *DashboardsService) Delete(id int64) error {
_, err := s.ctx.DB.Exec("DELETE FROM dashboards WHERe id = ?", id)
return err
}
func (s *DashboardsService) GetById(id int64) (*DashboardItem, error) {
item := DashboardItem{}