cleaned up admin

This commit is contained in:
Luke Berndt
2023-04-05 21:16:53 -04:00
parent efe3794eee
commit f7f5265264
26 changed files with 149 additions and 304 deletions

View File

@@ -1,99 +1,77 @@
import React, { Component } from "react";
import React from "react";
import { Group } from '@visx/group';
import { curveStep} from '@visx/curve';
import { LinePath } from '@visx/shape';
import { scaleLinear, scaleBand, scaleTime } from '@visx/scale';
import { scaleLinear, scaleTime } from '@visx/scale';
import { timeParse, timeFormat } from 'd3-time-format';
import { AxisBottom, AxisLeft } from '@visx/axis';
import { Dimmer, Loader } from "semantic-ui-react";
import { Loader } from "semantic-ui-react";
const CallChart = (props) => {
class CallChart extends Component {
constructor(props) {
super(props);
}
var callData = props.data;
if (!callData) {
return (
<Loader size='large'>Loading</Loader>
)
}
render() {
var callData = this.props.data;
if (!callData) {
return (
var callTotals = callData.callTotals;
var errorTotals = callData.errorTotals;
<Loader size='large'>Loading</Loader>
// Define the graph dimensions and margins
const width = props.width;
const height = 500;
const margin = { top: 20, bottom: 40, left: 40, right: 20 };
const parseDate = timeParse("%Y%m%d");
const format = timeFormat("%b %d");
const formatDate = (date) => format(parseDate(date));
)
}
var callTotals = [];
var errorTotals = [];
// Then we'll create some bounds
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;
// Define the graph dimensions and margins
const width = this.props.width;
const height = 500;
const margin = { top: 20, bottom: 40, left: 40, right: 20 };
const parseDate = timeParse("%Y%m%d");
const format = timeFormat("%b %d");
const formatDate = (date) => format(parseDate(date));
// accessors
const x = d => d.x;
const y = d => d.y;
// Then we'll create some bounds
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;
// accessors
const x = d => d.x;
const y = d => d.y;
// Compose together the scale and accessor functions to get point functions
const dotColor = n => {
var colores_g = ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"];
return colores_g[n % colores_g.length];
}
const compose = (scale, accessor) => (data) => scale(accessor(data));
var xScale, yScale, xPoint, yPoint;
if (callData) {
// We'll use some mock data from `@vx/mock-data` for this.
callTotals = callData.callTotals;
errorTotals = callData.errorTotals;
// scales
xScale = scaleTime({
range: [0, xMax],
domain: [callData.minDate, callData.maxDate],
tickFormat: () => (val) => formatDate(val)
});
yScale = scaleLinear({
range: [yMax, 0],
domain: [0, callData.maxValue],
});
xPoint = compose(xScale, x);
yPoint = compose(yScale, y);
}
var xScale, yScale;
if (callData) {
// We'll use some mock data from `@vx/mock-data` for this.
// scales
xScale = scaleTime({
range: [0, xMax],
domain: [callData.minDate, callData.maxDate],
tickFormat: () => (val) => formatDate(val)
});
yScale = scaleLinear({
range: [yMax, 0],
domain: [0, callData.maxValue],
});
}
return (
<svg width={width} height={height}>
<Group left={margin.left} top={margin.top} >
<AxisBottom top={yMax} scale={xScale} numTicks={width > 520 ? 10 : 5} />
<AxisLeft scale={yScale} />
<LinePath
data={callTotals}
x={x}
y={y}
strokeWidth={2}
curve={curveStep}
/>
<LinePath
data={errorTotals}
x={x}
y={y}
strokeWidth={2}
stroke="red"
curve={curveStep}
/>
</Group>
</svg>
);
}
<svg width={width} height={height}>
<Group left={margin.left} top={margin.top}>
<AxisBottom top={yMax} scale={xScale} numTicks={width > 520 ? 10 : 5} />
<AxisLeft scale={yScale} />
<LinePath
data={callTotals}
x={x}
y={y}
strokeWidth={2}
curve={curveStep}
/>
<LinePath
data={errorTotals}
x={x}
y={y}
strokeWidth={2}
stroke="red"
curve={curveStep}
/>
</Group>
</svg>
);
}
export default CallChart;

View File

@@ -3,36 +3,24 @@ import React, { useState } from "react";
import {
Container,
Header,
Form,
Grid,
Segment,
Input,
Button,
Divider,
Message,
Icon
} from "semantic-ui-react";
import { useCreateSystemMutation} from '../features/api/apiSlice'
import { useSelector, useDispatch } from 'react-redux'
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useSelector } from 'react-redux'
import { useNavigate } from 'react-router-dom';
import SystemForm from "./SystemForm";
// ----------------------------------------------------
const requestMessageStyle = {
color: "red"
};
// ----------------------------------------------------
const CreateSystem = (props) => {
const CreateSystem = () => {
const navigate = useNavigate();
const [createSystem, { error }] = useCreateSystemMutation();
const [createSystem ] = useCreateSystemMutation();
const { screenName } = useSelector((state) => state.user);
const [requestMessage, setRequestMessage] = useState("");
const handleSubmit = async (system) => {
try {
const originalPromiseResult = await createSystem(system).unwrap();
await createSystem(system).unwrap();
navigate("/list-systems")
} catch (error) {
const message = error.data.message;

View File

@@ -7,9 +7,7 @@ import { AxisBottom, AxisLeft } from '@visx/axis';
import { Loader } from "semantic-ui-react";
import { LegendOrdinal} from '@visx/legend';
class ErrorChart extends Component {
constructor(props) {
super(props);
}
render() {
var errorData = this.props.data;
@@ -44,12 +42,11 @@ class ErrorChart extends Component {
return colores_g[n % colores_g.length];
}
const compose = (scale, accessor) => (data) => scale(accessor(data));
var zScale = scaleOrdinal({
domain: errorData.legend,
range: ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"]
});
var xScale, yScale, xPoint, yPoint;
var xScale, yScale;
if (errorData) {
// We'll use some mock data from `@vx/mock-data` for this.
data = errorData.data;
@@ -67,8 +64,6 @@ class ErrorChart extends Component {
domain: errorData.legend,
range: ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"]
});
xPoint = compose(xScale, x);
yPoint = compose(yScale, y);
}

View File

@@ -1,4 +1,3 @@
import { Component, useRef } from "react";
import SystemCard from "./SystemCard";
import {
Container,
@@ -9,15 +8,12 @@ import {
Button,
} from "semantic-ui-react";
import { useGetSystemsQuery, } from '../features/api/apiSlice'
import { useDispatch } from 'react-redux'
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
// ----------------------------------------------------
const ListSystems = (props) => {
const ListSystems = () => {
const { data, isSuccess } = useGetSystemsQuery();
const dispatch = useDispatch();
const navigate = useNavigate();
let systems = false;
if (isSuccess) {
@@ -31,7 +27,6 @@ const ListSystems = (props) => {
<div>
<Container>
<Header as="h1">Radio Systems</Header>
<Button onClick={(e) => navigate("/create-system")}><Icon name='plus' />Add System</Button>
<Divider />
<Card.Group itemsPerRow={4}>

View File

@@ -1,4 +1,3 @@
import React, { Component } from "react"
import CallChart from "./CallChart"
import { ParentSize } from "@visx/responsive";

View File

@@ -1,4 +1,3 @@
import React, { Component } from "react"
import ErrorChart from "./ErrorChart"
import { ParentSize } from "@visx/responsive";

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useLayoutEffect, useState, useRef, useCallback, useMemo } from "react";
import { Link, useLocation, useParams, useNavigate } from 'react-router-dom';
import React, { useEffect, useLayoutEffect, useState } from "react";
import { Link, useParams, useNavigate } from 'react-router-dom';
import ListTalkgroups from "../Talkgroups/ListTalkgroups.js";
import MessageBox from "../Components/Message.js";
import ListGroups from "../Group/ListGroups.js";
@@ -19,23 +19,21 @@ import {
List,
Segment,
Tab,
Divider,
Label
Divider
} from "semantic-ui-react";
const System = (props) => {
const System = () => {
const { shortName } = useParams();
const navigate = useNavigate();
const { data: systemsData, isSuccess: isSystemsSuccess } = useGetSystemsQuery();
const { data: talkgroupsData, isSuccess: isTalkgroupsSuccess } = useGetTalkgroupsQuery(shortName);
const { data: groupsData, isSuccess: isGroupsSuccess } = useGetGroupsQuery(shortName);
const { data: errorsData, isSuccess: isErrorsSuccess } = useGetErrorsQuery(shortName);
const [deleteGroupAPI, { isLoading: isDeleting }] = useDeleteGroupMutation();
const [reorderGroupsAPI, { isLoading: isReordering }] = useSaveGroupOrderMutation();
const [importTalkgroupsAPI, { isLoading: isImporting }] = useImportTalkgroupsMutation();
const { data: groupsData } = useGetGroupsQuery(shortName);
const { data: systemErrorData, isSuccess: isErrorsSuccess } = useGetErrorsQuery(shortName);
const [deleteGroupAPI] = useDeleteGroupMutation();
const [reorderGroupsAPI] = useSaveGroupOrderMutation();
const [importTalkgroupsAPI] = useImportTalkgroupsMutation();
const [deleteSystemAPI ] = useDeleteSystemMutation();
const [openSystemDeleteConfirm, setOpenSystemDeleteConfirm] = useState(false);
const [openPermissionDeleteConfirm, setOpenPermissionDeleteConfirm] = useState(false);
const [openMessage, setOpenMessage] = useState(false);
const [requestMessage, setRequestMessage] = useState("");
const [groupVisible, setGroupVisible] = useState(false);
@@ -99,17 +97,17 @@ const System = (props) => {
var maxValue = 0;
var MS_PER_MINUTE = 60000;
if (statistic) {
for (var j = 0; j < statistic.callTotals.length; j++) {
var spotsBack = statistic.callTotals.length - j;
var time = new Date(now - spotsBack * 15 * MS_PER_MINUTE);
for (let j = 0; j < statistic.callTotals.length; j++) {
let spotsBack = statistic.callTotals.length - j;
let time = new Date(now - spotsBack * 15 * MS_PER_MINUTE);
if (time < minDate) minDate = time;
if (statistic.callTotals[j] > maxValue)
maxValue = statistic.callTotals[j];
callTotals.push({ y: statistic.callTotals[j], x: time });
}
for (var j = 0; j < statistic.errorTotals.length; j++) {
var spotsBack = statistic.errorTotals.length - j;
var time = new Date(now - spotsBack * 15 * MS_PER_MINUTE);
for (let j = 0; j < statistic.errorTotals.length; j++) {
let spotsBack = statistic.errorTotals.length - j;
let time = new Date(now - spotsBack * 15 * MS_PER_MINUTE);
if (time < minDate) minDate = time;
if (statistic.errorTotals[j] > maxValue)
maxValue = statistic.errorTotals[j];
@@ -163,7 +161,7 @@ const System = (props) => {
const deleteGroup = async (groupId) => {
for (const num in groupsData) {
if (groupsData[num]._id == groupId) {
if (groupsData[num]._id === groupId) {
await deleteGroupAPI(groupsData[num])
}
}
@@ -203,7 +201,7 @@ const System = (props) => {
const handleSystemDeleteConfirm = async () => {
setOpenSystemDeleteConfirm(false);
try {
const originalPromiseResult = await deleteSystemAPI(shortName).unwrap();
await deleteSystemAPI(shortName).unwrap();
navigate("/list-systems")
} catch (error) {
const message = error.data.message;
@@ -217,7 +215,7 @@ const System = (props) => {
let system = false;
if (isSystemsSuccess) {
system = systemsData.systems.find(sys => sys.shortName == shortName);
system = systemsData.systems.find(sys => sys.shortName === shortName);
}
useLayoutEffect(() => {
@@ -239,9 +237,9 @@ const System = (props) => {
useEffect(() => {
if (isErrorsSuccess) {
processErrors(errorData)
processErrors(systemErrorData)
}
}, [isErrorsSuccess]);
}, [systemErrorData]);
let fileInput = null;
var location = "";
@@ -289,6 +287,7 @@ const System = (props) => {
case "state":
location = system.state;
break;
default:
case "city":
location = system.city + ", " + system.state;
break;

View File

@@ -1,5 +1,4 @@
import React, { Component } from "react";
import {
Card,
Icon,

View File

@@ -1,40 +0,0 @@
import { connect } from "react-redux"
import * as systemActionCreators from "./system-actions"
import * as talkgroupActionCreators from "../Talkgroups/talkgroup-actions"
import * as groupActionCreators from "../Group/group-actions"
import * as permissionActionCreators from "../Permission/permission-actions"
import * as errorActionCreators from "./error-actions"
import { bindActionCreators } from 'redux'
import System from "./System"
function mapStateToProps(state,props) {
return {
system: state.system.items.find((item) => item.shortName === props.match.params.shortName),
permissions: state.permission.items,
statistic: state.statistic[props.match.params.shortName],
systemIsWaiting: state.system.isWaiting,
talkgroupsIsWaiting: state.talkgroup.isWaiting,
groupsIsWaiting: state.group.isWaiting,
talkgroups: state.talkgroup.items[props.match.params.shortName],
orderChange: state.group.orderChange,
groups: state.group.items[props.match.params.shortName],
errors: state.error.items[props.match.params.shortName],
shortName: props.match.params.shortName,
activeTab: (props.match.params.tab ? props.match.params.tab : 0)
}
}
function mapDispatchToProps(dispatch) {
return {
groupActions: bindActionCreators(groupActionCreators, dispatch),
systemActions: bindActionCreators(systemActionCreators, dispatch),
talkgroupActions: bindActionCreators(talkgroupActionCreators, dispatch),
errorActions: bindActionCreators(errorActionCreators, dispatch),
permissionActions: bindActionCreators(permissionActionCreators, dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(System)

View File

@@ -28,13 +28,11 @@ const SystemForm = (props) => {
const [nameError, setNameError] = useState(false);
const [shortNameError, setShortNameError] = useState(false);
const [descriptionError, setDescriptionError] = useState(false);
const [emailError, setEmailError] = useState(false);
const [systemTypeError, setSystemTypeError] = useState(false);
const [systemStateError, setSystemStateError] = useState(false);
const [cityError, setCityError] = useState(false);
const [countyError, setCountyError] = useState(false);
const [countryError, setCountryError] = useState(false);
const [isEditing, setIsEditing] = useState(props.isEditing);
const [isEditing] = useState(props.isEditing);
useEffect(() => {
if (props.isEditing && props.system) {
@@ -49,7 +47,7 @@ const SystemForm = (props) => {
setShowScreenName(props.system.showScreenName);
setIgnoreUnknownTalkgroup(props.system.ignoreUnknownTalkgroup);
}
}, [props.system]);
}, [props.system, props.isEditing]);
const checkInputs = () => {

View File

@@ -1,31 +1,31 @@
import React, { useEffect, useLayoutEffect, useState, useRef, useCallback, useMemo } from "react";
import React, { useState } from "react";
import SystemForm from "./SystemForm";
import {
Container,
Header
} from "semantic-ui-react";
import { useUpdateSystemMutation, useGetSystemsQuery, } from '../features/api/apiSlice'
import { useSelector, useDispatch } from 'react-redux'
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useSelector } from 'react-redux'
import { useNavigate, useParams } from 'react-router-dom';
const UpdateSystem = (props) => {
const { screenName } = useSelector((state) => state.user);
const { shortName } = useParams();
const { data: systemsData, isSuccess: isSystemsSuccess } = useGetSystemsQuery();
const [updateSystem, { error }] = useUpdateSystemMutation();
const [updateSystem] = useUpdateSystemMutation();
const [requestMessage, setRequestMessage] = useState("");
const navigate = useNavigate();
let system = false;
if (isSystemsSuccess) {
system = systemsData.systems.find(sys => sys.shortName == shortName);
system = systemsData.systems.find(sys => sys.shortName === shortName);
}
const handleSystemSubmit = async (system) => {
try {
const originalPromiseResult = await updateSystem(system).unwrap();
await updateSystem(system).unwrap();
navigate("/system/" + shortName)
} catch (error) {
const message = error.data.message;