Documentation
  • 👋Welcome to Cerberus
  • Overview
    • 💡What we do
    • ✨Our Features
  • Product Guides
    • 💡Core concepts
    • 🍎Creating an App
    • 📎Modeling your domain
    • 📄Creating policies
  • Tutorial
    • 🛠️Getting set up
      • 🌠Cloning project
      • 👷Setting up workspace
      • 🏃‍♂️Build and run app
    • 📏Creating static rules
      • Create an account
      • Add migrations
    • ✍️Implementation
      • Backend
        • Migrate existing data
        • Routes
        • Services
          • User
          • Project
          • Sprint
          • Story
      • Frontend
        • Settings
        • Projects
        • Sprints
        • Stories
  • APIs
    • 🎨REST API
    • 🖥️Websocket API
  • Migrations
    • 🐧Scripting language
    • 🏃‍♂️Running migrations
Powered by GitBook
On this page
  1. Tutorial
  2. Implementation
  3. Frontend

Settings

First, we'll refactor the Settings page.

We'll make use of the new users list we get from Cerberus, as well as roles, and permission settings.

Replace the 'src/components/settings/Settings.js' file with the following:

import {useContext, useEffect, useState} from "react";
import {AuthContext} from "../../context/AuthContext";
import {AccessGuard, Permissions, Roles, Users} from "@a11n-io/cerberus-reactjs";
import "@a11n-io/cerberus-reactjs/dist/index.css"
import {Button, Col, Container, Form, ListGroup, ListGroupItem, Row, Tab, Tabs} from "react-bootstrap";
import Loader from "../../uikit/Loader";
import useFetch from "../../hooks/useFetch";

export default function Settings() {

    return <>
        <Tabs defaultActiveKey='users' className='mb-3'>
            <Tab eventKey='users' title='Users'>
                <Users NoUserSelectedComponent={AddUser}/>
            </Tab>
            <Tab eventKey='roles' title='Roles'>
                <Roles />
            </Tab>
            <Tab eventKey='permissions' title='Permissions'>
                <AccountPermissions />
            </Tab>
        </Tabs>
    </>
}

function AddUser() {
    const authCtx = useContext(AuthContext)
    const { post, loading } = useFetch('/api/')
    const {get} = useFetch(`${process.env.REACT_APP_CERBERUS_API_HOST}/api/`) // get roles from cerberus
    const [email, setEmail] = useState("")
    const [password, setPassword] = useState("")
    const [name, setName] = useState("")
    const [roles, setRoles] = useState([])
    const [selectedRole, setSelectedRole] = useState("")

    useEffect(() => {
        get(`roles?sort=name&order=asc&skip=0&limit=100`, {
            "Authorization": "Bearer " + authCtx.user.cerberusToken
        })
            .then(r => {
                if (r && r.page) {
                    setRoles(r.page)
                } else {
                    setRoles([])
                }
            })
            .catch(e => console.error(e))
    }, [])

    function handleEmailChanged(e) {
        setEmail(e.target.value)
    }

    function handlePasswordChanged(e) {
        setPassword(e.target.value)
    }

    function handleNameChanged(e) {
        setName(e.target.value)
    }

    function handleRoleSelected(e) {
        setSelectedRole(e.target.value)
    }

    function handleFormSubmit(e) {
        e.preventDefault()
        post('users', {
            email: email,
            password: password,
            name: name,
            roleName: selectedRole
        })
            .then((r) => {

            })
            .catch((e) => console.error(e))
    }

    if (loading) {
        return <Loader />
    }

    return <>
        <AccessGuard resourceId={authCtx.user.accountId} action="AddUser">
            <Form onSubmit={handleFormSubmit}>
                <Form.Group className='mb-3'>
                    <Form.Label>Email</Form.Label>
                    <Form.Control
                        type='text'
                        placeholder='Enter email'
                        onChange={handleEmailChanged}
                    />
                </Form.Group>
                <Form.Group className='mb-3'>
                    <Form.Label>Password</Form.Label>
                    <Form.Control
                        type='text'
                        placeholder='Enter password'
                        onChange={handlePasswordChanged}
                    />
                </Form.Group>
                <Form.Group className='mb-3'>
                    <Form.Label>Name</Form.Label>
                    <Form.Control
                        type='text'
                        placeholder='Enter name'
                        onChange={handleNameChanged}
                    />
                </Form.Group>
                <Form.Group className='mb-3'>
                    <Form.Label>Role</Form.Label>
                    <Form.Select onChange={handleRoleSelected}>
                        <option value="">Select a role</option>
                        {
                            roles.map(role => {
                                return (
                                    <option key={role.id} value={role.name}>{role.displayName}</option>
                                )
                            })
                        }
                    </Form.Select>
                </Form.Group>
                <Button disabled={email === "" || password === "" || name === ""
                    || selectedRole === ""
                }
                        variant='primary' type='submit'>
                    Add
                </Button>
            </Form>
        </AccessGuard>
    </>
}

function AccountPermissions() {
    const authCtx = useContext(AuthContext)

    return <>
        <AccessGuard resourceId={authCtx.user.accountId} action="ReadAccountPermissions">
            <Permissions resourceId={authCtx.user.accountId} changeAction="ChangeAccountPermissions"/>
        </AccessGuard>
    </>
}

When you run the app now, you'll see a new form to add a user, as well as a tab for Roles, and Account permissions.

You'll notice the code that fetches the roles are limited to 100 results.

We'll leave it as an exercise to improve the UI so that the results are paginated.

PreviousFrontendNextProjects

Last updated 2 years ago

✍️