Added messages, fixed light property, more
This commit is contained in:
+16
@@ -14,6 +14,12 @@ const theme = deepMerge(grommet, {
|
|||||||
brand: "#ff4e4e",
|
brand: "#ff4e4e",
|
||||||
text: "#336",
|
text: "#336",
|
||||||
},
|
},
|
||||||
|
input: {
|
||||||
|
padding: {
|
||||||
|
horizontal: "small",
|
||||||
|
vertical: "xsmall",
|
||||||
|
},
|
||||||
|
},
|
||||||
focus: {
|
focus: {
|
||||||
border: {
|
border: {
|
||||||
color: "#ff4e4e80",
|
color: "#ff4e4e80",
|
||||||
@@ -28,6 +34,16 @@ const theme = deepMerge(grommet, {
|
|||||||
radius: "4px",
|
radius: "4px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
tabs: {
|
||||||
|
header: {
|
||||||
|
background: "#ccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tab: {
|
||||||
|
margin: {
|
||||||
|
vertical: "xsmall",
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|||||||
@@ -69,6 +69,13 @@ const client = new ApolloClient({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
resolvers: {
|
||||||
|
Device: {
|
||||||
|
messages() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const CONNECTED = gql`
|
const CONNECTED = gql`
|
||||||
@@ -119,6 +126,7 @@ const GETDEVICES = gql`
|
|||||||
devices {
|
devices {
|
||||||
id
|
id
|
||||||
...DeviceInfo
|
...DeviceInfo
|
||||||
|
messages @client
|
||||||
properties {
|
properties {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@@ -136,6 +144,7 @@ const GETDEVICE = gql`
|
|||||||
device(id: $id) {
|
device(id: $id) {
|
||||||
id
|
id
|
||||||
...DeviceInfo
|
...DeviceInfo
|
||||||
|
messages @client
|
||||||
properties {
|
properties {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@@ -155,6 +164,7 @@ client
|
|||||||
.subscribe(({ data }) => {
|
.subscribe(({ data }) => {
|
||||||
const res = client.readQuery({ query: GETDEVICES });
|
const res = client.readQuery({ query: GETDEVICES });
|
||||||
data.newDevice.properties = [];
|
data.newDevice.properties = [];
|
||||||
|
data.newDevice.messages = [];
|
||||||
client.writeQuery({
|
client.writeQuery({
|
||||||
query: GETDEVICES,
|
query: GETDEVICES,
|
||||||
data: { devices: [...res.devices, data.newDevice] },
|
data: { devices: [...res.devices, data.newDevice] },
|
||||||
@@ -239,4 +249,41 @@ client
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const NEW_MESSAGE = gql`
|
||||||
|
subscription newMessage {
|
||||||
|
newMessage {
|
||||||
|
id
|
||||||
|
device {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
client
|
||||||
|
.subscribe({
|
||||||
|
query: NEW_MESSAGE,
|
||||||
|
})
|
||||||
|
.subscribe(({ data }) => {
|
||||||
|
const res = client.readQuery({
|
||||||
|
query: GETDEVICE,
|
||||||
|
variables: { id: data.newMessage.device.id },
|
||||||
|
});
|
||||||
|
const messages = res.device.messages
|
||||||
|
? [data.newMessage.message, ...res.device.messages]
|
||||||
|
: [data.newMessage.message];
|
||||||
|
|
||||||
|
client.writeQuery({
|
||||||
|
query: GETDEVICE,
|
||||||
|
variables: { id: res.device.id },
|
||||||
|
data: {
|
||||||
|
device: {
|
||||||
|
...res.device,
|
||||||
|
messages,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
export default client;
|
export default client;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, Fragment } from "react";
|
||||||
import { useMutation } from "@apollo/react-hooks";
|
import { useMutation, useApolloClient } from "@apollo/react-hooks";
|
||||||
import { driversToInterfaces } from "../../utils/indi";
|
import { msgToColor } from "../../utils/indi";
|
||||||
import Property from "./property";
|
import Property from "./property";
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
import { Box, Button, Tabs, Tab } from "grommet";
|
import { Box, Button, Tabs, Tab, Text, Layer } from "grommet";
|
||||||
|
import { Close, Trash } from "grommet-icons";
|
||||||
|
|
||||||
const CONNECT_DEVICE = gql`
|
const CONNECT_DEVICE = gql`
|
||||||
mutation connectDevice($id: String!) {
|
mutation connectDevice($id: String!) {
|
||||||
@@ -13,7 +14,14 @@ const CONNECT_DEVICE = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Device = ({ device }) => {
|
const MSGS_FRAGMENT = gql`
|
||||||
|
fragment DeviceMsgs on Device {
|
||||||
|
messages
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Device = ({ device, messages, onMessagesClosed }) => {
|
||||||
|
const client = useApolloClient();
|
||||||
const [connect] = useMutation(CONNECT_DEVICE, {
|
const [connect] = useMutation(CONNECT_DEVICE, {
|
||||||
variables: { id: device.id },
|
variables: { id: device.id },
|
||||||
});
|
});
|
||||||
@@ -40,12 +48,16 @@ const Device = ({ device }) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Tabs justify="start" activeIndex={currentTab} onActive={(nextTab) => {
|
<Tabs
|
||||||
setCurrentTab(nextTab);
|
justify="start"
|
||||||
const newValue = { ...selectedTabs };
|
activeIndex={currentTab}
|
||||||
newValue[device.id] = nextTab;
|
onActive={(nextTab) => {
|
||||||
setSelectedTabs(newValue)
|
setCurrentTab(nextTab);
|
||||||
}}>
|
const newValue = { ...selectedTabs };
|
||||||
|
newValue[device.id] = nextTab;
|
||||||
|
setSelectedTabs(newValue);
|
||||||
|
}}
|
||||||
|
>
|
||||||
{groups.map((g) => (
|
{groups.map((g) => (
|
||||||
<Tab title={g} key={g}>
|
<Tab title={g} key={g}>
|
||||||
<Box pad="small">
|
<Box pad="small">
|
||||||
@@ -57,6 +69,32 @@ const Device = ({ device }) => {
|
|||||||
</Tab>
|
</Tab>
|
||||||
))}
|
))}
|
||||||
</Tabs>
|
</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>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { Box, Text } from "grommet";
|
||||||
|
import { StatusGoodSmall } from "grommet-icons";
|
||||||
|
|
||||||
import { stateToEmoji } from "../../utils/indi";
|
import { stateToColor } from "../../utils/indi";
|
||||||
|
|
||||||
const LightVector = ({ vector }) => {
|
const LightVector = ({ vector }) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<Box gap="xsmall">
|
||||||
{vector.values.map(v => (
|
{vector.values.map((v) => (
|
||||||
<div key={v.name}>{stateToEmoji(v.switch)} {v.label || v.name}</div>
|
<Box key={v.name} direction="row" align="center" gap="small">
|
||||||
|
<StatusGoodSmall
|
||||||
|
size="medium"
|
||||||
|
color={stateToColor(v.light)}
|
||||||
|
/>
|
||||||
|
<Box><Text>{v.label || v.name}</Text></Box>
|
||||||
|
</Box>
|
||||||
))}
|
))}
|
||||||
</div>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LightVector;
|
export default LightVector;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Box, TextInput, Button } from "grommet";
|
import { Box, TextInput, Button, Text } from "grommet";
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
import { useMutation } from "@apollo/react-hooks";
|
import { useMutation } from "@apollo/react-hooks";
|
||||||
|
|
||||||
@@ -15,8 +15,12 @@ const NumberValue = ({ vector, value }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box key={value.name} direction="row" align="center">
|
<Box key={value.name} direction="row" align="center">
|
||||||
<Box width="small">{value.label || value.name}</Box>
|
<Box width="small">
|
||||||
<Box width="small">{value.formated || value.number}</Box>
|
<Text>{value.label || value.name}</Text>
|
||||||
|
</Box>
|
||||||
|
<Box width="small">
|
||||||
|
<Text>{value.formated || value.number}</Text>
|
||||||
|
</Box>
|
||||||
{vector.permission !== 0 && (
|
{vector.permission !== 0 && (
|
||||||
<Box direction="row" align="center" gap="xsmall">
|
<Box direction="row" align="center" gap="xsmall">
|
||||||
<TextInput
|
<TextInput
|
||||||
@@ -33,10 +37,8 @@ const NumberValue = ({ vector, value }) => {
|
|||||||
name: value.name,
|
name: value.name,
|
||||||
value: parseFloat(newval),
|
value: parseFloat(newval),
|
||||||
};
|
};
|
||||||
console.log(input);
|
|
||||||
sendOneNumber({ variables: { input } }).then((data) => {
|
sendOneNumber({ variables: { input } });
|
||||||
console.log(data);
|
|
||||||
});
|
|
||||||
}}
|
}}
|
||||||
></Button>
|
></Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Box } from "grommet";
|
import { Box, Text } from "grommet";
|
||||||
import { StatusGoodSmall } from "grommet-icons";
|
import { StatusGoodSmall } from "grommet-icons";
|
||||||
|
|
||||||
import { stateToColor } from "../../utils/indi";
|
import { stateToColor } from "../../utils/indi";
|
||||||
@@ -16,7 +16,7 @@ const Property = ({ property }) => {
|
|||||||
size="medium"
|
size="medium"
|
||||||
color={stateToColor(property.vector.state)}
|
color={stateToColor(property.vector.state)}
|
||||||
/>
|
/>
|
||||||
<strong>{property.vector.label || property.name}</strong>
|
<Text>{property.vector.label || property.name}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
{property.vector.__typename === "NumberVector" && (
|
{property.vector.__typename === "NumberVector" && (
|
||||||
<NumberVector vector={property.vector} />
|
<NumberVector vector={property.vector} />
|
||||||
|
|||||||
@@ -35,14 +35,8 @@ const SwitchVector = ({ vector }) => {
|
|||||||
property: vector.name,
|
property: vector.name,
|
||||||
values: newValues,
|
values: newValues,
|
||||||
};
|
};
|
||||||
console.log(vector.rule);
|
|
||||||
console.log(input);
|
|
||||||
|
|
||||||
sendSwitch({
|
sendSwitch({ variables: { input } });
|
||||||
variables: { input },
|
|
||||||
}).then((data) => {
|
|
||||||
console.log(data);
|
|
||||||
});
|
|
||||||
}}
|
}}
|
||||||
></Button>
|
></Button>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,7 +1,59 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { Box, Button, TextInput } from "grommet";
|
import { Box, Button, TextInput, Text } from "grommet";
|
||||||
|
import gql from "graphql-tag";
|
||||||
|
import { useMutation } from "@apollo/react-hooks";
|
||||||
|
|
||||||
|
const SEND = gql`
|
||||||
|
mutation sendOneText($input: OneTextInput!) {
|
||||||
|
sendOneText(input: $input)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TextValue = ({ vector, value }) => {
|
||||||
|
const [newval, setNewval] = useState(value.text);
|
||||||
|
const [sendOneText] = useMutation(SEND);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box key={value.name} direction="row" align="center">
|
||||||
|
<Box width="small"><Text>{value.label || value.name}</Text></Box>
|
||||||
|
<Box width="small"><Text>{value.text}</Text></Box>
|
||||||
|
{vector.permission !== 0 && (
|
||||||
|
<Box direction="row" align="center" gap="xsmall">
|
||||||
|
<TextInput
|
||||||
|
value={newval}
|
||||||
|
onChange={(e) => setNewval(e.target.value)}
|
||||||
|
></TextInput>
|
||||||
|
<Button
|
||||||
|
primary
|
||||||
|
label="Set"
|
||||||
|
onClick={() => {
|
||||||
|
const input = {
|
||||||
|
device: vector.device,
|
||||||
|
property: vector.name,
|
||||||
|
name: value.name,
|
||||||
|
value: newval,
|
||||||
|
};
|
||||||
|
console.log(input);
|
||||||
|
sendOneText({ variables: { input } });
|
||||||
|
}}
|
||||||
|
></Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const TextVector = ({ vector }) => {
|
const TextVector = ({ vector }) => {
|
||||||
|
return (
|
||||||
|
<Box gap="xsmall">
|
||||||
|
{vector.values.map((v) => (
|
||||||
|
<TextValue key={v.name} vector={vector} value={v} />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*const TextVector = ({ vector }) => {
|
||||||
return (
|
return (
|
||||||
<Box gap="xsmall">
|
<Box gap="xsmall">
|
||||||
{vector.values.map((v) => (
|
{vector.values.map((v) => (
|
||||||
@@ -18,6 +70,6 @@ const TextVector = ({ vector }) => {
|
|||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};*/
|
||||||
|
|
||||||
export default TextVector;
|
export default TextVector;
|
||||||
+16
-12
@@ -4,7 +4,8 @@ import { useQuery, useSubscription, useMutation } from "@apollo/react-hooks";
|
|||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
import { deviceInfoFragment, propertyVectorFragment } from "./graphql/fragment";
|
import { deviceInfoFragment, propertyVectorFragment } from "./graphql/fragment";
|
||||||
import Device from "./components/indi/device";
|
import Device from "./components/indi/device";
|
||||||
import { Box, Tabs, Tab, Button, Header, Heading } from "grommet";
|
import { Box, Tabs, Tab, Button, Header, Heading, Layer } from "grommet";
|
||||||
|
import { Contact } from "grommet-icons";
|
||||||
import { isConnectedQuery } from "./graphql/query";
|
import { isConnectedQuery } from "./graphql/query";
|
||||||
|
|
||||||
const GETDEVICES = gql`
|
const GETDEVICES = gql`
|
||||||
@@ -12,6 +13,7 @@ const GETDEVICES = gql`
|
|||||||
devices {
|
devices {
|
||||||
id
|
id
|
||||||
...DeviceInfo
|
...DeviceInfo
|
||||||
|
messages @client
|
||||||
properties {
|
properties {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@@ -52,6 +54,7 @@ const Devices = () => {
|
|||||||
const { data } = useQuery(GETDEVICES);
|
const { data } = useQuery(GETDEVICES);
|
||||||
const [connect] = useMutation(CONNECT);
|
const [connect] = useMutation(CONNECT);
|
||||||
const [disconnect] = useMutation(DISCONNECT);
|
const [disconnect] = useMutation(DISCONNECT);
|
||||||
|
const [openMsg, setOpenMsg] = useState(false);
|
||||||
|
|
||||||
if (!data || !data.devices) {
|
if (!data || !data.devices) {
|
||||||
return <div>No data</div>;
|
return <div>No data</div>;
|
||||||
@@ -66,16 +69,8 @@ const Devices = () => {
|
|||||||
</Heading>
|
</Heading>
|
||||||
</Box>
|
</Box>
|
||||||
<Box direction="row" gap="xsmall">
|
<Box direction="row" gap="xsmall">
|
||||||
<Button
|
<Button label="Capture" onClick={() => {}} />
|
||||||
label="Capture"
|
<Button label="INDI panel" onClick={() => {}} />
|
||||||
onClick={() => {
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
label="INDI panel"
|
|
||||||
onClick={() => {
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{!connected ? (
|
{!connected ? (
|
||||||
<Button
|
<Button
|
||||||
label="Connect"
|
label="Connect"
|
||||||
@@ -91,16 +86,25 @@ const Devices = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<Button icon={<Contact />} onClick={() => setOpenMsg(true)} />
|
||||||
</Box>
|
</Box>
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
|
{false && (
|
||||||
|
<Layer full="vertical" position="right" modal={false}>
|
||||||
|
<Box width="medium" fill="vertical">
|
||||||
|
bla
|
||||||
|
</Box>
|
||||||
|
</Layer>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box overflow="auto">
|
<Box overflow="auto">
|
||||||
{data ? (
|
{data ? (
|
||||||
<Tabs justify="start">
|
<Tabs justify="start">
|
||||||
{data && data.devices ? (
|
{data && data.devices ? (
|
||||||
data.devices.map((d) => (
|
data.devices.map((d) => (
|
||||||
<Tab title={d.name} key={d.id}>
|
<Tab title={d.name} key={d.id}>
|
||||||
<Device device={d} />
|
<Device device={d} messages={openMsg} onMessagesClosed={() => setOpenMsg(false)}/>
|
||||||
</Tab>
|
</Tab>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -54,4 +54,16 @@ export function stateToColor(state) {
|
|||||||
case 3:
|
case 3:
|
||||||
return "status-error";
|
return "status-error";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function msgToColor(msg) {
|
||||||
|
if (msg.match(/\[INFO\]/)) {
|
||||||
|
return "status-ok";
|
||||||
|
} else if (msg.match(/\[WARNING\]/)) {
|
||||||
|
return "status-warning";
|
||||||
|
} else if (msg.match(/\[ERROR\]/)) {
|
||||||
|
return "status-error";
|
||||||
|
} else {
|
||||||
|
return "status-unknown";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user