using callback for tags

This commit is contained in:
Carter 2026-05-25 12:25:22 -06:00
parent 07b0e6c41e
commit a13c9d5946

View file

@ -8,7 +8,6 @@ import {
ListItem, ListItem,
ListItemIcon, ListItemIcon,
ListItemText, ListItemText,
Theme,
Typography Typography
} from "@mui/material"; } from "@mui/material";
import { makeStyles } from "@mui/styles"; import { makeStyles } from "@mui/styles";
@ -19,10 +18,10 @@ import TagSettings from "common/TagSettings";
import { Device, Tag } from "models"; import { Device, Tag } from "models";
import { filterByTag } from "pbHelpers/Tag"; import { filterByTag } from "pbHelpers/Tag";
import { useDeviceAPI, useSnackbar, useTagAPI } from "providers"; import { useDeviceAPI, useSnackbar, useTagAPI } from "providers";
import React, { useEffect, useRef, useState } from "react"; import React, { useCallback, useEffect, useRef, useState } from "react";
import { pond } from "protobuf-ts/pond"; import { pond } from "protobuf-ts/pond";
const useStyles = makeStyles((_theme: Theme) => { const useStyles = makeStyles(() => {
return ({ return ({
addIcon: { addIcon: {
color: "var(--status-ok)" color: "var(--status-ok)"
@ -45,19 +44,19 @@ function AddDeviceTag(props: AddDeviceTagProps) {
const [searchValue, setSearchValue] = useState(""); const [searchValue, setSearchValue] = useState("");
const [tags, setTags] = useState<Tag[]>([]) const [tags, setTags] = useState<Tag[]>([])
const loadTags = () => { const loadTags = useCallback(() => {
tagAPI.listTags().then(resp => { tagAPI.listTags().then(resp => {
let newTags: Tag[] = []; const newTags: Tag[] = [];
resp.data.tags.forEach((tag: pond.Tag) => { resp.data.tags.forEach((tag: pond.Tag) => {
newTags.push(Tag.create(tag)) newTags.push(Tag.create(tag))
}) })
setTags(newTags) setTags(newTags)
}) })
} }, [tagAPI])
useEffect(() => { useEffect(() => {
loadTags() loadTags()
}, []) }, [loadTags])
const tagItems = tags const tagItems = tags
.filter(tag => !deviceTags.some(tagSettings => tagSettings.key === tag.settings.key)) .filter(tag => !deviceTags.some(tagSettings => tagSettings.key === tag.settings.key))
@ -144,10 +143,10 @@ export default function DeviceTags(props: DeviceTagsProps) {
const [deviceTags, setDeviceTags] = useState<pond.TagSettings[]>(device.status.tags); const [deviceTags, setDeviceTags] = useState<pond.TagSettings[]>(device.status.tags);
const previousDeviceRef = useRef(device); const previousDeviceRef = useRef(device);
const loadTags = () => { const loadTags = useCallback(() => {
// setLoading(true) // setLoading(true)
tagAPI.listTags().then(resp => { tagAPI.listTags().then(resp => {
let newTags: Tag[] = []; const newTags: Tag[] = [];
resp.data.tags.forEach((tag: pond.Tag) => { resp.data.tags.forEach((tag: pond.Tag) => {
newTags.push(Tag.create(tag)) newTags.push(Tag.create(tag))
}) })
@ -155,7 +154,7 @@ export default function DeviceTags(props: DeviceTagsProps) {
}).finally(() => { }).finally(() => {
// setLoading(false) // setLoading(false)
}) })
} }, [tagAPI])
useEffect(() => { useEffect(() => {
if (previousDeviceRef.current !== device) { if (previousDeviceRef.current !== device) {
@ -166,14 +165,16 @@ export default function DeviceTags(props: DeviceTagsProps) {
useEffect(() => { useEffect(() => {
loadTags() loadTags()
}, []) }, [loadTags])
const addTag = (tag: Tag) => { const addTag = (tag: Tag) => {
if (!deviceTags.some(dt => dt.key === tag.settings.key)) { if (!deviceTags.some(dt => dt.key === tag.settings.key)) {
deviceAPI deviceAPI
.tag(device.id(), tag.settings.key) .tag(device.id(), tag.settings.key)
.then(() => { .then(() => {
setDeviceTags([...deviceTags, tag.settings]); setDeviceTags(current =>
current.some(dt => dt.key === tag.settings.key) ? current : [...current, tag.settings]
);
}) })
.catch(() => error("Failed to tag device as " + tag.name)); .catch(() => error("Failed to tag device as " + tag.name));
} }
@ -184,7 +185,7 @@ export default function DeviceTags(props: DeviceTagsProps) {
deviceAPI deviceAPI
.untag(device.id(), tag.key()) .untag(device.id(), tag.key())
.then(() => { .then(() => {
setDeviceTags(deviceTags.filter(t => tag.key() !== t.key)); setDeviceTags(current => current.filter(t => tag.key() !== t.key));
}) })
.catch(() => error("Failed to remove tag " + tag.name + " from device")); .catch(() => error("Failed to remove tag " + tag.name + " from device"));
} }
@ -197,7 +198,7 @@ export default function DeviceTags(props: DeviceTagsProps) {
return ( return (
<React.Fragment> <React.Fragment>
{deviceTags?.map(tagSettings => { {deviceTags?.map(tagSettings => {
let pondTag = pond.Tag.create({ settings: tagSettings }) const pondTag = pond.Tag.create({ settings: tagSettings })
return ( return (
<Grid key={"device-tags-"+tagSettings.key}> <Grid key={"device-tags-"+tagSettings.key}>
<DeviceTag tag={Tag.create(pondTag)} removeTagFromDevice={removeTagFromDevice} /> <DeviceTag tag={Tag.create(pondTag)} removeTagFromDevice={removeTagFromDevice} />