Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[+] implement GET /metric & DELETE /metric to web UI, closes #116 #117

Merged
merged 3 commits into from
Feb 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { AlertColor, Box, Button, Dialog, DialogActions, DialogContent, DialogCo

import { useMutation, useQueryClient } from "@tanstack/react-query";
import { QueryKeys } from "queries/queryKeys";
import { Db } from "queries/types";
import { Db } from "queries/types/DbTypes";
import DbService from "services/Db";


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import AddIcon from '@mui/icons-material/Add';
import { Button } from "@mui/material";
import { GridToolbarColumnsButton, GridToolbarContainer, GridToolbarFilterButton } from "@mui/x-data-grid";
import { Db } from 'queries/types';
import { Db } from 'queries/types/DbTypes';

export const GridToolbarComponent = (setModalOpen: React.Dispatch<React.SetStateAction<boolean>>, setEditData: React.Dispatch<React.SetStateAction<Db | undefined>>) => {

Expand Down
2 changes: 1 addition & 1 deletion src/webui/src/layout/Dashboard/DbsTable/ModalComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { AxiosResponse } from "axios";
import { Controller, FieldPath, FormProvider, SubmitHandler, useForm, useFormContext } from "react-hook-form";
import { QueryKeys } from "queries/queryKeys";
import { Db, createDbForm, updateDbForm } from "queries/types";
import { Db, createDbForm, updateDbForm } from "queries/types/DbTypes";
import DbService from "services/Db";
import {
AutocompleteComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
TextField, Tooltip
} from "@mui/material";
import { ControllerRenderProps, FieldPath } from "react-hook-form";
import { createDbForm } from "queries/types";
import { createDbForm } from "queries/types/DbTypes";

type SelectParams = {
field: ControllerRenderProps<createDbForm, FieldPath<createDbForm>>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TextField } from "@mui/material";
import { ControllerRenderProps, FieldPath } from "react-hook-form";
import { createDbForm } from "queries/types";
import { createDbForm } from "queries/types/DbTypes";


type Params = {
Expand Down
45 changes: 5 additions & 40 deletions src/webui/src/layout/Dashboard/DbsTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { useState } from "react";

import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from '@mui/icons-material/Close';
import { Alert, AlertColor, Box, CircularProgress, Snackbar, Typography } from "@mui/material";
import { Alert, AlertColor, Box, Checkbox, CircularProgress, Snackbar, Typography } from "@mui/material";
import {
DataGrid,
GridColDef,
Expand All @@ -12,7 +10,7 @@ import {
import { useQuery } from "@tanstack/react-query";
import moment from "moment";
import { QueryKeys } from "queries/queryKeys";
import { Db } from "queries/types";
import { Db } from "queries/types/DbTypes";
import DbService from "services/Db";

import { ActionsComponent } from "./ActionsComponent";
Expand Down Expand Up @@ -114,13 +112,7 @@ export const DbsTable = () => {
headerName: "Super user?",
width: 120,
type: "boolean",
renderCell: (params: GridRenderCellParams<boolean>) => {
if (params.value) {
return <CheckIcon />;
} else {
return <CloseIcon />;
}
},
renderCell: (params: GridRenderCellParams<boolean>) => <Checkbox checked={params.value} disableRipple />,
align: "center",
headerAlign: "center"
},
Expand All @@ -131,21 +123,6 @@ export const DbsTable = () => {
align: "center",
headerAlign: "center"
},
{
field: "Helpers",
headerName: "Auto-create helpers?",
type: "boolean",
width: 120,
renderCell: (params: GridRenderCellParams<boolean>) => {
if (params.value) {
return <CheckIcon />;
} else {
return <CloseIcon />;
}
},
align: "center",
headerAlign: "center"
},
{
field: "md_sslmode",
headerName: "SSL Mode",
Expand Down Expand Up @@ -240,13 +217,7 @@ export const DbsTable = () => {
headerName: "Master mode only?",
type: "boolean",
width: 120,
renderCell: (params: GridRenderCellParams<boolean>) => {
if (params.value) {
return <CheckIcon />;
} else {
return <CloseIcon />;
}
},
renderCell: (params: GridRenderCellParams<boolean>) => <Checkbox checked={params.value} disableRipple />,
align: "center",
headerAlign: "center"
},
Expand All @@ -270,13 +241,7 @@ export const DbsTable = () => {
headerName: "Enabled?",
type: "boolean",
width: 120,
renderCell: (params: GridRenderCellParams<boolean>) => {
if (params.value) {
return <CheckIcon />;
} else {
return <CloseIcon />;
}
},
renderCell: (params: GridRenderCellParams<boolean>) => <Checkbox checked={params.value} disableRipple />,
align: "center",
headerAlign: "center"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
import { Box, Button } from "@mui/material";
import { AlertColor, Box, Button } from "@mui/material";
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { QueryKeys } from 'queries/queryKeys';
import { Metric } from 'queries/types/MetricTypes';
import MetricService from 'services/Metric';

type Props = {
data: any
type Params = {
data: Metric,
handleAlertOpen: (isOpen: boolean, text: string, type: AlertColor) => void
};

export const ActionsComponent = ({ data }: Props) => {
export const ActionsComponent = ({ data, handleAlertOpen }: Params) => {
const services = MetricService.getInstance();
const queryClient = useQueryClient();

const deleteRecord = useMutation({
mutationFn: async (m_id: number) => {
return await services.deleteMetric(m_id);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: QueryKeys.metric });
handleAlertOpen(true, `Metric "${data.m_name}" has been deleted successfully!`, "success");
},
onError: (error: any) => {
handleAlertOpen(true, error.response.data, "error");
}
});

const handleClick = () => {
alert(JSON.stringify(data));
Expand All @@ -26,6 +46,7 @@ export const ActionsComponent = ({ data }: Props) => {
size="small"
variant="contained"
startIcon={<DeleteIcon />}
onClick={() => deleteRecord.mutate(data.m_id)}
>
Delete
</Button>
Expand Down
92 changes: 65 additions & 27 deletions src/webui/src/layout/MetricDefinitions/MetricsTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from '@mui/icons-material/Close';
import { Box, Typography } from "@mui/material";
import { useState } from "react";
import { Alert, AlertColor, Box, Checkbox, CircularProgress, Snackbar, Typography } from "@mui/material";
import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid";
import { useQuery } from '@tanstack/react-query';
import moment from 'moment';
import { QueryKeys } from 'queries/queryKeys';
import { Metric } from 'queries/types/MetricTypes';
import MetricService from 'services/Metric';
import { ActionsComponent } from './ActionsComponent';
import { GridToolbarComponent } from "./GridToolbarComponent";

export const MetricsTable = () => {
const services = MetricService.getInstance();
const [alertOpen, setAlertOpen] = useState(false);
const [severity, setSeverity] = useState<AlertColor>();
const [alertText, setAlertText] = useState("");

const data = [
{
"m_id": 1,
"m_name": "wsl",
"m_version": 14,
"m_comment": "some comment about metric",
"m_is_active": true,
"m_is_helper": false,
"m_last_modified_on": new Date()
},
{
"m_id": 2,
"m_name": "backends",
"m_version": 10.0,
"m_comment": "some comment about metric",
"m_is_active": true,
"m_is_helper": false,
"m_last_modified_on": new Date()
const handleAlertOpen = (isOpen: boolean, text: string, type: AlertColor) => {
setSeverity(type);
setAlertText(text);
setAlertOpen(isOpen);
};

const handleAlertClose = () => {
setAlertOpen(false);
};

const { status, data } = useQuery<Metric[]>({
queryKey: QueryKeys.metric,
queryFn: async () => {
return await services.getMetrics();
}
];
});

const columns: GridColDef[] = [
{
Expand All @@ -47,7 +50,7 @@ export const MetricsTable = () => {
headerAlign: "center"
},
{
field: "m_version",
field: "m_pg_version_from",
headerName: "PG version",
width: 150,
type: "number",
Expand All @@ -57,23 +60,39 @@ export const MetricsTable = () => {
{
field: "m_comment",
headerName: "Comment",
width: 150,
width: 200,
align: "center",
headerAlign: "center"
},
{
field: "m_is_active",
headerName: "Enabled?",
width: 120,
renderCell: (params: GridRenderCellParams<boolean>) => params.value ? <CheckIcon /> : <CloseIcon />,
renderCell: (params: GridRenderCellParams<boolean>) => <Checkbox checked={params.value} disableRipple />,
align: "center",
headerAlign: "center"
},
{
field: "m_is_helper",
headerName: "Helpers?",
width: 120,
renderCell: (params: GridRenderCellParams<boolean>) => params.value ? <CheckIcon /> : <CloseIcon />,
renderCell: (params: GridRenderCellParams<boolean>) => <Checkbox checked={params.value} disableRipple />,
align: "center",
headerAlign: "center"
},
{
field: "m_master_only",
headerName: "Master only?",
width: 120,
renderCell: (params: GridRenderCellParams<boolean>) => <Checkbox checked={params.value} disableRipple />,
align: "center",
headerAlign: "center"
},
{
field: "m_standby_only",
headerName: "Standby only?",
width: 120,
renderCell: (params: GridRenderCellParams<boolean>) => <Checkbox checked={params.value} disableRipple />,
align: "center",
headerAlign: "center"
},
Expand All @@ -94,14 +113,33 @@ export const MetricsTable = () => {
type: "actions",
width: 200,
renderCell: (params) => (
<ActionsComponent data={params.row} />
<ActionsComponent data={params.row} handleAlertOpen={handleAlertOpen} />
),
headerAlign: "center"
}
];

if (status === "loading") {
return (
<Box sx={{ width: "100%", height: 500, display: "flex", justifyContent: "center", alignItems: "center" }}>
<CircularProgress />
</Box>
);
};

if (status === "error") {
return (
<Box>
<Typography>Some error happens</Typography>
</Box>
);
};

return (
<Box display="flex" flexDirection="column" gap={1} height="100%">
<Snackbar open={alertOpen} autoHideDuration={5000} onClose={handleAlertClose}>
<Alert sx={{ width: "auto" }} variant="filled" severity={severity}>{alertText}</Alert>
</Snackbar>
<Typography variant="h5">
Metrics
</Typography>
Expand Down
3 changes: 2 additions & 1 deletion src/webui/src/queries/queryKeys.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const QueryKeys = {
db: ["db"]
db: ["db"],
metric: ["metric"]
};
File renamed without changes.
14 changes: 14 additions & 0 deletions src/webui/src/queries/types/MetricTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type Metric = {
m_id: number,
m_sql: string,
m_name: string,
m_sql_su: string,
m_comment: string | null,
m_is_active: boolean,
m_is_helper: boolean,
m_master_only: boolean,
m_column_attrs: Object,
m_standby_only: boolean,
m_pg_version_from: number,
m_last_modified_on: string
};
4 changes: 2 additions & 2 deletions src/webui/src/services/Db/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import axios from "axios";
import { createDbForm, updateDbForm } from "queries/types";
import { createDbForm, updateDbForm } from "queries/types/DbTypes";

export default class DbService {
private static _instance: DbService;
Expand All @@ -10,7 +10,7 @@ export default class DbService {
}

return DbService._instance;
}
};

public async getMonitoredDb() {
return await axios.get("/db").
Expand Down
30 changes: 30 additions & 0 deletions src/webui/src/services/Metric/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import axios from "axios";


export default class MetricService {
private static _instance: MetricService;

public static getInstance(): MetricService {
if (!MetricService._instance) {
MetricService._instance = new MetricService();
}

return MetricService._instance;
};

public async getMetrics() {
return await axios.get("/metric").
then(response => response.data).
catch(error => {
throw error;
});
};

public async deleteMetric(m_id: number) {
return await axios.delete("/metric", { params: { "id": m_id } }).
then(response => response.data).
catch(error => {
throw error;
});
};
}