diff --git a/striker-ui/components/ManageFencesPanel.tsx b/striker-ui/components/ManageFencesPanel.tsx new file mode 100644 index 00000000..dccbec20 --- /dev/null +++ b/striker-ui/components/ManageFencesPanel.tsx @@ -0,0 +1,141 @@ +import { FC, useMemo, useRef, useState } from 'react'; + +import API_BASE_URL from '../lib/consts/API_BASE_URL'; + +import AddFenceInputGroup from './AddFenceInputGroup'; +import api from '../lib/api'; +import ConfirmDialog from './ConfirmDialog'; +import EditFenceInputGroup from './EditFenceInputGroup'; +import FlexBox from './FlexBox'; +import handleAPIError from '../lib/handleAPIError'; +import List from './List'; +import { Panel, PanelHeader } from './Panels'; +import periodicFetch from '../lib/fetchers/periodicFetch'; +import Spinner from './Spinner'; +import { BodyText, HeaderText } from './Text'; +import useIsFirstRender from '../hooks/useIsFirstRender'; +import useProtectedState from '../hooks/useProtectedState'; + +const ManageFencesPanel: FC = () => { + const isFirstRender = useIsFirstRender(); + + const confirmDialogRef = useRef({}); + + const [confirmDialogProps, setConfirmDialogProps] = + useState({ + actionProceedText: '', + content: '', + titleText: '', + }); + const [fenceTemplate, setFenceTemplate] = useProtectedState< + APIFenceTemplate | undefined + >(undefined); + const [isEditFences, setIsEditFences] = useState(false); + const [isLoadingFenceTemplate, setIsLoadingFenceTemplate] = + useProtectedState(true); + + const { data: fenceOverviews, isLoading: isFenceOverviewsLoading } = + periodicFetch(`${API_BASE_URL}/fence`, { + refreshInterval: 60000, + }); + + const listElement = useMemo( + () => ( + { + setConfirmDialogProps({ + actionProceedText: 'Add', + content: , + titleText: 'Add a fence device', + }); + + confirmDialogRef.current.setOpen?.call(null, true); + }} + onEdit={() => { + setIsEditFences((previous) => !previous); + }} + onItemClick={({ fenceAgent: fenceId, fenceName, fenceParameters }) => { + setConfirmDialogProps({ + actionProceedText: 'Update', + content: ( + + ), + titleText: `Update fence ${fenceName} parameters`, + }); + + confirmDialogRef.current.setOpen?.call(null, true); + }} + renderListItem={( + fenceUUID, + { fenceAgent, fenceName, fenceParameters }, + ) => ( + + {fenceName} + + {Object.entries(fenceParameters).reduce( + (previous, [parameterId, parameterValue]) => + `${previous} ${parameterId}="${parameterValue}"`, + fenceAgent, + )} + + + )} + /> + ), + [fenceOverviews, fenceTemplate, isEditFences], + ); + const panelContent = useMemo( + () => + isLoadingFenceTemplate || isFenceOverviewsLoading ? ( + + ) : ( + listElement + ), + [isFenceOverviewsLoading, isLoadingFenceTemplate, listElement], + ); + + if (isFirstRender) { + api + .get(`/fence/template`) + .then(({ data }) => { + setFenceTemplate(data); + }) + .catch((error) => { + handleAPIError(error); + }) + .finally(() => { + setIsLoadingFenceTemplate(false); + }); + } + + return ( + <> + + + Manage fence devices + + {panelContent} + + + + ); +}; + +export default ManageFencesPanel;