alert level has a complete form
+ alert level now has entry for country and volcano name + widget now has a submit button + now has a refresh button that only appears when something is submitted + adjusted number of columns in grid layout + other small sizing adjustments in canvas
This commit is contained in:
@@ -1,18 +1,8 @@
|
|||||||
import { IoIosArrowBack } from "react-icons/io";
|
import { IoIosArrowBack } from "react-icons/io";
|
||||||
import { Menu, Portal } from "@chakra-ui/react";
|
import { Menu, Portal } from "@chakra-ui/react";
|
||||||
import { v4 as uuid } from 'uuid';
|
|
||||||
import AlertLevel from "./AlertLevelWidget";
|
import AlertLevel from "./AlertLevelWidget";
|
||||||
|
|
||||||
export default function AddWidgetMenu({onAddWidget, widgetArray, setWidgetArray}) {
|
export default function AddWidgetMenu({appendWidget}) {
|
||||||
function appendWidget(name) {
|
|
||||||
const newID = uuid(); // could be replaced with something else like guid
|
|
||||||
setWidgetArray([ // updating widget array containing info on the types of widgets
|
|
||||||
...widgetArray,
|
|
||||||
{i: newID, widget: name}
|
|
||||||
]);
|
|
||||||
onAddWidget(newID); // updating array containing info on layout of widgets
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu.Root>
|
<Menu.Root>
|
||||||
<Menu.TriggerItem>
|
<Menu.TriggerItem>
|
||||||
@@ -23,10 +13,22 @@ export default function AddWidgetMenu({onAddWidget, widgetArray, setWidgetArray}
|
|||||||
<Menu.Content>
|
<Menu.Content>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
value="AlertLevel"
|
value="AlertLevel"
|
||||||
onClick={() => appendWidget(AlertLevel)}
|
onClick={() => appendWidget(AlertLevel, 3, 6, 3, 6, 3, 6)} // width and height are passed through here for each widget
|
||||||
>
|
>
|
||||||
Alert Level
|
Alert Level
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
CO2
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
IVANS
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
Plume Heights
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
Alert Level Changes
|
||||||
|
</Menu.Item>
|
||||||
</Menu.Content>
|
</Menu.Content>
|
||||||
</Menu.Positioner>
|
</Menu.Positioner>
|
||||||
</Portal>
|
</Portal>
|
||||||
|
|||||||
@@ -1,27 +1,65 @@
|
|||||||
import Widget from "./Widget";
|
import Widget from "./Widget";
|
||||||
import { HStack, Box, Field, Input, Button } from "@chakra-ui/react";
|
import { Stack, Box, Field, Input, Button, Text } from "@chakra-ui/react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
export default function AlertLevel({id, isEditable, isDelete, DeleteWidget}) {
|
export default function AlertLevel({id, isEditable, isDelete, DeleteWidget}) {
|
||||||
const { register, handleSubmit } = useForm();
|
const { register, handleSubmit } = useForm();
|
||||||
const onSubmit = (data) => console.log(data);
|
const onSubmit = (data) => {
|
||||||
|
console.log(data);
|
||||||
|
setIsSubmit(true);
|
||||||
|
}
|
||||||
|
const [isSubmit, setIsSubmit] = useState(false);
|
||||||
|
|
||||||
|
// Prop Forwarding
|
||||||
|
const widgetProps = { id, isEditable, isDelete, DeleteWidget, isSubmit, setIsSubmit }
|
||||||
return (
|
return (
|
||||||
<Widget id={id} title="Alert Level" isEditable={isEditable} isDelete={isDelete} DeleteWidget={DeleteWidget}>
|
<Widget title="Alert Level" {...widgetProps}>
|
||||||
<Box
|
{!isSubmit ? (
|
||||||
as="form"
|
<Box
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
as="form"
|
||||||
width="100%"
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
height="100%"
|
width="100%"
|
||||||
p={2}
|
height="100%"
|
||||||
>
|
pt={1}
|
||||||
<Field.Root orientation="horizontal" >
|
pl={3}
|
||||||
<HStack display="flex" spacing={4} align="center" width="100%">
|
pr={3}
|
||||||
<Field.Label display="flex" whiteSpace="nowrap">Country Name</Field.Label>
|
display="flex"
|
||||||
<Input {...register("countryname")} placeholder="Enter country name"/>
|
flexDir="column"
|
||||||
</HStack>
|
gap="3"
|
||||||
</Field.Root>
|
>
|
||||||
</Box>
|
<Field.Root orientation="horizontal" >
|
||||||
|
<Stack direction="column" gap="3" width="100%">
|
||||||
|
<Stack direction="row" display="flex" flexShrink={1} spacing={4} align="center" width="100%">
|
||||||
|
<Field.Label whiteSpace="nowrap" fontWeight="bold">Country Name</Field.Label>
|
||||||
|
<Input {...register("countryname")} placeholder="Enter country name"/>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction="row" display="flex" spacing={4} align="center" width="100%">
|
||||||
|
<Field.Label display="flex" whiteSpace="nowrap" fontWeight="bold">Volcano Name</Field.Label>
|
||||||
|
<Input {...register("countryname")} placeholder="Enter volcano name"/>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Field.Root>
|
||||||
|
<Button type="submit" size="sm" onClick={() => setIsSubmit(true)}>Submit</Button>
|
||||||
|
</Box>
|
||||||
|
):(
|
||||||
|
<Box p={1} mt={1} ml="auto" mr="auto" width="200px">
|
||||||
|
<Box
|
||||||
|
bg="bg"
|
||||||
|
shadow="md"
|
||||||
|
borderRadius="md"
|
||||||
|
p={8}
|
||||||
|
width="200px"
|
||||||
|
height="10px"
|
||||||
|
textAlign="center"
|
||||||
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
>
|
||||||
|
<Text fontsize="2xl" fontWeight="bold" color="gray.700">Alert Level Data Coming Soon.</Text>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Widget>
|
</Widget>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,8 @@ import { IconButton, Menu, Portal } from "@chakra-ui/react";
|
|||||||
import { FiSettings } from "react-icons/fi";
|
import { FiSettings } from "react-icons/fi";
|
||||||
import AddWidgetMenu from "./AddWidgetMenu";
|
import AddWidgetMenu from "./AddWidgetMenu";
|
||||||
|
|
||||||
export function SettingsButton({onAddWidget, onEditWidgets, onDeleteWidgets, widgetArray, setWidgetArray}) {
|
export function SettingsButton({ onEditWidgets, onDeleteWidgets, appendWidget}) {
|
||||||
|
const addWidgetMenuProps = { appendWidget }
|
||||||
return (
|
return (
|
||||||
<Menu.Root>
|
<Menu.Root>
|
||||||
<Menu.Trigger asChild >
|
<Menu.Trigger asChild >
|
||||||
@@ -13,7 +14,7 @@ export function SettingsButton({onAddWidget, onEditWidgets, onDeleteWidgets, wid
|
|||||||
<Portal>
|
<Portal>
|
||||||
<Menu.Positioner>
|
<Menu.Positioner>
|
||||||
<Menu.Content>
|
<Menu.Content>
|
||||||
<AddWidgetMenu onAddWidget={onAddWidget} setWidgetArray={setWidgetArray} widgetArray={widgetArray}/>
|
<AddWidgetMenu {...addWidgetMenuProps}/>
|
||||||
<Menu.Item onClick={onEditWidgets} value ="editwidget">Edit Widgets</Menu.Item>
|
<Menu.Item onClick={onEditWidgets} value ="editwidget">Edit Widgets</Menu.Item>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
onClick={onDeleteWidgets}
|
onClick={onDeleteWidgets}
|
||||||
@@ -27,9 +28,4 @@ export function SettingsButton({onAddWidget, onEditWidgets, onDeleteWidgets, wid
|
|||||||
</Portal>
|
</Portal>
|
||||||
</Menu.Root>
|
</Menu.Root>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
import { useSlotRecipe, chakra, Flex, CloseButton, Text, IconButton } from "@chakra-ui/react"
|
import { useSlotRecipe, chakra, Flex, CloseButton, Text, IconButton } from "@chakra-ui/react"
|
||||||
import { FaEllipsisH } from "react-icons/fa";
|
import { GrUndo } from "react-icons/gr";
|
||||||
|
|
||||||
export default function Widget({ id, title, isEditable, isDelete, DeleteWidget, children }) {
|
export default function Widget(props) {
|
||||||
|
// deconstructing props
|
||||||
|
const { id, title, isEditable, isDelete, DeleteWidget, isSubmit, setIsSubmit, children } = props;
|
||||||
const recipe = useSlotRecipe({ key: "widget" });
|
const recipe = useSlotRecipe({ key: "widget" });
|
||||||
const styles = recipe();
|
const styles = recipe();
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<chakra.div css={styles.header} cursor={isEditable ? "move":"default"}>
|
<chakra.div css={styles.header} cursor={isEditable ? "move":"default"}>
|
||||||
@@ -19,12 +22,14 @@ export default function Widget({ id, title, isEditable, isDelete, DeleteWidget,
|
|||||||
<>
|
<>
|
||||||
<Flex flexDirection="row" justifyContent="space-between" alignItems="center">
|
<Flex flexDirection="row" justifyContent="space-between" alignItems="center">
|
||||||
<Text className="widget-handle" w="100%" display="flex" alignItems="center" height="32px" fontWeight="bold">{title}</Text>
|
<Text className="widget-handle" w="100%" display="flex" alignItems="center" height="32px" fontWeight="bold">{title}</Text>
|
||||||
<IconButton size="xs" bg="base300" cursor="pointer"><FaEllipsisH fill="text"/></IconButton>
|
{isSubmit ? (
|
||||||
|
<IconButton onClick={() => setIsSubmit(false)} size="xs" bg="base300" cursor="pointer"><GrUndo fill="text" /></IconButton>
|
||||||
|
):(null)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</chakra.div>
|
</chakra.div>
|
||||||
<chakra.div height="100%" mb="3">
|
<chakra.div height="100%" mb="2">
|
||||||
{children}
|
{children}
|
||||||
</chakra.div>
|
</chakra.div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -9,23 +9,27 @@ import { RemoteSensing } from "./HomeTabs/RemoteSensing";
|
|||||||
import { CancelButton } from "../CanvasComponents/CancelButton";
|
import { CancelButton } from "../CanvasComponents/CancelButton";
|
||||||
import { SaveButton } from "../CanvasComponents/SaveButton";
|
import { SaveButton } from "../CanvasComponents/SaveButton";
|
||||||
import DeleteAllButton from "../CanvasComponents/DeleteAllButton";
|
import DeleteAllButton from "../CanvasComponents/DeleteAllButton";
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
|
|
||||||
export default function Home({...props}) {
|
export default function Home({...props}) {
|
||||||
// deconstructing props
|
// deconstructing props
|
||||||
const { view, layout, setLayout, setOriginalLayout, onLayoutChange, onChangeView, onCancel,
|
const { view, layout, setLayout, setOriginalLayout, onLayoutChange, onChangeView, onCancel,
|
||||||
isDelete, setIsDelete, isEditable, setIsEditable, widgetArray, setWidgetArray } = props;
|
isDelete, setIsDelete, isEditable, setIsEditable, widgetArray, setWidgetArray } = props;
|
||||||
|
|
||||||
const onAddWidget = (ID) => {
|
const onAddWidget = (ID, w, h, minw, minh, maxw, maxh) => {
|
||||||
setLayout(prev => [
|
setLayout(prev => [
|
||||||
...prev,
|
...prev,
|
||||||
{
|
{
|
||||||
i: ID,
|
i: ID,
|
||||||
x: (prev.length * 3) % 12,
|
x: (prev.length * 3) % 12,
|
||||||
y: Infinity,
|
y: Infinity,
|
||||||
w: 2,
|
w: w,
|
||||||
h: 5,
|
h: h,
|
||||||
minW: 2,
|
minW: minw,
|
||||||
minH: 5,
|
minH: minh,
|
||||||
|
maxW: maxw,
|
||||||
|
maxH: maxh,
|
||||||
static: false,
|
static: false,
|
||||||
resizeHandles: ['se']
|
resizeHandles: ['se']
|
||||||
}
|
}
|
||||||
@@ -33,6 +37,15 @@ export default function Home({...props}) {
|
|||||||
onEditWidgets();
|
onEditWidgets();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function appendWidget(name, w, h, minw, minh, maxw, maxh) {
|
||||||
|
const newID = uuid(); // could be replaced with something else like guid
|
||||||
|
setWidgetArray([ // updating widget array containing info on the types of widgets
|
||||||
|
...widgetArray,
|
||||||
|
{i: newID, widget: name }
|
||||||
|
]);
|
||||||
|
onAddWidget(newID, w, h, minw, minh, maxw, maxh); // updating array containing info on layout of widgets
|
||||||
|
}
|
||||||
|
|
||||||
const onEditWidgets = () => {
|
const onEditWidgets = () => {
|
||||||
console.log("widgets are now editable");
|
console.log("widgets are now editable");
|
||||||
setOriginalLayout(layout); // Backup layout before editing
|
setOriginalLayout(layout); // Backup layout before editing
|
||||||
@@ -87,7 +100,7 @@ export default function Home({...props}) {
|
|||||||
|
|
||||||
// Prop Forwarding
|
// Prop Forwarding
|
||||||
const MyDashboardProps = { layout, onLayoutChange, isEditable, isDelete, DeleteWidget, widgetArray };
|
const MyDashboardProps = { layout, onLayoutChange, isEditable, isDelete, DeleteWidget, widgetArray };
|
||||||
const settingsButtonProps = { onAddWidget, onEditWidgets, onDeleteWidgets, setWidgetArray, widgetArray };
|
const settingsButtonProps = { onEditWidgets, onDeleteWidgets, appendWidget };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
/* HEADER */
|
/* HEADER */
|
||||||
@@ -109,7 +122,7 @@ export default function Home({...props}) {
|
|||||||
top="0"
|
top="0"
|
||||||
zIndex="dropdown" // zIndex: 1100
|
zIndex="dropdown" // zIndex: 1100
|
||||||
bg="base200"
|
bg="base200"
|
||||||
px={6}
|
px={5}
|
||||||
pt={3}
|
pt={3}
|
||||||
align="center"
|
align="center"
|
||||||
justify="space-between"
|
justify="space-between"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export default function MyDashboard({layout, onLayoutChange, isEditable, isDelet
|
|||||||
|
|
||||||
console.log("widgetArray: ", widgetArray);
|
console.log("widgetArray: ", widgetArray);
|
||||||
console.log("layout: ", layout);
|
console.log("layout: ", layout);
|
||||||
|
|
||||||
if (widgetArray.length && layout.length) {
|
if (widgetArray.length && layout.length) {
|
||||||
const widgetMap = new Map(widgetArray.map(item => [item.i, item]));
|
const widgetMap = new Map(widgetArray.map(item => [item.i, item]));
|
||||||
merged = layout.map(item => {
|
merged = layout.map(item => {
|
||||||
@@ -29,17 +30,16 @@ export default function MyDashboard({layout, onLayoutChange, isEditable, isDelet
|
|||||||
useCSSTransforms={false} // remove the sliding animation of the widgets
|
useCSSTransforms={false} // remove the sliding animation of the widgets
|
||||||
className="layout"
|
className="layout"
|
||||||
layout={layout}
|
layout={layout}
|
||||||
cols={12} // Total columns in grid
|
cols={16} // Total columns in grid
|
||||||
rowHeight={30} //Height of a single row in px
|
rowHeight={30} // Height of a single row in px
|
||||||
isBounded={true} // Total width of the grid
|
isBounded={true} // Total width of the grid
|
||||||
margin={[10, 10]} // [horizontal, vertical] gap
|
margin={[15, 5]} // [horizontal, vertical] gap
|
||||||
onLayoutChange={onLayoutChange}
|
onLayoutChange={onLayoutChange}
|
||||||
draggableHandle=".widget-handle" // Make only the header draggable
|
draggableHandle=".widget-handle" // Make only the header draggable
|
||||||
onDragStart={handleDragStart}
|
onDragStart={handleDragStart}
|
||||||
onDragStop={handleDragStop}
|
onDragStop={handleDragStop}
|
||||||
position="relative"
|
position="relative"
|
||||||
resizeHandle={<CustomResizeHandle isVisable={isEditable} />}
|
resizeHandle={<CustomResizeHandle isVisable={isEditable} />}
|
||||||
isResizable={isEditable}
|
|
||||||
>
|
>
|
||||||
{merged.map((item) => {
|
{merged.map((item) => {
|
||||||
const Widget = item.widget;
|
const Widget = item.widget;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Header from './Header/Header.jsx';
|
import Header from './Header/Header.jsx';
|
||||||
import Sidebar from './Sidebar/Sidebar.jsx';
|
import Sidebar from './Sidebar/Sidebar.jsx';
|
||||||
import Canvas from './Canvas/Canvas.jsx';
|
import Canvas from './Canvas/Canvas.jsx';
|
||||||
import { Grid, GridItem, useRecipe } from '@chakra-ui/react';
|
import { Grid, GridItem, useRecipe, Dialog } from '@chakra-ui/react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
:root {
|
:root {
|
||||||
font-family: Georgia, 'Times New Roman', Times, serif;
|
font-family: Georgia, 'Times New Roman', Times, serif;
|
||||||
color: #19332D;
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user