feat: impl mock api for devices & fishbone
This commit is contained in:
parent
167ec6b943
commit
f8aa6ad785
|
|
@ -3,9 +3,10 @@ import Box from "@mui/material/Box";
|
||||||
import Alert from "@mui/material/Alert";
|
import Alert from "@mui/material/Alert";
|
||||||
import { DeviceState } from "../types/device.types";
|
import { DeviceState } from "../types/device.types";
|
||||||
import { AuthState } from "../types/auth.types";
|
import { AuthState } from "../types/auth.types";
|
||||||
|
import { FishboneState } from "../types/fishbone.types";
|
||||||
|
|
||||||
interface FlashMessageProps {
|
interface FlashMessageProps {
|
||||||
store: () => DeviceState | AuthState;
|
store: () => DeviceState | AuthState | FishboneState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function FlashMessage(props: FlashMessageProps) {
|
export default function FlashMessage(props: FlashMessageProps) {
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,9 @@ export default function DashboardLayout(props: Props) {
|
||||||
<Box sx={{ display: "flex" }}>
|
<Box sx={{ display: "flex" }}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<AppBar
|
<AppBar
|
||||||
|
// color="default"
|
||||||
position="fixed"
|
position="fixed"
|
||||||
|
enableColorOnDark
|
||||||
sx={{
|
sx={{
|
||||||
width: { sm: `calc(100% - ${drawerWidth}px)` },
|
width: { sm: `calc(100% - ${drawerWidth}px)` },
|
||||||
ml: { sm: `${drawerWidth}px` },
|
ml: { sm: `${drawerWidth}px` },
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ import IconButton from "../components/IconButton";
|
||||||
import { Edit } from "iconsax-react";
|
import { Edit } from "iconsax-react";
|
||||||
import useTitle from "../hooks/useTitle";
|
import useTitle from "../hooks/useTitle";
|
||||||
import { useDeviceStore } from "../stores/deviceStore";
|
import { useDeviceStore } from "../stores/deviceStore";
|
||||||
import { Device } from "../types/device.types";
|
import { DeviceDataTable } from "../types/device.types";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useMemo } from "react";
|
||||||
import FlashMessage from "../components/FlashMessage";
|
import FlashMessage from "../components/FlashMessage";
|
||||||
|
|
||||||
export default function Devices() {
|
export default function Devices() {
|
||||||
|
|
@ -25,7 +25,8 @@ export default function Devices() {
|
||||||
const { data, cacheExpired, getAll } = useDeviceStore();
|
const { data, cacheExpired, getAll } = useDeviceStore();
|
||||||
|
|
||||||
// Define columns
|
// Define columns
|
||||||
const columns: ColumnDef<Device>[] = [
|
const columns: ColumnDef<DeviceDataTable>[] = useMemo(
|
||||||
|
() => [
|
||||||
{
|
{
|
||||||
header: "Device Code",
|
header: "Device Code",
|
||||||
accessorKey: "device_code",
|
accessorKey: "device_code",
|
||||||
|
|
@ -42,6 +43,10 @@ export default function Devices() {
|
||||||
header: "Total Port",
|
header: "Total Port",
|
||||||
accessorKey: "port_amount",
|
accessorKey: "port_amount",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
header: "Total Used Port",
|
||||||
|
accessorKey: "total_used_port",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
header: "Status",
|
header: "Status",
|
||||||
accessorKey: "status",
|
accessorKey: "status",
|
||||||
|
|
@ -55,7 +60,7 @@ export default function Devices() {
|
||||||
: "warning.main"
|
: "warning.main"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{row.original.status}
|
{row.original.status.toUpperCase()}
|
||||||
</Typography>
|
</Typography>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
@ -65,19 +70,25 @@ export default function Devices() {
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<>
|
<>
|
||||||
<IconButton variant="text" color="secondary" href={`/devices/${row.original.id}`}>
|
<IconButton
|
||||||
|
variant="text"
|
||||||
|
color="secondary"
|
||||||
|
href={`/devices/${row.original.id}`}
|
||||||
|
>
|
||||||
<Edit variant="Bulk" color="currentColor" />
|
<Edit variant="Bulk" color="currentColor" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cacheExpired()) {
|
if (cacheExpired()) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await getAll()
|
await getAll();
|
||||||
})()
|
})();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { useDeviceStore } from "../../stores/deviceStore";
|
||||||
import { DeviceRequest } from "../../types/device.types";
|
import { DeviceRequest } from "../../types/device.types";
|
||||||
import FlashMessage from "../../components/FlashMessage";
|
import FlashMessage from "../../components/FlashMessage";
|
||||||
|
|
||||||
export default function DeviceCreate() {
|
export default function DeviceCreateOrEdit() {
|
||||||
useTitle("Devices");
|
useTitle("Devices");
|
||||||
const { pid } = useParams();
|
const { pid } = useParams();
|
||||||
const { update, create, isLoading, find, clearDevice, device } = useDeviceStore();
|
const { update, create, isLoading, find, clearDevice, device } = useDeviceStore();
|
||||||
|
|
@ -1,23 +1,31 @@
|
||||||
import Box from '@mui/material/Box';
|
import Box from "@mui/material/Box";
|
||||||
import Chip from '@mui/material/Chip';
|
import Chip from "@mui/material/Chip";
|
||||||
import FormControl from "@mui/material/FormControl";
|
import FormControl from "@mui/material/FormControl";
|
||||||
import Grid from "@mui/material/Grid2";
|
import Grid from "@mui/material/Grid2";
|
||||||
import InputLabel from "@mui/material/InputLabel";
|
import InputLabel from "@mui/material/InputLabel";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import Select from "@mui/material/Select";
|
import Select from "@mui/material/Select";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from "react";
|
||||||
import { DeviceStatus } from '../../types/device.types';
|
import { DeviceStatus } from "../../types/device.types";
|
||||||
import { useDeviceStore } from '../../stores/deviceStore';
|
import { useDeviceStore } from "../../stores/deviceStore";
|
||||||
|
|
||||||
export default function Form() {
|
export default function Form() {
|
||||||
const { device, clearDevice } = useDeviceStore();
|
const { device, clearDevice, towerSelect, getTowerSelect } = useDeviceStore();
|
||||||
const [select, setSelect] = useState<DeviceStatus>('active');
|
const [select, setSelect] = useState<DeviceStatus>("active");
|
||||||
|
const [tower, setTower] = useState<string>("");
|
||||||
|
|
||||||
const STATUS = ["active", "inactive", "maintenance"];
|
const STATUS = ["active", "inactive", "maintenance"];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSelect(device?.status || 'active');
|
(async () => {
|
||||||
|
await getTowerSelect();
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (device) {
|
||||||
|
setSelect(device.status);
|
||||||
|
setTower(device.tower_id as string);
|
||||||
|
}
|
||||||
|
|
||||||
const clear = async () => {
|
const clear = async () => {
|
||||||
await clearDevice();
|
await clearDevice();
|
||||||
|
|
@ -30,12 +38,17 @@ export default function Form() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
{/* Device Code */}
|
<Grid size={{ md: 6, xs: 12 }}>
|
||||||
<Grid size={{ md: 4, xs: 12 }}>
|
<TextField
|
||||||
<TextField fullWidth name='device_code' label="Device Code" variant="outlined" value={device?.device_code} />
|
fullWidth
|
||||||
|
name="device_code"
|
||||||
|
label="Device Code"
|
||||||
|
variant="outlined"
|
||||||
|
value={device?.device_code}
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
{/* Total Port */}
|
|
||||||
<Grid size={{ md: 4, xs: 12 }}>
|
<Grid size={{ md: 6, xs: 12 }}>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
name="port_count"
|
name="port_count"
|
||||||
|
|
@ -46,8 +59,26 @@ export default function Form() {
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* Status */}
|
<Grid size={{ md: 6, xs: 12 }}>
|
||||||
<Grid size={{ md: 4, xs: 12 }}>
|
<FormControl fullWidth>
|
||||||
|
<InputLabel id="tower-label">Tower</InputLabel>
|
||||||
|
<Select
|
||||||
|
name="tower"
|
||||||
|
labelId="tower-label"
|
||||||
|
label="Tower"
|
||||||
|
value={tower}
|
||||||
|
onChange={(e) => setTower(e.target.value)}
|
||||||
|
>
|
||||||
|
{towerSelect?.map((tower, key) => (
|
||||||
|
<MenuItem key={key} value={tower.value}>
|
||||||
|
{tower.label.toUpperCase()}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid size={{ md: 6, xs: 12 }}>
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
<InputLabel id="status-label">Status</InputLabel>
|
<InputLabel id="status-label">Status</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import Breadcrumbs from "@mui/material/Breadcrumbs";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
import CardContent from "@mui/material/CardContent";
|
import CardContent from "@mui/material/CardContent";
|
||||||
|
import Divider from "@mui/material/Divider";
|
||||||
import Link from "@mui/material/Link";
|
import Link from "@mui/material/Link";
|
||||||
import Grid from "@mui/material/Grid2";
|
import Grid from "@mui/material/Grid2";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
|
@ -13,24 +14,18 @@ import { ColumnDef } from "@tanstack/react-table";
|
||||||
import IconButton from "../components/IconButton";
|
import IconButton from "../components/IconButton";
|
||||||
import { Edit } from "iconsax-react";
|
import { Edit } from "iconsax-react";
|
||||||
import useTitle from "../hooks/useTitle";
|
import useTitle from "../hooks/useTitle";
|
||||||
|
import { useFishboneStore } from "../stores/fishboneStore";
|
||||||
interface UserData {
|
import { FishboneDataTable } from "../types/fishbone.types";
|
||||||
backbone: string;
|
import FlashMessage from "../components/FlashMessage";
|
||||||
device_start: string;
|
import { useEffect, useMemo } from "react";
|
||||||
device_end: string;
|
|
||||||
total_core: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Fishbone() {
|
export default function Fishbone() {
|
||||||
useTitle("Fishbone");
|
useTitle("Fishbone");
|
||||||
|
|
||||||
const data: UserData[] = [
|
const { data, cacheExpired, getAll } = useFishboneStore();
|
||||||
{ backbone: 'BB-BDG-SMD', device_start: "DV-CODE-1", device_end: "DV-CODE-2", total_core: '24 Core', },
|
|
||||||
{ backbone: 'BB-BDG-SBG', device_start: "DV-CODE-3", device_end: "DV-CODE-4", total_core: '24 Core', },
|
|
||||||
];
|
|
||||||
|
|
||||||
// Define columns
|
const columns: ColumnDef<FishboneDataTable>[] = useMemo(
|
||||||
const columns: ColumnDef<UserData>[] = [
|
() => [
|
||||||
{
|
{
|
||||||
header: "Backbone",
|
header: "Backbone",
|
||||||
accessorKey: "backbone",
|
accessorKey: "backbone",
|
||||||
|
|
@ -44,22 +39,40 @@ export default function Fishbone() {
|
||||||
accessorKey: "device_end",
|
accessorKey: "device_end",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: "Total Core",
|
header: "Address",
|
||||||
accessorKey: "total_core",
|
accessorKey: "address",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: '',
|
header: "Core used",
|
||||||
|
accessorKey: "core_amount",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "",
|
||||||
accessorKey: "action",
|
accessorKey: "action",
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
cell: () => (
|
cell: ({ row }) => (
|
||||||
<>
|
<>
|
||||||
<IconButton variant="light" color="info" >
|
<IconButton
|
||||||
|
variant="text"
|
||||||
|
color="secondary"
|
||||||
|
href={`/fishbone/${row.original.id}`}
|
||||||
|
>
|
||||||
<Edit variant="Bulk" color="currentColor" />
|
<Edit variant="Bulk" color="currentColor" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</>
|
</>
|
||||||
)
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (cacheExpired()) {
|
||||||
|
(async () => {
|
||||||
|
await getAll();
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
];
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box component="main">
|
<Box component="main">
|
||||||
|
|
@ -68,7 +81,11 @@ export default function Fishbone() {
|
||||||
<Typography variant="h3">Fishbone</Typography>
|
<Typography variant="h3">Fishbone</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid size="auto">
|
<Grid size="auto">
|
||||||
<Button variant="contained" startIcon={<AddIcon color="inherit" />}>
|
<Button
|
||||||
|
href="/fishbone/create"
|
||||||
|
variant="contained"
|
||||||
|
startIcon={<AddIcon color="inherit" />}
|
||||||
|
>
|
||||||
Add New
|
Add New
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
@ -82,12 +99,15 @@ export default function Fishbone() {
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Card sx={{ display: "flex" }}>
|
<FlashMessage store={useFishboneStore} />
|
||||||
<CardContent sx={{ flex: "1 0 auto" }}>
|
|
||||||
<ReactTable
|
<Card>
|
||||||
data={data}
|
<Box sx={{ p: 2 }}>
|
||||||
columns={columns}
|
<Typography variant="h5">List Devices</Typography>
|
||||||
/>
|
</Box>
|
||||||
|
<Divider />
|
||||||
|
<CardContent sx={{ flex: "1 0 auto", pt: 2, px: 0 }}>
|
||||||
|
<ReactTable data={data || []} columns={columns} />
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
import Box from "@mui/material/Box";
|
||||||
|
import Breadcrumbs from "@mui/material/Breadcrumbs";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import Card from "@mui/material/Card";
|
||||||
|
import Divider from "@mui/material/Divider";
|
||||||
|
import CardContent from "@mui/material/CardContent";
|
||||||
|
import Grid from "@mui/material/Grid2";
|
||||||
|
import Link from "@mui/material/Link";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { Home, Save } from "@mui/icons-material";
|
||||||
|
import useTitle from "../../hooks/useTitle";
|
||||||
|
import IconButton from "../../components/IconButton";
|
||||||
|
import { Back } from "iconsax-react";
|
||||||
|
import { useParams } from "react-router";
|
||||||
|
import Form from "./Form";
|
||||||
|
import { FormEvent, useEffect } from "react";
|
||||||
|
import FlashMessage from "../../components/FlashMessage";
|
||||||
|
import { useFishboneStore } from "../../stores/fishboneStore";
|
||||||
|
import { FishboneRequest } from "../../types/fishbone.types";
|
||||||
|
|
||||||
|
export default function FishboneCreateOrEdit() {
|
||||||
|
useTitle("Fishbone");
|
||||||
|
const { pid } = useParams();
|
||||||
|
const { update, create, isLoading, find, clearFishbone } = useFishboneStore();
|
||||||
|
|
||||||
|
const IS_EDIT_PAGE = pid!!;
|
||||||
|
|
||||||
|
const onSubmit = async (e: FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const formData = new FormData(e.target as HTMLFormElement);
|
||||||
|
|
||||||
|
const data = Object.fromEntries(formData.entries()) as unknown as FishboneRequest;
|
||||||
|
|
||||||
|
if (IS_EDIT_PAGE) {
|
||||||
|
await update(pid!!, data);
|
||||||
|
} else {
|
||||||
|
await create(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (pid!!) {
|
||||||
|
(async () => {
|
||||||
|
await find(pid!!);
|
||||||
|
})()
|
||||||
|
} else {
|
||||||
|
(async () => {
|
||||||
|
await clearFishbone()
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box component="main">
|
||||||
|
<Grid container spacing={2} alignItems={"center"} mb={4}>
|
||||||
|
<Grid size="auto">
|
||||||
|
<Box display={"flex"} alignItems={"center"} gap={1}>
|
||||||
|
<IconButton variant="dashed" color="primary" href="/fishbone">
|
||||||
|
<Back variant="Outline" color="currentColor" />
|
||||||
|
</IconButton>
|
||||||
|
<Typography variant="h3">{IS_EDIT_PAGE ? `Edit Fishbone - ${pid}` : 'Create Fishbone'}</Typography>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
<Grid size={12}>
|
||||||
|
<Breadcrumbs aria-label="breadcrumb">
|
||||||
|
<Link underline="hover" color="inherit" href="/dashboard">
|
||||||
|
<Home />
|
||||||
|
</Link>
|
||||||
|
<Link underline="hover" color="inherit" href="/fishbone">
|
||||||
|
<Typography sx={{ color: "text.primary" }}>Fishbone</Typography>
|
||||||
|
</Link>
|
||||||
|
<Typography sx={{ color: "text.primary" }}>{IS_EDIT_PAGE ? pid : 'Create'}</Typography>
|
||||||
|
</Breadcrumbs>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<FlashMessage store={useFishboneStore} />
|
||||||
|
|
||||||
|
<Card component="form" onSubmit={onSubmit}>
|
||||||
|
<Box
|
||||||
|
sx={{ px: 3, py: 1 }}
|
||||||
|
display={"flex"}
|
||||||
|
justifyContent={"space-between"}
|
||||||
|
alignItems={"center"}
|
||||||
|
>
|
||||||
|
<Typography variant="h5">Fill the form</Typography>
|
||||||
|
<Button
|
||||||
|
disabled={isLoading}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
startIcon={<Save color="inherit" />}
|
||||||
|
>
|
||||||
|
{IS_EDIT_PAGE ? "Save Changes" : "Create"}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
<Divider />
|
||||||
|
<CardContent>
|
||||||
|
<Form />
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
import Box from "@mui/material/Box";
|
||||||
|
import Chip from "@mui/material/Chip";
|
||||||
|
import FormControl from "@mui/material/FormControl";
|
||||||
|
import Grid from "@mui/material/Grid2";
|
||||||
|
import InputLabel from "@mui/material/InputLabel";
|
||||||
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
import Select from "@mui/material/Select";
|
||||||
|
import TextField from "@mui/material/TextField";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useFishboneStore } from "../../stores/fishboneStore";
|
||||||
|
|
||||||
|
export default function Form() {
|
||||||
|
const {
|
||||||
|
fishbone,
|
||||||
|
clearFishbone,
|
||||||
|
backboneSelect,
|
||||||
|
deviceSelect,
|
||||||
|
getDeviceSelect,
|
||||||
|
getBackboneSelect,
|
||||||
|
} = useFishboneStore();
|
||||||
|
const [backbone, setBackbone] = useState<string>("");
|
||||||
|
const [deviceStart, setDeviceStart] = useState<string>("");
|
||||||
|
const [deviceEnd, setDeviceEnd] = useState<string>("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
await getBackboneSelect();
|
||||||
|
await getDeviceSelect();
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (fishbone) {
|
||||||
|
setBackbone(fishbone.backbone_id);
|
||||||
|
setDeviceStart(fishbone.dev_start_id);
|
||||||
|
setDeviceEnd(fishbone.dev_end_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clear = async () => {
|
||||||
|
await clearFishbone();
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clear();
|
||||||
|
};
|
||||||
|
}, [fishbone]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid size={{ md: 4, xs: 12 }}>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<InputLabel id="backbone-label">Backbone</InputLabel>
|
||||||
|
<Select
|
||||||
|
name="backbone"
|
||||||
|
labelId="backbone-label"
|
||||||
|
label="Backbone"
|
||||||
|
value={backbone}
|
||||||
|
onChange={(e) => setBackbone(e.target.value)}
|
||||||
|
>
|
||||||
|
{backboneSelect?.map((backbone, key) => (
|
||||||
|
<MenuItem key={key} value={backbone.value}>
|
||||||
|
{backbone.label.toUpperCase()}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid size={{ md: 4, xs: 12 }}>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<InputLabel id="device-start-label">Device Start</InputLabel>
|
||||||
|
<Select
|
||||||
|
name="device-start"
|
||||||
|
labelId="device-start-label"
|
||||||
|
label="Device Start"
|
||||||
|
value={deviceStart}
|
||||||
|
onChange={(e) => setDeviceStart(e.target.value)}
|
||||||
|
>
|
||||||
|
{deviceSelect?.map((device, key) => (
|
||||||
|
<MenuItem key={key} value={device.value}>
|
||||||
|
{device.label.toUpperCase()}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid size={{ md: 4, xs: 12 }}>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<InputLabel id="device-end-label">Device End</InputLabel>
|
||||||
|
<Select
|
||||||
|
name="device-end"
|
||||||
|
labelId="device-end-label"
|
||||||
|
label="Device End"
|
||||||
|
value={deviceEnd}
|
||||||
|
onChange={(e) => setDeviceEnd(e.target.value)}
|
||||||
|
>
|
||||||
|
{deviceSelect
|
||||||
|
?.filter((b) => b.value != deviceStart)
|
||||||
|
.map((device, key) => (
|
||||||
|
<MenuItem key={key} value={device.value}>
|
||||||
|
{device.label.toUpperCase()}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid size={{ md: 12, xs: 12 }}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
name="core_amount"
|
||||||
|
label="Core used"
|
||||||
|
variant="outlined"
|
||||||
|
type="number"
|
||||||
|
slotProps={{
|
||||||
|
htmlInput: Object.assign(
|
||||||
|
{ min: 1 },
|
||||||
|
fishbone?.backbone_core && { max: fishbone.backbone_core }
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
value={fishbone?.core_amount}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid size={{ md: 6, xs: 12 }}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
name="longitude"
|
||||||
|
label="Longitude"
|
||||||
|
variant="outlined"
|
||||||
|
type="number"
|
||||||
|
value={fishbone?.longitude}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid size={{ md: 6, xs: 12 }}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
name="latitude"
|
||||||
|
label="Latitude"
|
||||||
|
variant="outlined"
|
||||||
|
type="number"
|
||||||
|
value={fishbone?.latitude}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { createAPI } from "../services/api";
|
import { createAPI } from "../services/api";
|
||||||
import { DeviceRepositoryProps, Device } from "../types/device.types";
|
import { DeviceRepositoryProps, Device, IGetTowerSelect } from "../types/device.types";
|
||||||
import { ResponseApi } from "../types/response.types";
|
import { ResponseApi } from "../types/response.types";
|
||||||
|
import { SelectState } from "../types/store.types";
|
||||||
|
|
||||||
const api = createAPI();
|
const api = createAPI();
|
||||||
|
|
||||||
|
|
@ -19,9 +20,9 @@ export const deviceRepository: DeviceRepositoryProps = {
|
||||||
latitude: "1",
|
latitude: "1",
|
||||||
address: "Jl. Jend Sudirman No. XX",
|
address: "Jl. Jend Sudirman No. XX",
|
||||||
port_amount: 10,
|
port_amount: 10,
|
||||||
|
total_used_port: 5,
|
||||||
status: "active",
|
status: "active",
|
||||||
created_at: "2024-01-01",
|
created_at: "2024-01-01",
|
||||||
updated_at: "2024-01-01",
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
|
|
@ -39,6 +40,7 @@ export const deviceRepository: DeviceRepositoryProps = {
|
||||||
address: "Jl. Jend Sudirman No. XX",
|
address: "Jl. Jend Sudirman No. XX",
|
||||||
port_amount: 10,
|
port_amount: 10,
|
||||||
status: "active",
|
status: "active",
|
||||||
|
tower_id: null,
|
||||||
created_at: "2024-01-01",
|
created_at: "2024-01-01",
|
||||||
updated_at: "2024-01-01",
|
updated_at: "2024-01-01",
|
||||||
})
|
})
|
||||||
|
|
@ -53,4 +55,16 @@ export const deviceRepository: DeviceRepositoryProps = {
|
||||||
const response = await api.put<ResponseApi<null>>(`/api/v1/devices/${id}`, data);
|
const response = await api.put<ResponseApi<null>>(`/api/v1/devices/${id}`, data);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getTowerSelect() {
|
||||||
|
// const response = await api.get<ResponseApi<SelectState[]>>("/api/v1/devices/tower-select");
|
||||||
|
|
||||||
|
// return (response.data.data as IGetTowerSelect[])?.map((i: IGetTowerSelect) => ({label: i.tower_code, value: i.id})) as SelectState[];
|
||||||
|
return Promise.resolve([
|
||||||
|
{
|
||||||
|
label: "TWR-EX-001",
|
||||||
|
value: "1",
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
import { createAPI } from "../services/api";
|
||||||
|
import { FishboneRepositoryProps, Fishbone, IGetBackboneSelect } from "../types/fishbone.types";
|
||||||
|
import { ResponseApi } from "../types/response.types";
|
||||||
|
import { SelectState } from "../types/store.types";
|
||||||
|
|
||||||
|
const api = createAPI();
|
||||||
|
|
||||||
|
export const fishboneRepository: FishboneRepositoryProps = {
|
||||||
|
async getAll() {
|
||||||
|
// const response = await api.get<ResponseApi<Fishbone[]>>("/api/v1/fishbones");
|
||||||
|
|
||||||
|
// return response.data.data as Fishbone[];
|
||||||
|
|
||||||
|
return Promise.resolve([
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
backbone: "abced-efghi",
|
||||||
|
device_start: "DEV-S1",
|
||||||
|
device_end: "DEV-E1",
|
||||||
|
address: "Jl. Jend Sudirman No. XX",
|
||||||
|
core_amount: 10,
|
||||||
|
longitude: "1",
|
||||||
|
latitude: "1",
|
||||||
|
}
|
||||||
|
])
|
||||||
|
},
|
||||||
|
|
||||||
|
async getFishboneById(id: string) {
|
||||||
|
// const response = await api.get<ResponseApi<Fishbone>>(`/api/v1/fishbones/${id}`);
|
||||||
|
|
||||||
|
// return response.data.data as Fishbone;
|
||||||
|
return Promise.resolve({
|
||||||
|
id: "1",
|
||||||
|
// fishbone_code: "DV-EX-001",
|
||||||
|
backbone_id: "abced-efghi",
|
||||||
|
backbone_core: "16",
|
||||||
|
dev_start_id: "1",
|
||||||
|
dev_end_id: "2",
|
||||||
|
longitude: "1",
|
||||||
|
latitude: "1",
|
||||||
|
core_amount: 10,
|
||||||
|
address: "Jl. Jend Sudirman No. XX",
|
||||||
|
created_at: "2024-01-01",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
async createFishbone(data: Fishbone) {
|
||||||
|
const response = await api.post<ResponseApi<null>>("/api/v1/fishbones", data);
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
|
||||||
|
async updateFishbone(id: string, data: Fishbone) {
|
||||||
|
const response = await api.put<ResponseApi<null>>(`/api/v1/fishbones/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
|
||||||
|
async getBackboneSelect() {
|
||||||
|
// const response = await api.get<ResponseApi<SelectState[]>>("/api/v1/fishbones/backbone");
|
||||||
|
|
||||||
|
// return (response.data.data as IGetBackboneSelect[])?.map((i: IGetBackboneSelect) => ({label: i.backbone_code, value: i.id})) as SelectState[];
|
||||||
|
return Promise.resolve([
|
||||||
|
{
|
||||||
|
label: "BB-001",
|
||||||
|
value: "abced-efghi",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "BB-002",
|
||||||
|
value: "jklmn-opqrs",
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
async getDeviceSelect() {
|
||||||
|
// const response = await api.get<ResponseApi<SelectState[]>>("/api/v1/fishbones/device");
|
||||||
|
|
||||||
|
// return (response.data.data as IGetBackboneSelect[])?.map((i: IGetBackboneSelect) => ({label: i.backbone_code, value: i.id})) as SelectState[];
|
||||||
|
|
||||||
|
return Promise.resolve([
|
||||||
|
{
|
||||||
|
label: "DEV-S1",
|
||||||
|
value: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "DEV-S2",
|
||||||
|
value: "2",
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -9,7 +9,8 @@ import Devices from "../pages/Devices";
|
||||||
import Fishbone from "../pages/Fishbone";
|
import Fishbone from "../pages/Fishbone";
|
||||||
import Towers from "../pages/Towers";
|
import Towers from "../pages/Towers";
|
||||||
import RequiredAuth from "./RequiredAuth";
|
import RequiredAuth from "./RequiredAuth";
|
||||||
import DeviceCreate from "../pages/Devices/Create";
|
import DeviceCreateOrEdit from "../pages/Devices/CreateOrEdit";
|
||||||
|
import FishboneCreateOrEdit from "../pages/Fishbone/CreateOrEdit";
|
||||||
|
|
||||||
export default function Routes() {
|
export default function Routes() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -31,8 +32,11 @@ export default function Routes() {
|
||||||
<Route path="/towers" element={<Towers />} />
|
<Route path="/towers" element={<Towers />} />
|
||||||
|
|
||||||
{/* Create Page */}
|
{/* Create Page */}
|
||||||
<Route path="/devices/:pid" element={<DeviceCreate />} />
|
<Route path="/devices/:pid" element={<DeviceCreateOrEdit />} />
|
||||||
<Route path="/devices/create" element={<DeviceCreate />} />
|
<Route path="/devices/create" element={<DeviceCreateOrEdit />} />
|
||||||
|
|
||||||
|
<Route path="/fishbone/:pid" element={<FishboneCreateOrEdit />} />
|
||||||
|
<Route path="/fishbone/create" element={<FishboneCreateOrEdit />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
</Route>
|
</Route>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ export const useDeviceStore = create<DeviceState>()(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
error: null,
|
error: null,
|
||||||
lastUpdate: null,
|
lastUpdate: null,
|
||||||
|
towerSelect: [],
|
||||||
getAll: async () => {
|
getAll: async () => {
|
||||||
set({ isLoading: true });
|
set({ isLoading: true });
|
||||||
try {
|
try {
|
||||||
|
|
@ -89,6 +90,23 @@ export const useDeviceStore = create<DeviceState>()(
|
||||||
set({ isLoading: false });
|
set({ isLoading: false });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getTowerSelect: async () => {
|
||||||
|
set({ isLoading: true });
|
||||||
|
try {
|
||||||
|
const towers = await deviceRepository.getTowerSelect();
|
||||||
|
set({ towerSelect: towers });
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.status === 401) {
|
||||||
|
set({ error: error.response?.status?.description });
|
||||||
|
} else {
|
||||||
|
set({
|
||||||
|
error: error.response?.status?.description || error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
set({ isLoading: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
clearError: () => set({ error: null }),
|
clearError: () => set({ error: null }),
|
||||||
clearDevice: () => {
|
clearDevice: () => {
|
||||||
set({ device: null })
|
set({ device: null })
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
import { create } from "zustand";
|
||||||
|
import { persist } from "zustand/middleware";
|
||||||
|
import { fishboneRepository } from "../repositories/fishboneRepository";
|
||||||
|
import { createJSONStorage } from "zustand/middleware";
|
||||||
|
import { immer } from 'zustand/middleware/immer'
|
||||||
|
import { secureStorage } from "./storage";
|
||||||
|
import { Fishbone, FishboneState } from "../types/fishbone.types";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
export const useFishboneStore = create<FishboneState>()(
|
||||||
|
persist(
|
||||||
|
immer((set, get) => ({
|
||||||
|
data: [],
|
||||||
|
fishbone: null,
|
||||||
|
isLoading: false,
|
||||||
|
error: null,
|
||||||
|
lastUpdate: null,
|
||||||
|
backboneSelect: [],
|
||||||
|
deviceSelect: [],
|
||||||
|
getAll: async () => {
|
||||||
|
set({ isLoading: true });
|
||||||
|
try {
|
||||||
|
const fishbones = await fishboneRepository.getAll();
|
||||||
|
set({ data: fishbones, lastUpdate: dayjs().valueOf() });
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.status === 401) {
|
||||||
|
set({ error: error.response?.status?.description });
|
||||||
|
} else {
|
||||||
|
set({
|
||||||
|
error: error.response?.status?.description || error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
set({ isLoading: false, lastUpdate: dayjs().valueOf() });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
find: async (id: string) => {
|
||||||
|
set({ isLoading: true });
|
||||||
|
try {
|
||||||
|
const fishbone = await fishboneRepository.getFishboneById(id);
|
||||||
|
|
||||||
|
set({ fishbone: fishbone });
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.status === 401) {
|
||||||
|
set({ error: error.response.status.description });
|
||||||
|
} else {
|
||||||
|
set({
|
||||||
|
error: error.response?.status?.description || error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
set({ isLoading: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
create: async (
|
||||||
|
fishbone: Omit<Fishbone, "id" & "created_at" & "updated_at">
|
||||||
|
) => {
|
||||||
|
set({ isLoading: true });
|
||||||
|
try {
|
||||||
|
await fishboneRepository.createFishbone(fishbone);
|
||||||
|
} catch (error: any) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
if (error.status === 401) {
|
||||||
|
set({ error: error.response.status.description });
|
||||||
|
} else {
|
||||||
|
set({
|
||||||
|
error: error.response?.status?.description || error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
set({ isLoading: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
update: async (
|
||||||
|
id: string,
|
||||||
|
fishbone: Omit<Fishbone, "id" & "created_at" & "updated_at">
|
||||||
|
) => {
|
||||||
|
set({ isLoading: true });
|
||||||
|
try {
|
||||||
|
await fishboneRepository.updateFishbone(id, fishbone);
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.status === 401) {
|
||||||
|
set({ error: error.response.status.description });
|
||||||
|
} else {
|
||||||
|
set({
|
||||||
|
error: error.response?.status?.description || error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
set({ isLoading: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getBackboneSelect: async () => {
|
||||||
|
set({ isLoading: true });
|
||||||
|
try {
|
||||||
|
const backboneSelect = await fishboneRepository.getBackboneSelect();
|
||||||
|
set({ backboneSelect: backboneSelect });
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.status === 401) {
|
||||||
|
set({ error: error.response.status.description });
|
||||||
|
} else {
|
||||||
|
set({
|
||||||
|
error: error.response?.status?.description || error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
set({ isLoading: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getDeviceSelect: async () => {
|
||||||
|
set({ isLoading: true });
|
||||||
|
try {
|
||||||
|
const deviceSelect = await fishboneRepository.getDeviceSelect();
|
||||||
|
set({ deviceSelect: deviceSelect });
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.status === 401) {
|
||||||
|
set({ error: error.response.status.description });
|
||||||
|
} else {
|
||||||
|
set({
|
||||||
|
error: error.response?.status?.description || error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
set({ isLoading: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearError: () => set({ error: null }),
|
||||||
|
clearFishbone: () => {
|
||||||
|
set({ fishbone: null })
|
||||||
|
},
|
||||||
|
cacheExpired: () => {
|
||||||
|
return (
|
||||||
|
get().lastUpdate === null ||
|
||||||
|
dayjs(get().lastUpdate).isBefore(
|
||||||
|
dayjs().subtract(
|
||||||
|
import.meta.env.VITE_APP_CACHE_TIME_VALUE,
|
||||||
|
import.meta.env.VITE_APP_CACHE_TIME_UNIT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
{ name: "fishbones", storage: createJSONStorage(() => secureStorage) }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
@ -96,7 +96,7 @@ export default function ComponentsOverrides(theme: Theme) {
|
||||||
TableFooter(theme),
|
TableFooter(theme),
|
||||||
TableHead(theme),
|
TableHead(theme),
|
||||||
TablePagination(),
|
TablePagination(),
|
||||||
TableRow(),
|
TableRow(theme),
|
||||||
Tabs(),
|
Tabs(),
|
||||||
ToggleButton(theme),
|
ToggleButton(theme),
|
||||||
Tooltip(theme),
|
Tooltip(theme),
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import { ResponseApi } from "./response.types";
|
import { ResponseApi } from "./response.types";
|
||||||
import { CacheState, ErrorState } from "./store.types";
|
import { CacheState, ErrorState, SelectState } from "./store.types";
|
||||||
|
|
||||||
export interface DeviceRepositoryProps {
|
export interface DeviceRepositoryProps {
|
||||||
getAll: () => Promise<Device[] | []>;
|
getAll: () => Promise<DeviceDataTable[] | []>;
|
||||||
getDeviceById: (id: string) => Promise<Device>;
|
getDeviceById: (id: string) => Promise<Device>;
|
||||||
createDevice: (device: DeviceRequest) => Promise<Pick<ResponseApi<any>, "status">>;
|
createDevice: (device: DeviceRequest) => Promise<Pick<ResponseApi<any>, "status">>;
|
||||||
updateDevice: (id: string, device: DeviceRequest) => Promise<Pick<ResponseApi<any>, "status">>;
|
updateDevice: (id: string, device: DeviceRequest) => Promise<Pick<ResponseApi<any>, "status">>;
|
||||||
|
getTowerSelect: () => Promise<SelectState[] | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Device {
|
export interface Device {
|
||||||
|
|
@ -16,6 +17,7 @@ export interface Device {
|
||||||
latitude: string | number;
|
latitude: string | number;
|
||||||
port_amount: number;
|
port_amount: number;
|
||||||
status: DeviceStatus;
|
status: DeviceStatus;
|
||||||
|
tower_id: string | null;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|
@ -29,10 +31,12 @@ export interface DeviceRequest extends Omit<Device, "id" & "created_at" & "updat
|
||||||
* =============
|
* =============
|
||||||
*/
|
*/
|
||||||
export interface DeviceState extends ErrorState, CacheState {
|
export interface DeviceState extends ErrorState, CacheState {
|
||||||
data?: Device[];
|
data?: DeviceDataTable[];
|
||||||
device?: Device | null;
|
device?: Device | null;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
lastUpdate: number | null;
|
lastUpdate: number | null;
|
||||||
|
towerSelect: SelectState[] | null;
|
||||||
|
getTowerSelect: () => Promise<void>;
|
||||||
getAll: () => Promise<void>;
|
getAll: () => Promise<void>;
|
||||||
find: (id: string) => Promise<void>;
|
find: (id: string) => Promise<void>;
|
||||||
create: (device: DeviceRequest) => Promise<void>;
|
create: (device: DeviceRequest) => Promise<void>;
|
||||||
|
|
@ -40,7 +44,12 @@ export interface DeviceState extends ErrorState, CacheState {
|
||||||
clearDevice: () => void;
|
clearDevice: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeviceErrorInputState {
|
export interface DeviceDataTable extends Pick<Device, "id" | "device_code" | "device_type" | "port_amount" | "status"> {
|
||||||
username?: string | null;
|
address: string;
|
||||||
password?: string | null;
|
total_used_port: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGetTowerSelect {
|
||||||
|
id: string;
|
||||||
|
tower_code: string;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { ResponseApi } from "./response.types";
|
||||||
|
import { CacheState, ErrorState, SelectState } from "./store.types";
|
||||||
|
|
||||||
|
export interface FishboneRepositoryProps {
|
||||||
|
getAll: () => Promise<FishboneDataTable[] | []>;
|
||||||
|
getFishboneById: (id: string) => Promise<Fishbone>;
|
||||||
|
createFishbone: (fishbone: FishboneRequest) => Promise<Pick<ResponseApi<any>, "status">>;
|
||||||
|
updateFishbone: (id: string, fishbone: FishboneRequest) => Promise<Pick<ResponseApi<any>, "status">>;
|
||||||
|
getBackboneSelect: () => Promise<SelectState[] | null>;
|
||||||
|
getDeviceSelect: () => Promise<SelectState[] | null>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Fishbone {
|
||||||
|
id: string;
|
||||||
|
backbone_id: string;
|
||||||
|
backbone_core: string;
|
||||||
|
dev_start_id: string;
|
||||||
|
dev_end_id: string;
|
||||||
|
longitude: string | number;
|
||||||
|
latitude: string | number;
|
||||||
|
core_amount: number;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FishboneRequest extends Omit<Fishbone, "id" & "created_at" & "updated_at"> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fishbone State
|
||||||
|
* =============
|
||||||
|
*/
|
||||||
|
export interface FishboneState extends ErrorState, CacheState {
|
||||||
|
data?: FishboneDataTable[];
|
||||||
|
fishbone?: Fishbone | null;
|
||||||
|
isLoading: boolean;
|
||||||
|
lastUpdate: number | null;
|
||||||
|
backboneSelect: SelectState[] | null;
|
||||||
|
deviceSelect: SelectState[] | null;
|
||||||
|
getBackboneSelect: () => Promise<void>;
|
||||||
|
getDeviceSelect: () => Promise<void>;
|
||||||
|
getAll: () => Promise<void>;
|
||||||
|
find: (id: string) => Promise<void>;
|
||||||
|
create: (fishbone: FishboneRequest) => Promise<void>;
|
||||||
|
update: (id: string, fishbone: FishboneRequest) => Promise<void>;
|
||||||
|
clearFishbone: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FishboneDataTable extends Pick<Fishbone, "id" | "core_amount" | "longitude" | "latitude"> {
|
||||||
|
backbone: string;
|
||||||
|
address: string;
|
||||||
|
device_start: string;
|
||||||
|
device_end: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGetBackboneSelect {
|
||||||
|
id: string;
|
||||||
|
backbone_code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGetDeviceSelect {
|
||||||
|
id: string;
|
||||||
|
device_code: string;
|
||||||
|
}
|
||||||
|
|
@ -6,3 +6,8 @@ export interface ErrorState<T = undefined> {
|
||||||
export interface CacheState {
|
export interface CacheState {
|
||||||
cacheExpired: () => boolean;
|
cacheExpired: () => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SelectState {
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue