import {Link, useNavigate} from "react-router-dom"; import { Paper, styled, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Button, IconButton, Checkbox, Box } from "@mui/material"; import {useCallback, useContext, useEffect, useState} from "react"; import {LocaleContext} from "shared/locale"; import {Add, Cached, Delete, Edit, Refresh} from "@mui/icons-material"; import Dialog from "shared/elements/dialog"; import ViewContent from "../../elements/view-content"; import ButtonBar from "../../elements/button-bar"; import TableBodyStriped from "shared/elements/table-body-striped"; const RouteTableRow = styled(TableRow)((props) => ({ "& td": { fontFamily: "monospace" } })); export default function RouteListView(props) { // meta const api = props.api; const {translate: L, requestModules, currentLocale} = useContext(LocaleContext); const navigate = useNavigate(); // data const [fetchRoutes, setFetchRoutes] = useState(true); const [routes, setRoutes] = useState({}); // ui const [dialogData, setDialogData] = useState({show: false}); const [isGeneratingCache, setGeneratingCache] = useState(false); const onFetchRoutes = useCallback((force = false) => { if (force || fetchRoutes) { setFetchRoutes(false); props.api.fetchRoutes().then(res => { if (!res.success) { props.showDialog(res.msg, L("routes.fetch_routes_error")); navigate("/admin/dashboard"); } else { setRoutes(res.routes); } }); } }, [fetchRoutes]); useEffect(() => { onFetchRoutes(); }, []); useEffect(() => { requestModules(props.api, ["general", "routes"], currentLocale).then(data => { if (!data.success) { props.showDialog("Error fetching translations: " + data.msg); } }); }, [currentLocale]); const onToggleRoute = useCallback((id, active) => { if (active) { props.api.enableRoute(id).then(data => { if (!data.success) { props.showDialog(data.msg, L("routes.enable_route_error")); } else { setRoutes({...routes, [id]: { ...routes[id], active: true }}); } }); } else { props.api.disableRoute(id).then(data => { if (!data.success) { props.showDialog(data.msg, L("routes.disable_route_error")); } else { setRoutes({...routes, [id]: { ...routes[id], active: false }}); } }); } }, [routes]); const onDeleteRoute = useCallback(id => { props.api.deleteRoute(id).then(data => { if (!data.success) { props.showDialog(data.msg, L("routes.remove_route_error")); } else { let newRoutes = { ...routes }; delete newRoutes[id]; setRoutes(newRoutes); } }) }, [routes]); const onRegenerateCache = useCallback(() => { if (!isGeneratingCache) { setGeneratingCache(true); props.api.regenerateRouterCache().then(data => { if (!data.success) { props.showDialog(data.msg, L("routes.regenerate_router_cache_error")); setGeneratingCache(false); } else { setDialogData({ open: true, title: L("general.success"), message: L("routes.regenerate_router_cache_success"), onClose: () => setGeneratingCache(false) }) } }); } }, [isGeneratingCache]); const BoolCell = (props) => props.checked ? L("general.yes") : L("general.no") return <> Home, {L("routes.title")} ]}> {L("general.id")} {L("routes.route")} {L("routes.type")} {L("routes.target")} {L("routes.extra")} {L("routes.active")} {L("routes.exact")} {L("general.controls")} {Object.entries(routes).map(([id, route]) => {route.id} {route.pattern} {route.type} {route.target} {route.extra} onToggleRoute(route.id, e.target.checked)} /> navigate("/admin/routes/" + id)}> setDialogData({ open: true, title: L("routes.delete_route_title"), message: L("routes.delete_route_text"), inputs: [ { type: "text", name: "pattern", value: route.pattern, disabled: true} ], options: [L("general.cancel"), L("general.ok")], onOption: btn => btn === 1 ? onDeleteRoute(route.id) : true })}> )}
{ setDialogData({open: false}); dialogData.onClose && dialogData.onClose() }} title={dialogData.title} message={dialogData.message} onOption={dialogData.onOption} inputs={dialogData.inputs} options={[L("general.cancel"), L("general.ok")]} /> }