You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.7 KiB
102 lines
2.7 KiB
import React, { useState, useEffect, Fragment } from "react"; |
|
import { useMutation, useApolloClient } from "@apollo/react-hooks"; |
|
import { msgToColor } from "../../utils/indi"; |
|
import Property from "./property"; |
|
import gql from "graphql-tag"; |
|
import { Box, Button, Tabs, Tab, Text, Layer } from "grommet"; |
|
import { Close, Trash } from "grommet-icons"; |
|
|
|
const CONNECT_DEVICE = gql` |
|
mutation connectDevice($id: String!) { |
|
connectDevice(id: $id) { |
|
id |
|
} |
|
} |
|
`; |
|
|
|
const MSGS_FRAGMENT = gql` |
|
fragment DeviceMsgs on Device { |
|
messages |
|
} |
|
`; |
|
|
|
const Device = ({ device, messages, onMessagesClosed }) => { |
|
const client = useApolloClient(); |
|
const [connect] = useMutation(CONNECT_DEVICE, { |
|
variables: { id: device.id }, |
|
}); |
|
const [groups, setGroups] = useState([]); |
|
const [selectedTabs, setSelectedTabs] = useState({}); |
|
const [currentTab, setCurrentTab] = useState(0); |
|
|
|
useEffect(() => { |
|
const groups = new Set(); |
|
device.properties.forEach((v) => { |
|
groups.add(v.vector.group); |
|
}); |
|
setGroups(Array.from(groups)); |
|
setCurrentTab(selectedTabs[device.id] || 0); |
|
}, [device]); |
|
|
|
return ( |
|
<Box> |
|
{!device.connected && ( |
|
<Button |
|
label="Connect" |
|
onClick={() => { |
|
connect(); |
|
}} |
|
/> |
|
)} |
|
<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 direction="row"> |
|
<Button icon={<Close />} onClick={() => onMessagesClosed()} /> |
|
<Button |
|
icon={<Trash />} |
|
onClick={() => { |
|
client.writeFragment({ |
|
id: client.cache.config.dataIdFromObject(device), |
|
fragment: MSGS_FRAGMENT, |
|
data: { |
|
__typename: "Device", |
|
messages: [], |
|
}, |
|
}); |
|
}} |
|
/> |
|
</Box> |
|
<Box width="medium" pad="small"> |
|
{device.messages.map((msg) => ( |
|
<Text color={msgToColor(msg)}>{msg}</Text> |
|
))} |
|
</Box> |
|
</Layer> |
|
) : null} |
|
</Box> |
|
); |
|
}; |
|
|
|
export default Device;
|
|
|