Browse Source

I can a lot of things.

webui
Stian Aune 5 years ago
parent
commit
118a21ad42
  1. 6
      webui/src/App.js
  2. 40
      webui/src/Components/Group.jsx
  3. 20
      webui/src/Components/Modals/GroupAddModal.jsx
  4. 101
      webui/src/Components/Modals/GroupPropertiesModal.jsx
  5. 39
      webui/src/Components/Modals/LightPropertiesModal.jsx
  6. 84
      webui/src/Components/Modals/PermissionsModal.jsx
  7. 12
      webui/src/Helpers/groups.js
  8. 33
      webui/src/Hooks/auth.js

6
webui/src/App.js

@ -5,18 +5,12 @@ import LoginForm from "./Components/Forms/LoginForm";
import {Container} from "reactstrap";
import {BrowserRouter} from "react-router-dom";
import {Route} from "react-router";
import {setGlobal} from "reactn";
import useAuth from "./Hooks/auth";
import IndexPage from "./Components/Pages/IndexPage";
import GroupPage from "./Components/Pages/GroupPage";
import Loading from "./Components/Loading";
import LightPage from "./Components/Pages/LightPage";
setGlobal({
"auth/login": false,
"auth/checked": false,
});
export default function App() {
const [hasStarted, setHasStarted] = useState(false);
const {isLoggedIn, isChecked, verify} = useAuth();

40
webui/src/Components/Group.jsx

@ -6,10 +6,15 @@ import Loading from "./Loading";
import {deleteGroup} from "../Helpers/groups";
import ColorModal from "./Modals/ColorModal";
import {changeColor} from "../Helpers/lights";
import GroupPropertiesModal from "./Modals/GroupPropertiesModal";
import useAuth from "../Hooks/auth";
function Group({id, name}) {
function Group({id, name, permissions}) {
const {user} = useAuth();
const lights = useLights({groupId: id});
const [colorModal, setColorModal] = useState("");
const [colorModal, setColorModal] = useState(false);
const [propModal, setPropModal] = useState(false);
const ready = lights !== null;
const noLights = ready && lights.length === 0;
@ -34,6 +39,14 @@ function Group({id, name}) {
pValue = lights[0].on;
}
function iCan(name) {
const perm = permissions.find(p => p.userId === user.id);
return typeof perm !== "undefined"
? perm[name]
: false;
}
return (
<Card className="mt-3">
<CardHeader>{name}</CardHeader>
@ -42,15 +55,21 @@ function Group({id, name}) {
? <ListGroup>{lights.map(light => <Light key={light.id} {...light} />)}</ListGroup>
: <Loading/>}
</CardBody>
<CardFooter>
<Button color="primary">Detaljer</Button>
{(iCan("manage") || iCan("write") || iCan("delete")) && (
<CardFooter>
{iCan("manage") && (
<Button color="primary" onClick={() => setPropModal(true)}>Detaljer</Button>
)}
{" "}
{hasLights && (
{hasLights && iCan("write") && (
<Button color="secondary" onClick={() => setColorModal(true)}>Skift farger</Button>
)}
{" "}
{id > 0 && <Button color="danger" onClick={onDelete}>Fjern</Button>}
</CardFooter>
{iCan("delete") && (id > 0) && (
<Button color="danger" onClick={onDelete}>Fjern</Button>
)}
</CardFooter>
)}
{colorModal && (
<ColorModal cValue={cValue}
bValue={bValue}
@ -64,6 +83,13 @@ function Group({id, name}) {
onCancel={() => setColorModal(false)}
/>
)}
{propModal && (
<GroupPropertiesModal id={id}
nValue={name}
permissions={permissions}
onClose={() => setPropModal(false)}
/>
)}
</Card>
);
}

20
webui/src/Components/Modals/GroupAddModal.jsx

@ -1,5 +1,5 @@
import React, {useState} from "react";
import {Button, Form, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader} from "reactstrap";
import {Button, Col, Form, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader} from "reactstrap";
import {addGroup} from "../../Helpers/groups";
function GroupAddModal({onClose}) {
@ -10,15 +10,17 @@ function GroupAddModal({onClose}) {
<ModalHeader>Ny gruppe</ModalHeader>
<ModalBody style={{margin: "0 auto"}}>
<Form>
<FormGroup>
<Label for="text-name">
Navn
<FormGroup row>
<Label sm={3} for="text-name">
Navn:
</Label>
<Input type="text"
id="text-name"
name="power"
value={name}
onChange={e => setName(e.target.value)}/>
<Col sm={9}>
<Input type="text"
id="text-name"
name="power"
value={name}
onChange={e => setName(e.target.value)}/>
</Col>
</FormGroup>
</Form>
</ModalBody>

101
webui/src/Components/Modals/GroupPropertiesModal.jsx

@ -0,0 +1,101 @@
import React, {useState} from "react";
import useAuth from "../../Hooks/auth";
import {
Button,
Col,
Form,
FormGroup,
Input,
InputGroup,
InputGroupAddon,
Label,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
Row
} from "reactstrap";
import PermissionsModal from "./PermissionsModal";
function GroupPropertiesModal({id, nValue, permissions, onClose}) {
const {users} = useAuth();
const [name, setName] = useState(nValue);
const [permUserId, setPermUserId] = useState(null);
const [permModal, setPermModal] = useState(false);
function permissionFor(userId) {
const perm = permissions.find(p => p.userId === userId);
return typeof perm !== "undefined"
? perm
: null;
}
return (
<Modal isOpen={true}>
<ModalHeader>Endre gruppe</ModalHeader>
<ModalBody style={{margin: "0 auto"}}>
<Form>
<FormGroup row>
<Label sm={3} for="text-name">
Navn:
</Label>
<Col sm={9}>
<Input type="text"
id="text-name"
name="power"
value={name}
onChange={e => setName(e.target.value)}/>
</Col>
</FormGroup>
<FormGroup row>
<Label sm={3}>
Tilgang:
</Label>
<Col sm={9}>
{users.map(user => {
const permission = permissionFor(user.id);
const btnColor = permission !== null ? "secondary" : "success";
const btnLabel = permission !== null ? "Endre" : "Opprett";
return (
<Row>
<InputGroup className="mb-2">
<Input className="permission" disabled value={user.name}/>
<InputGroupAddon addonType="prepend">
<Button color={btnColor} onClick={() => {
setPermUserId(user.id);
setPermModal(true);
}}>{btnLabel}</Button>
</InputGroupAddon>
</InputGroup>
</Row>
)
})}
</Col>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="primary"
onClick={() => {
onClose();
}}
>
Lagre
</Button>
{" "}
<Button color="secondary" onClick={onClose}>Avbryt</Button>
</ModalFooter>
{permModal && (
<PermissionsModal permissions={permissionFor(permUserId)}
groupId={id}
userId={permUserId}
onClose={() => setPermModal(false)}
/>
)}
</Modal>
);
}
export default GroupPropertiesModal;

39
webui/src/Components/Modals/LightPropertiesModal.jsx

@ -1,6 +1,5 @@
import React, {useState} from "react";
import {Button, Form, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader} from "reactstrap";
import {addGroup} from "../../Helpers/groups";
import {Button, Col, Form, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader} from "reactstrap";
import useGroups from "../../Hooks/group";
import Loading from "../Loading";
import {changeLight} from "../../Helpers/lights";
@ -18,27 +17,31 @@ function LightPropertiesModal({id, gValue, nValue, onClose}) {
<ModalHeader>Lysegenskaper</ModalHeader>
<ModalBody style={{margin: "0 auto"}}>
<Form>
<FormGroup>
<Label for="text-name">
Navn
<FormGroup row>
<Label sm={3} for="text-name">
Navn:
</Label>
<Input type="text"
id="text-name"
value={name}
onChange={e => setName(e.target.value)}
/>
<Col sm={9}>
<Input type="text"
id="text-name"
value={name}
onChange={e => setName(e.target.value)}
/>
</Col>
</FormGroup>
</Form>
<Form>
<FormGroup>
<Label for="sel-group">
Navn
<FormGroup row>
<Label sm={3} for="sel-group">
Gruppe:
</Label>
<Input type="select"
value={groupId}
onChange={e => setGroupId(parseInt(e.target.value, 10))}>
{groups.map(g => <option value={g.id}>{g.name}</option>)}
</Input>
<Col sm={9}>
<Input type="select"
value={groupId}
onChange={e => setGroupId(parseInt(e.target.value, 10))}>
{groups.map(g => <option value={g.id}>{g.name}</option>)}
</Input>
</Col>
</FormGroup>
</Form>
</ModalBody>

84
webui/src/Components/Modals/PermissionsModal.jsx

@ -0,0 +1,84 @@
import React, {useState} from "react";
import {Button, CustomInput, FormGroup, Modal, ModalBody, ModalFooter, ModalHeader} from "reactstrap";
import {savePermissions} from "../../Helpers/groups";
function PermissionsModal({groupId, userId, permissions, onClose}) {
function getPermission(type) {
if (permissions === null || typeof permissions[type] === "undefined") {
return false;
}
return permissions[type];
}
const [read, setRead] = useState(getPermission("read"));
const [write, setWrite] = useState(getPermission("write"));
const [create, setCreate] = useState(getPermission("create"));
const [remove, setRemove] = useState(getPermission("delete"));
const manage = getPermission("manage");
return (
<Modal isOpen={true}>
<ModalHeader>Endre gruppe</ModalHeader>
<ModalBody style={{margin: "0 auto"}}>
<FormGroup className="perm-switch">
<CustomInput type="switch"
id="switch-read"
name="read"
label="Les"
checked={read}
onChange={e => setRead(e.target.checked)}/>
</FormGroup>
<FormGroup className="perm-switch">
<CustomInput type="switch"
id="switch-write"
name="write"
label="Skriv"
checked={write}
onChange={e => setWrite(e.target.checked)}/>
</FormGroup>
<FormGroup className="perm-switch">
<CustomInput type="switch"
id="switch-create"
name="create"
label="Opprett"
checked={create}
onChange={e => setCreate(e.target.checked)}/>
</FormGroup>
<FormGroup className="perm-switch">
<CustomInput type="switch"
id="switch-remove"
name="remove"
label="Slett"
checked={remove}
onChange={e => setRemove(e.target.checked)}/>
</FormGroup>
<FormGroup className="perm-switch">
<CustomInput type="switch"
id="switch-manage"
name="manage"
label="Forvalte"
checked={manage}
disabled/>
</FormGroup>
</ModalBody>
<ModalFooter>
<Button color="primary"
onClick={() => {
savePermissions(
groupId,
userId,
{read, write, delete: remove, create});
onClose();
}}
>
Lagre
</Button>
{" "}
<Button color="secondary" onClick={onClose}>Avbryt</Button>
</ModalFooter>
</Modal>
);
}
export default PermissionsModal;

12
webui/src/Helpers/groups.js

@ -1,6 +1,6 @@
import {randId} from "./random";
import {fetchDelete, fetchGet, fetchPost} from "./fetcher";
import {notNullish, nullish} from "./null";
import {fetchDelete, fetchGet, fetchPatch, fetchPost} from "./fetcher";
import {nullish} from "./null";
const localData = {};
const callbacks = [];
@ -42,6 +42,14 @@ export function deleteGroup(groupId) {
});
}
export function savePermissions(groupId, userId, permissions) {
fetchPatch(`/group/${groupId}/permission/${userId}`, permissions).then(({data, error}) => {
if (error === null) {
fetchAll();
}
});
}
function fetchAll() {
fetchGet("/group/").then(({data, error}) => {
if (error === null) {

33
webui/src/Hooks/auth.js

@ -1,15 +1,40 @@
import {useGlobal} from "reactn";
import {setGlobal, useGlobal} from "reactn";
import {fetchGet, fetchPost} from "../Helpers/fetcher";
setGlobal({
"auth/login": false,
"auth/checked": false,
"auth/users/me": null,
"auth/users/all": [],
});
export default function useAuth() {
const [isLoggedIn, setIsLoggedIn] = useGlobal("auth/login");
const [isChecked, setIsChecked] = useGlobal("auth/checked");
const [user, setUser] = useGlobal("auth/users/me");
const [users, setUsers] = useGlobal("auth/users/all");
function fetchUsers() {
fetchGet("/user/").then(({data, error}) => {
if (error === null) {
setUsers(data);
}
});
}
function verify() {
setIsChecked(false);
fetchGet("/user/session").then(({data, error}) => {
setIsLoggedIn(error === null && data.loggedIn);
const validSession = error === null && data.loggedIn;
setIsLoggedIn(validSession);
if (validSession) {
setUser(data.user);
fetchUsers();
}
setIsChecked(true);
})
}
@ -26,6 +51,8 @@ export default function useAuth() {
}
setIsLoggedIn(true);
setIsLoggedIn(data);
fetchUsers();
});
}
@ -60,5 +87,5 @@ export default function useAuth() {
})
}
return {isLoggedIn, isChecked, verify, login, logout, register};
return {isLoggedIn, isChecked, user, users, verify, login, logout, register};
}
Loading…
Cancel
Save