|
|
|
|
import React, { useState, useEffect, useContext } from "react";
|
|
|
|
|
import { useApolloClient } from "@apollo/client";
|
|
|
|
|
import { msgToColor } from "../../utils/indi";
|
|
|
|
|
import Property from "./property";
|
|
|
|
|
import gql from "graphql-tag";
|
|
|
|
|
import {
|
|
|
|
|
Box,
|
|
|
|
|
Button,
|
|
|
|
|
Tabs,
|
|
|
|
|
Tab,
|
|
|
|
|
Text,
|
|
|
|
|
Layer,
|
|
|
|
|
ResponsiveContext,
|
|
|
|
|
} from "grommet";
|
|
|
|
|
import { Close, Trash } from "grommet-icons";
|
|
|
|
|
|
|
|
|
|
const MSGS_FRAGMENT = gql`
|
|
|
|
|
fragment DeviceMsgs on Device {
|
|
|
|
|
messages
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const Device = ({ device, messages, onMessagesClosed }) => {
|
|
|
|
|
const client = useApolloClient();
|
|
|
|
|
const [groups, setGroups] = useState([]);
|
|
|
|
|
const [selectedTabs, setSelectedTabs] = useState({});
|
|
|
|
|
const [currentTab, setCurrentTab] = useState(0);
|
|
|
|
|
const size = useContext(ResponsiveContext);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const groups = new Set();
|
|
|
|
|
device.properties.forEach((v) => {
|
|
|
|
|
groups.add(v.vector.group);
|
|
|
|
|
});
|
|
|
|
|
setGroups(Array.from(groups));
|
|
|
|
|
setCurrentTab(selectedTabs[device.id] || 0);
|
|
|
|
|
}, [device, selectedTabs]);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Box>
|
|
|
|
|
<Tabs
|
|
|
|
|
justify="start"
|
|
|
|
|
activeIndex={currentTab}
|
|
|
|
|
onActive={(nextTab) => {
|
|
|
|
|
setCurrentTab(nextTab);
|
|
|
|
|
const newValue = { ...selectedTabs };
|
|
|
|
|
newValue[device.id] = nextTab;
|
|
|
|
|
setSelectedTabs(newValue);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{groups.map((g) => (
|
|
|
|
|
<Tab title={g} key={g}>
|
|
|
|
|
<Box pad="small">
|
|
|
|
|
{device.properties &&
|
|
|
|
|
device.properties
|
|
|
|
|
.filter((p) => p.vector.group === g)
|
|
|
|
|
.map((p) => <Property property={p} key={p.id} />)}
|
|
|
|
|
</Box>
|
|
|
|
|
</Tab>
|
|
|
|
|
))}
|
|
|
|
|
</Tabs>
|
|
|
|
|
|
|
|
|
|
{messages ? (
|
|
|
|
|
<Layer position="right" full="vertical" modal={false}>
|
|
|
|
|
<Box
|
|
|
|
|
background={{ color: "light-1", opacity: "strong" }}
|
|
|
|
|
fill="vertical"
|
|
|
|
|
align="start"
|
|
|
|
|
width={size}
|
|
|
|
|
>
|
|
|
|
|
<Box direction="row" justify="end" fill="horizontal">
|
|
|
|
|
<Button
|
|
|
|
|
icon={<Trash />}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
client.writeFragment({
|
|
|
|
|
id: client.cache.config.dataIdFromObject(device),
|
|
|
|
|
fragment: MSGS_FRAGMENT,
|
|
|
|
|
data: {
|
|
|
|
|
__typename: "Device",
|
|
|
|
|
messages: [],
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Button icon={<Close />} onClick={() => onMessagesClosed()} />
|
|
|
|
|
</Box>
|
|
|
|
|
<Box pad="medium">
|
|
|
|
|
{device.messages.map((msg) => (
|
|
|
|
|
<Text color={msgToColor(msg)}>{msg}</Text>
|
|
|
|
|
))}
|
|
|
|
|
</Box>
|
|
|
|
|
</Box>
|
|
|
|
|
</Layer>
|
|
|
|
|
) : null}
|
|
|
|
|
</Box>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default Device;
|