fix some bugs
This commit is contained in:
parent
ca05fd5b3e
commit
ee40a4d544
|
@ -0,0 +1,136 @@
|
||||||
|
{
|
||||||
|
"Information": {
|
||||||
|
"defaultMessage": "Information"
|
||||||
|
},
|
||||||
|
"addNewChild": {
|
||||||
|
"defaultMessage": "Add new child"
|
||||||
|
},
|
||||||
|
"addNewDialogButton": {
|
||||||
|
"defaultMessage": "Add new dialog button"
|
||||||
|
},
|
||||||
|
"addUser": {
|
||||||
|
"defaultMessage": "Create user"
|
||||||
|
},
|
||||||
|
"alarms": {
|
||||||
|
"defaultMessage": "Alarms"
|
||||||
|
},
|
||||||
|
"applyChanges": {
|
||||||
|
"defaultMessage": "Apply changes"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"defaultMessage": "Country"
|
||||||
|
},
|
||||||
|
"createNewFolder": {
|
||||||
|
"defaultMessage": "Create new folder"
|
||||||
|
},
|
||||||
|
"createNewUser": {
|
||||||
|
"defaultMessage": "Create new user"
|
||||||
|
},
|
||||||
|
"customerName": {
|
||||||
|
"defaultMessage": "Customer name"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"defaultMessage": "Email"
|
||||||
|
},
|
||||||
|
"english": {
|
||||||
|
"defaultMessage": "English"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
},
|
||||||
|
"folder": {
|
||||||
|
"defaultMessage": "Folder"
|
||||||
|
},
|
||||||
|
"german": {
|
||||||
|
"defaultMessage": "German"
|
||||||
|
},
|
||||||
|
"groupTabs": {
|
||||||
|
"defaultMessage": "Group tabs"
|
||||||
|
},
|
||||||
|
"groupTree": {
|
||||||
|
"defaultMessage": "Group tree"
|
||||||
|
},
|
||||||
|
"information": {
|
||||||
|
"defaultMessage": "Information"
|
||||||
|
},
|
||||||
|
"inheritedAccess": {
|
||||||
|
"defaultMessage": "Inherited access from"
|
||||||
|
},
|
||||||
|
"installation": {
|
||||||
|
"defaultMessage": "Installation"
|
||||||
|
},
|
||||||
|
"installationTabs": {
|
||||||
|
"defaultMessage": "Installation tabs"
|
||||||
|
},
|
||||||
|
"installations": {
|
||||||
|
"defaultMessage": "Installations"
|
||||||
|
},
|
||||||
|
"lastWeek": {
|
||||||
|
"defaultMessage": "Last week"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"defaultMessage": "Location"
|
||||||
|
},
|
||||||
|
"log": {
|
||||||
|
"defaultMessage": "Log"
|
||||||
|
},
|
||||||
|
"logout": {
|
||||||
|
"defaultMessage": "Logout"
|
||||||
|
},
|
||||||
|
"makeASelection": {
|
||||||
|
"defaultMessage": "Please make a selection on the left"
|
||||||
|
},
|
||||||
|
"manageAccess": {
|
||||||
|
"defaultMessage": "Manage access"
|
||||||
|
},
|
||||||
|
"move": {
|
||||||
|
"defaultMessage": "Move"
|
||||||
|
},
|
||||||
|
"moveTo": {
|
||||||
|
"defaultMessage": "Move to"
|
||||||
|
},
|
||||||
|
"moveTree": {
|
||||||
|
"defaultMessage": "Move tree"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"defaultMessage": "Name"
|
||||||
|
},
|
||||||
|
"navigationTabs": {
|
||||||
|
"defaultMessage": "Navigation tabs"
|
||||||
|
},
|
||||||
|
"orderNumbers": {
|
||||||
|
"defaultMessage": "Order number"
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
"defaultMessage": "Region"
|
||||||
|
},
|
||||||
|
"requiredLocation": {
|
||||||
|
"defaultMessage": "Location is required"
|
||||||
|
},
|
||||||
|
"requiredName": {
|
||||||
|
"defaultMessage": "Name is required"
|
||||||
|
},
|
||||||
|
"requiredRegion": {
|
||||||
|
"defaultMessage": "Region is required"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"defaultMessage": "Search"
|
||||||
|
},
|
||||||
|
"submit": {
|
||||||
|
"defaultMessage": "Submit"
|
||||||
|
},
|
||||||
|
"updateFolderErrorMessage": {
|
||||||
|
"defaultMessage": "Couldn't update folder, an error occured"
|
||||||
|
},
|
||||||
|
"updatedSuccessfully": {
|
||||||
|
"defaultMessage": "Updated successfully"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"defaultMessage": "User"
|
||||||
|
},
|
||||||
|
"userTabs": {
|
||||||
|
"defaultMessage": "user tabs"
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"defaultMessage": "Users"
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,8 +5,9 @@ import {
|
||||||
IconButton,
|
IconButton,
|
||||||
Avatar,
|
Avatar,
|
||||||
ListItemAvatar,
|
ListItemAvatar,
|
||||||
|
Alert,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Fragment, useContext, useEffect } from "react";
|
import { Fragment, useContext, useEffect, useState } from "react";
|
||||||
import axiosConfig from "../../../config/axiosConfig";
|
import axiosConfig from "../../../config/axiosConfig";
|
||||||
import PersonRemoveIcon from "@mui/icons-material/PersonRemove";
|
import PersonRemoveIcon from "@mui/icons-material/PersonRemove";
|
||||||
import PersonIcon from "@mui/icons-material/Person";
|
import PersonIcon from "@mui/icons-material/Person";
|
||||||
|
@ -14,10 +15,12 @@ import { UsersContext } from "../../Context/UsersContextProvider";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { GroupContext } from "../../Context/GroupContextProvider";
|
import { GroupContext } from "../../Context/GroupContextProvider";
|
||||||
import { UserContext } from "../../Context/UserContextProvider";
|
import { UserContext } from "../../Context/UserContextProvider";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
const UsersWithDirectAccess = () => {
|
const UsersWithDirectAccess = () => {
|
||||||
const { fetchUsersWithDirectAccessForResource, directAccessUsers } =
|
const { fetchUsersWithDirectAccessForResource, directAccessUsers } =
|
||||||
useContext(UsersContext);
|
useContext(UsersContext);
|
||||||
|
const [error, setError] = useState<any>();
|
||||||
const { currentType } = useContext(GroupContext);
|
const { currentType } = useContext(GroupContext);
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const { getCurrentUser } = useContext(UserContext);
|
const { getCurrentUser } = useContext(UserContext);
|
||||||
|
@ -35,12 +38,20 @@ const UsersWithDirectAccess = () => {
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
fetchUsersWithDirectAccessForResource();
|
fetchUsersWithDirectAccessForResource();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setError(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (directAccessUsers && directAccessUsers.length) {
|
if (directAccessUsers && directAccessUsers.length) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{error && (
|
||||||
|
<Alert severity="error">
|
||||||
|
<FormattedMessage id="error" defaultMessage={error.title} />
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
{directAccessUsers.map((user) => {
|
{directAccessUsers.map((user) => {
|
||||||
return (
|
return (
|
||||||
<Fragment key={user.id}>
|
<Fragment key={user.id}>
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
import routes from "../../../routes.json";
|
import routes from "../../../routes.json";
|
||||||
import PersonIcon from "@mui/icons-material/Person";
|
import PersonIcon from "@mui/icons-material/Person";
|
||||||
import { UsersContext } from "../../Context/UsersContextProvider";
|
import { UsersContext } from "../../Context/UsersContextProvider";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
const UsersWithInheritedAccess = () => {
|
const UsersWithInheritedAccess = () => {
|
||||||
const { fetchUsersWithInheritedAccessForResource, inheritedAccessUsers } =
|
const { fetchUsersWithInheritedAccessForResource, inheritedAccessUsers } =
|
||||||
|
@ -45,7 +46,10 @@ const UsersWithInheritedAccess = () => {
|
||||||
primary={user.name}
|
primary={user.name}
|
||||||
secondary={
|
secondary={
|
||||||
<>
|
<>
|
||||||
Inherited access from{" "}
|
<FormattedMessage
|
||||||
|
id="inheritedAccess"
|
||||||
|
defaultMessage="Inherited access from"
|
||||||
|
/>
|
||||||
<Link
|
<Link
|
||||||
id={"inherited-access-user-link-" + user.id}
|
id={"inherited-access-user-link-" + user.id}
|
||||||
to={
|
to={
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Dialog, DialogContent, DialogTitle, IconButton } from "@mui/material";
|
import { Dialog, DialogContent, DialogTitle, IconButton } from "@mui/material";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import axiosConfig from "../../config/axiosConfig";
|
import axiosConfig from "../../config/axiosConfig";
|
||||||
import { I_Folder } from "../../util/types";
|
import { I_Folder } from "../../util/types";
|
||||||
import FolderForm from "./FolderForm";
|
import FolderForm from "./FolderForm";
|
||||||
|
@ -13,6 +13,7 @@ interface AddNewDialogProps {
|
||||||
|
|
||||||
const AddNewDialog = (props: AddNewDialogProps) => {
|
const AddNewDialog = (props: AddNewDialogProps) => {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const handleSubmit = (data: I_Folder, childData: Partial<I_Folder>) => {
|
const handleSubmit = (data: I_Folder, childData: Partial<I_Folder>) => {
|
||||||
return axiosConfig
|
return axiosConfig
|
||||||
|
@ -49,13 +50,19 @@ const AddNewDialog = (props: AddNewDialogProps) => {
|
||||||
maxWidth="sm"
|
maxWidth="sm"
|
||||||
>
|
>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
Create new folder
|
<FormattedMessage
|
||||||
|
id="createNewFolder"
|
||||||
|
defaultMessage="Create new folder"
|
||||||
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
id={"add-new-child-dialog-icon-button-" + props.values.id}
|
id={"add-new-child-dialog-icon-button-" + props.values.id}
|
||||||
edge="start"
|
edge="start"
|
||||||
color="inherit"
|
color="inherit"
|
||||||
onClick={() => setOpen(false)}
|
onClick={() => setOpen(false)}
|
||||||
aria-label="close"
|
aria-label={intl.formatMessage({
|
||||||
|
id: "addNewDialogButton",
|
||||||
|
defaultMessage: "Add new dialog button",
|
||||||
|
})}
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
right: 8,
|
right: 8,
|
||||||
|
|
|
@ -24,7 +24,10 @@ const GroupTabs = () => {
|
||||||
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
|
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
|
||||||
<AntTabs
|
<AntTabs
|
||||||
value={routeMatch?.pattern?.path}
|
value={routeMatch?.pattern?.path}
|
||||||
aria-label="basic tabs example"
|
aria-label={intl.formatMessage({
|
||||||
|
id: "groupTabs",
|
||||||
|
defaultMessage: "Group tabs",
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
{currentType === "Folder" ? (
|
{currentType === "Folder" ? (
|
||||||
<StyledTab
|
<StyledTab
|
||||||
|
|
|
@ -9,11 +9,13 @@ import routes from "../../../routes.json";
|
||||||
import { GroupContext } from "../../Context/GroupContextProvider";
|
import { GroupContext } from "../../Context/GroupContextProvider";
|
||||||
import { instanceOfFolder } from "../../../util/group.util";
|
import { instanceOfFolder } from "../../../util/group.util";
|
||||||
import { Grid, CircularProgress } from "@mui/material";
|
import { Grid, CircularProgress } from "@mui/material";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
const GroupTree = () => {
|
const GroupTree = () => {
|
||||||
const { setCurrentType, fetchData, data, loading } = useContext(GroupContext);
|
const { setCurrentType, fetchData, data, loading } = useContext(GroupContext);
|
||||||
const [openNodes, setOpenNodes] = useState<string[]>([]);
|
const [openNodes, setOpenNodes] = useState<string[]>([]);
|
||||||
const [selected, setSelected] = useState<string>("");
|
const [selected, setSelected] = useState<string>("");
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData();
|
fetchData();
|
||||||
|
@ -69,7 +71,10 @@ const GroupTree = () => {
|
||||||
if (data) {
|
if (data) {
|
||||||
return (
|
return (
|
||||||
<TreeView
|
<TreeView
|
||||||
aria-label="rich object"
|
aria-label={intl.formatMessage({
|
||||||
|
id: "groupTree",
|
||||||
|
defaultMessage: "Group tree",
|
||||||
|
})}
|
||||||
defaultCollapseIcon={<ExpandMoreIcon />}
|
defaultCollapseIcon={<ExpandMoreIcon />}
|
||||||
defaultExpandIcon={<ChevronRightIcon />}
|
defaultExpandIcon={<ChevronRightIcon />}
|
||||||
sx={{
|
sx={{
|
||||||
|
|
|
@ -56,7 +56,9 @@ const MoveDialog = (props: MoveDialogProps) => {
|
||||||
}}
|
}}
|
||||||
scroll="paper"
|
scroll="paper"
|
||||||
>
|
>
|
||||||
<DialogTitle>Move to</DialogTitle>
|
<DialogTitle>
|
||||||
|
<FormattedMessage id="moveTo" defaultMessage="Move to" />
|
||||||
|
</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MoveTree
|
<MoveTree
|
||||||
parentId={selectedParentId}
|
parentId={selectedParentId}
|
||||||
|
@ -68,7 +70,7 @@ const MoveDialog = (props: MoveDialogProps) => {
|
||||||
id={"move-dialog-move-button-" + id}
|
id={"move-dialog-move-button-" + id}
|
||||||
onClick={handleMove}
|
onClick={handleMove}
|
||||||
>
|
>
|
||||||
Move
|
<FormattedMessage id="move" defaultMessage="Move" />
|
||||||
</InnovenergyButton>
|
</InnovenergyButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { TreeItem } from "@mui/lab";
|
||||||
import { I_Folder, I_Installation } from "../../../util/types";
|
import { I_Folder, I_Installation } from "../../../util/types";
|
||||||
import { GroupContext } from "../../Context/GroupContextProvider";
|
import { GroupContext } from "../../Context/GroupContextProvider";
|
||||||
import { instanceOfFolder } from "../../../util/group.util";
|
import { instanceOfFolder } from "../../../util/group.util";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
interface MoveTreeProps {
|
interface MoveTreeProps {
|
||||||
setSelectedParentId: (value: number) => void;
|
setSelectedParentId: (value: number) => void;
|
||||||
|
@ -14,6 +15,7 @@ interface MoveTreeProps {
|
||||||
|
|
||||||
const MoveTree = (props: MoveTreeProps) => {
|
const MoveTree = (props: MoveTreeProps) => {
|
||||||
const { data } = useContext(GroupContext);
|
const { data } = useContext(GroupContext);
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const getNodes = (element: I_Folder | I_Installation): null | ReactNode => {
|
const getNodes = (element: I_Folder | I_Installation): null | ReactNode => {
|
||||||
if (instanceOfFolder(element)) {
|
if (instanceOfFolder(element)) {
|
||||||
|
@ -42,7 +44,10 @@ const MoveTree = (props: MoveTreeProps) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
return (
|
return (
|
||||||
<TreeView
|
<TreeView
|
||||||
aria-label="rich object"
|
aria-label={intl.formatMessage({
|
||||||
|
id: "moveTree",
|
||||||
|
defaultMessage: "Move tree",
|
||||||
|
})}
|
||||||
defaultCollapseIcon={<ExpandMoreIcon />}
|
defaultCollapseIcon={<ExpandMoreIcon />}
|
||||||
defaultExpandIcon={<ChevronRightIcon />}
|
defaultExpandIcon={<ChevronRightIcon />}
|
||||||
sx={{
|
sx={{
|
||||||
|
|
|
@ -12,6 +12,7 @@ const InnovenergySnackbar = (props: InnovenergySnackbarProps) => {
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Snackbar
|
<Snackbar
|
||||||
open={open}
|
open={open}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
const Alarms = () => {
|
const Alarms = () => {
|
||||||
return <div>alarms</div>;
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage id="alarms" defaultMessage="Alarms" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Alarms;
|
export default Alarms;
|
||||||
|
|
|
@ -22,7 +22,10 @@ const InstallationTabs = () => {
|
||||||
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
|
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
|
||||||
<AntTabs
|
<AntTabs
|
||||||
value={routeMatch?.pattern?.path ?? routes.installation + ":id"}
|
value={routeMatch?.pattern?.path ?? routes.installation + ":id"}
|
||||||
aria-label="installation tabs"
|
aria-label={intl.formatMessage({
|
||||||
|
id: "installationTabs",
|
||||||
|
defaultMessage: "Installation tabs",
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
<StyledTab
|
<StyledTab
|
||||||
id={"installation-tab-installation"}
|
id={"installation-tab-installation"}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Button, Dialog, DialogContent, DialogTitle } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import { useState } from "react";
|
|
||||||
import { UnixTime, TimeSpan } from "../../../dataCache/time";
|
import { UnixTime, TimeSpan } from "../../../dataCache/time";
|
||||||
import { createTimes } from "../../../util/graph.util";
|
import { createTimes } from "../../../util/graph.util";
|
||||||
import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers";
|
import {
|
||||||
|
DateTimePicker,
|
||||||
|
DateTimeValidationError,
|
||||||
|
LocalizationProvider,
|
||||||
|
} from "@mui/x-date-pickers";
|
||||||
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import InnovenergyButton from "../../Layout/InnovenergyButton";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
interface DateRangePickerProps {
|
interface DateRangePickerProps {
|
||||||
setRange: (value: Date[]) => void;
|
setRange: (value: Date[]) => void;
|
||||||
|
@ -15,64 +19,87 @@ interface DateRangePickerProps {
|
||||||
}
|
}
|
||||||
const DateRangePicker = (props: DateRangePickerProps) => {
|
const DateRangePicker = (props: DateRangePickerProps) => {
|
||||||
const { setRange, range, getCacheSeries } = props;
|
const { setRange, range, getCacheSeries } = props;
|
||||||
const [open, setOpen] = useState(false);
|
const [fromDateError, setFromDateError] =
|
||||||
|
useState<DateTimeValidationError | null>(null);
|
||||||
|
const [toDateError, setToDateError] =
|
||||||
|
useState<DateTimeValidationError | null>(null);
|
||||||
|
|
||||||
|
const handleChange = (fromDate: Date, toDate: Date) => {
|
||||||
|
setRange([fromDate, toDate]);
|
||||||
|
getCacheSeries(fromDate.getMilliseconds(), toDate.getMilliseconds());
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<InnovenergyButton onClick={() => setOpen(true)}>
|
<div>
|
||||||
Set range
|
<Button
|
||||||
</InnovenergyButton>
|
onClick={() => {
|
||||||
<Dialog open={open} maxWidth="lg" onClose={() => setOpen(false)}>
|
const weekRange = createTimes(
|
||||||
<DialogTitle id="dialog-title">Set range</DialogTitle>
|
UnixTime.now().rangeBefore(TimeSpan.fromDays(7)),
|
||||||
<DialogContent>
|
100
|
||||||
<div>
|
);
|
||||||
<Button
|
setRange([
|
||||||
onClick={() => {
|
weekRange[0].toDate(),
|
||||||
const weekRange = createTimes(
|
weekRange[weekRange.length - 1].toDate(),
|
||||||
UnixTime.now().rangeBefore(TimeSpan.fromDays(7)),
|
]);
|
||||||
100
|
getCacheSeries(
|
||||||
);
|
weekRange[0].ticks,
|
||||||
setRange([
|
weekRange[weekRange.length - 1].ticks
|
||||||
weekRange[0].toDate(),
|
);
|
||||||
weekRange[weekRange.length - 1].toDate(),
|
}}
|
||||||
]);
|
>
|
||||||
getCacheSeries(
|
<FormattedMessage id="lastWeek" defaultMessage="Last week" />
|
||||||
weekRange[0].ticks,
|
</Button>
|
||||||
weekRange[weekRange.length - 1].ticks
|
</div>
|
||||||
);
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||||
}}
|
<DateTimePicker
|
||||||
>
|
disableFuture
|
||||||
Last week
|
maxDateTime={dayjs(range[1])}
|
||||||
</Button>
|
label="From date"
|
||||||
</div>
|
value={dayjs(range[0])}
|
||||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
onChange={(newValue) => {
|
||||||
<DatePicker
|
if (newValue) {
|
||||||
label="From date"
|
handleChange(newValue.toDate(), range[1]);
|
||||||
value={dayjs(range[0])}
|
}
|
||||||
onChange={(newValue) => {
|
}}
|
||||||
if (newValue) {
|
onError={(err) => setFromDateError(err)}
|
||||||
const fromDate = newValue.toDate();
|
slotProps={{
|
||||||
const toDate = range[1];
|
textField: {
|
||||||
setRange([fromDate, toDate]);
|
variant: "outlined",
|
||||||
getCacheSeries(+fromDate, +toDate);
|
error: !!fromDateError,
|
||||||
}
|
helperText: fromDateError
|
||||||
}}
|
? "From date needs to be before to date"
|
||||||
/>
|
: "",
|
||||||
<DatePicker
|
},
|
||||||
label="To date"
|
}}
|
||||||
value={dayjs(range[1])}
|
/>
|
||||||
onChange={(newValue) => {
|
<DateTimePicker
|
||||||
if (newValue) {
|
disableFuture
|
||||||
const fromDate = newValue.toDate();
|
minDateTime={dayjs(range[0])}
|
||||||
const toDate = range[1];
|
label="To date"
|
||||||
setRange([fromDate, toDate]);
|
value={dayjs(range[1])}
|
||||||
getCacheSeries(+fromDate, +toDate);
|
sx={{
|
||||||
}
|
".Mui-disabled": {
|
||||||
}}
|
color: "red",
|
||||||
/>
|
},
|
||||||
</LocalizationProvider>
|
}}
|
||||||
</DialogContent>
|
onError={(err) => setToDateError(err)}
|
||||||
</Dialog>
|
onChange={(newValue) => {
|
||||||
|
if (newValue) {
|
||||||
|
handleChange(range[0], newValue.toDate());
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
slotProps={{
|
||||||
|
textField: {
|
||||||
|
variant: "outlined",
|
||||||
|
error: !!toDateError,
|
||||||
|
helperText: toDateError
|
||||||
|
? "To date needs to be after from date"
|
||||||
|
: "",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
GraphData,
|
GraphData,
|
||||||
createTimes,
|
createTimes,
|
||||||
flattenToggles,
|
flattenToggles,
|
||||||
insertTreeElements,
|
getTreeElements,
|
||||||
isNumeric,
|
isNumeric,
|
||||||
parseCsv,
|
parseCsv,
|
||||||
stringToColor,
|
stringToColor,
|
||||||
|
@ -16,20 +16,20 @@ import { BehaviorSubject, startWith, throttleTime, withLatestFrom } from "rxjs";
|
||||||
import { S3Access } from "../../../dataCache/S3/S3Access";
|
import { S3Access } from "../../../dataCache/S3/S3Access";
|
||||||
import DataCache, { FetchResult } from "../../../dataCache/dataCache";
|
import DataCache, { FetchResult } from "../../../dataCache/dataCache";
|
||||||
import { LogContext } from "../../Context/LogContextProvider";
|
import { LogContext } from "../../Context/LogContextProvider";
|
||||||
import { TreeElement } from "./CheckboxTree";
|
|
||||||
import { isDefined } from "../../../dataCache/utils/maybe";
|
import { isDefined } from "../../../dataCache/utils/maybe";
|
||||||
import { Data, Layout } from "plotly.js";
|
import { Data, Layout } from "plotly.js";
|
||||||
import { Alert, Button, ToggleButton, ToggleButtonGroup } from "@mui/material";
|
import { Alert } from "@mui/material";
|
||||||
import DateRangePicker from "./DateRangePicker";
|
import DateRangePicker from "./DateRangePicker";
|
||||||
import { LocalizationProvider } from "@mui/x-date-pickers";
|
import { LocalizationProvider } from "@mui/x-date-pickers";
|
||||||
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
const NUMBER_OF_NODES = 100;
|
const NUMBER_OF_NODES = 100;
|
||||||
|
|
||||||
const ScalarGraph = () => {
|
const ScalarGraph = () => {
|
||||||
const timeRange = createTimes(
|
const timeRange = createTimes(
|
||||||
UnixTime.now() /* .fromTicks(1682085650) */
|
UnixTime.now() /* .fromTicks(1682085650) */
|
||||||
.earlier(TimeSpan.fromDays(7))
|
.earlier(TimeSpan.fromDays(14))
|
||||||
.rangeBefore(TimeSpan.fromDays(4)),
|
.rangeBefore(TimeSpan.fromDays(4)),
|
||||||
NUMBER_OF_NODES
|
NUMBER_OF_NODES
|
||||||
);
|
);
|
||||||
|
@ -38,6 +38,7 @@ const ScalarGraph = () => {
|
||||||
timeRange[0].toDate(),
|
timeRange[0].toDate(),
|
||||||
timeRange[timeRange.length - 1].toDate(),
|
timeRange[timeRange.length - 1].toDate(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const [uiRevision, setUiRevision] = useState(Math.random());
|
const [uiRevision, setUiRevision] = useState(Math.random());
|
||||||
const [plotTitles, setPlotTitles] = useState<string[]>([]);
|
const [plotTitles, setPlotTitles] = useState<string[]>([]);
|
||||||
|
|
||||||
|
@ -67,22 +68,11 @@ const ScalarGraph = () => {
|
||||||
setTimeSeries(timeSeries);
|
setTimeSeries(timeSeries);
|
||||||
const toggleValues = timeSeries.find((timeStamp) => timeStamp.value);
|
const toggleValues = timeSeries.find((timeStamp) => timeStamp.value);
|
||||||
if (toggles === null && toggleValues && toggleValues.value) {
|
if (toggles === null && toggleValues && toggleValues.value) {
|
||||||
const treeElements = Object.keys(toggleValues.value)
|
const treeElements = getTreeElements(toggleValues.value);
|
||||||
.map((path) =>
|
|
||||||
path
|
|
||||||
.split("/")
|
|
||||||
.map((_, i, arr) => `/${arr.slice(1, i + 1).join("/")}`)
|
|
||||||
.slice(1)
|
|
||||||
)
|
|
||||||
.reduce(
|
|
||||||
(children, path) => insertTreeElements(children, path),
|
|
||||||
[] as TreeElement[]
|
|
||||||
);
|
|
||||||
setToggles(treeElements);
|
setToggles(treeElements);
|
||||||
setCheckedToggles(flattenToggles(treeElements));
|
setCheckedToggles(flattenToggles(treeElements));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => subscription.unsubscribe();
|
return () => subscription.unsubscribe();
|
||||||
}, [toggles]);
|
}, [toggles]);
|
||||||
|
|
||||||
|
@ -199,7 +189,6 @@ const ScalarGraph = () => {
|
||||||
barnorm: "percent",
|
barnorm: "percent",
|
||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Plot
|
<Plot
|
||||||
key={path}
|
key={path}
|
||||||
|
@ -228,19 +217,15 @@ const ScalarGraph = () => {
|
||||||
],
|
],
|
||||||
}}
|
}}
|
||||||
onRelayout={(params) => {
|
onRelayout={(params) => {
|
||||||
console.log("relayout");
|
|
||||||
const xaxisRange0 = params["xaxis.range[0]"];
|
const xaxisRange0 = params["xaxis.range[0]"];
|
||||||
const xaxisRange1 = params["xaxis.range[1]"];
|
const xaxisRange1 = params["xaxis.range[1]"];
|
||||||
|
|
||||||
if (xaxisRange0 && xaxisRange1) {
|
if (xaxisRange0 && xaxisRange1) {
|
||||||
setRange([new Date(xaxisRange0), new Date(xaxisRange1)]);
|
setRange([new Date(xaxisRange0), new Date(xaxisRange1)]);
|
||||||
setUiRevision(Math.random());
|
setUiRevision(Math.random());
|
||||||
console.log("ranges", xaxisRange0);
|
|
||||||
getCacheSeries(xaxisRange0, xaxisRange1);
|
getCacheSeries(xaxisRange0, xaxisRange1);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onRestyle={() => "event restyle"}
|
|
||||||
onRedraw={() => "event restyle"}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -249,7 +234,10 @@ const ScalarGraph = () => {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Alert sx={{ mt: 2 }} severity="info">
|
<Alert sx={{ mt: 2 }} severity="info">
|
||||||
Please make a selection on the left
|
<FormattedMessage
|
||||||
|
id="makeASelection"
|
||||||
|
defaultMessage="Please make a selection on the left"
|
||||||
|
/>
|
||||||
</Alert>
|
</Alert>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import useRouteMatch from "../../hooks/useRouteMatch";
|
import useRouteMatch from "../../hooks/useRouteMatch";
|
||||||
import routes from "../../routes.json";
|
import routes from "../../routes.json";
|
||||||
|
@ -9,6 +9,7 @@ const NavigationButtons = () => {
|
||||||
routes.installations + "*",
|
routes.installations + "*",
|
||||||
routes.users + "*",
|
routes.users + "*",
|
||||||
]);
|
]);
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -37,7 +38,10 @@ const NavigationButtons = () => {
|
||||||
<AntTabs
|
<AntTabs
|
||||||
id="navigation-buttons-group"
|
id="navigation-buttons-group"
|
||||||
value={routeMatch?.pattern?.path}
|
value={routeMatch?.pattern?.path}
|
||||||
aria-label="basic tabs example"
|
aria-label={intl.formatMessage({
|
||||||
|
id: "navigationTabs",
|
||||||
|
defaultMessage: "Navigation tabs",
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
<StyledTab
|
<StyledTab
|
||||||
id="navigation-tab-installations"
|
id="navigation-tab-installations"
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
import * as React from "react";
|
|
||||||
import Table from "@mui/material/Table";
|
|
||||||
import TableBody from "@mui/material/TableBody";
|
|
||||||
import TableCell from "@mui/material/TableCell";
|
|
||||||
import TableContainer from "@mui/material/TableContainer";
|
|
||||||
import TableHead from "@mui/material/TableHead";
|
|
||||||
import TableRow from "@mui/material/TableRow";
|
|
||||||
import Paper from "@mui/material/Paper";
|
|
||||||
|
|
||||||
const rows = [
|
|
||||||
{
|
|
||||||
device: "48TL200",
|
|
||||||
code: "MSWE",
|
|
||||||
message: "Main switch error",
|
|
||||||
severity: "Alarm",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
device: "48TL200",
|
|
||||||
code: "MSWE",
|
|
||||||
message: "Main switch error",
|
|
||||||
severity: "Alarm",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
device: "48TL200",
|
|
||||||
code: "MSWE",
|
|
||||||
message: "Main switch error",
|
|
||||||
severity: "Alarm",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
device: "48TL200",
|
|
||||||
code: "MSWE",
|
|
||||||
message: "Main switch error",
|
|
||||||
severity: "Alarm",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const BasicTable = () => {
|
|
||||||
return (
|
|
||||||
<TableContainer component={Paper}>
|
|
||||||
{/* <Table aria-label="simple table">
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell>Device</TableCell>
|
|
||||||
<TableCell>Code</TableCell>
|
|
||||||
<TableCell>Message</TableCell>
|
|
||||||
<TableCell>Severity</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{rows.map((row, i) => (
|
|
||||||
<TableRow
|
|
||||||
key={i}
|
|
||||||
>
|
|
||||||
<TableCell>{row.device}</TableCell>
|
|
||||||
<TableCell>{row.code}</TableCell>
|
|
||||||
<TableCell>{row.message}</TableCell>
|
|
||||||
<TableCell>{row.severity}</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table> */}
|
|
||||||
</TableContainer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default BasicTable;
|
|
|
@ -1,5 +1,4 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import Box from "@mui/material/Box";
|
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import routes from "../../routes.json";
|
import routes from "../../routes.json";
|
||||||
import useRouteMatch from "../../hooks/useRouteMatch";
|
import useRouteMatch from "../../hooks/useRouteMatch";
|
||||||
|
|
|
@ -18,5 +18,33 @@
|
||||||
"groups": "Groups",
|
"groups": "Groups",
|
||||||
"group": "Group",
|
"group": "Group",
|
||||||
"folder": "Folder",
|
"folder": "Folder",
|
||||||
"updateFolderErrorMessage": "Couldn't update folder, an error occured"
|
"updateFolderErrorMessage": "Couldn't update folder, an error occured",
|
||||||
|
"Information": "Information",
|
||||||
|
"addNewChild": "Add new child",
|
||||||
|
"addNewDialogButton": "Add new dialog button",
|
||||||
|
"addUser": "Create user",
|
||||||
|
"createNewFolder": "Create new folder",
|
||||||
|
"createNewUser": "Create new user",
|
||||||
|
"email": "Email",
|
||||||
|
"error": "",
|
||||||
|
"groupTabs": "Group tabs",
|
||||||
|
"groupTree": "Group tree",
|
||||||
|
"information": "Information",
|
||||||
|
"inheritedAccess": "Inherited access from",
|
||||||
|
"installationTabs": "Installation tabs",
|
||||||
|
"installations": "Installations",
|
||||||
|
"lastWeek": "Last week",
|
||||||
|
"makeASelection": "Please make a selection on the left",
|
||||||
|
"manageAccess": "Manage access",
|
||||||
|
"move": "Move",
|
||||||
|
"moveTo": "Move to",
|
||||||
|
"moveTree": "Move tree",
|
||||||
|
"name": "Name",
|
||||||
|
"navigationTabs": "Navigation tabs",
|
||||||
|
"requiredLocation": "Location is required",
|
||||||
|
"requiredName": "Name is required",
|
||||||
|
"requiredRegion": "Region is required",
|
||||||
|
"submit": "Submit",
|
||||||
|
"user": "User",
|
||||||
|
"userTabs": "user tabs"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue