Pick first dashboard if there's any, dashboards are now deletable
This commit is contained in:
parent
4173629693
commit
c7d430805a
|
|
@ -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'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ export const DashboardHeader = () => {
|
|||
<CancelIcon />
|
||||
</div>
|
||||
|
||||
<DashboardSwitch />
|
||||
|
||||
<DashboardFilters />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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{}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue