DEV Community

Cover image for Create a Simple React JS Workflow App From Scratch – Your Ultimate Guide
Optimajet Limited
Optimajet Limited

Posted on • Updated on

Create a Simple React JS Workflow App From Scratch – Your Ultimate Guide

It's time to write our second application, where there will be a list of schemes, processes, and a Workflow Designer with the ability to start a process and see its status. We will use create-react-app template to create a simple React application. Open your console and go to the folder react-example, then execute following commands:

npx create-react-app frontend
cd frontend
npm run start
Enter fullscreen mode Exit fullscreen mode

You should see something similar in your console:

Compiled successfully!

You can now view frontend in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.50.125:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully
Enter fullscreen mode Exit fullscreen mode

Now open your browser at http://localhost:3000 (in your case address may be different) and you will see an example React application. Let's start hack it. First we will add a navigation bar to our application. We will use React Suite library.

Stop frontend application if its running (Ctrl+C). Open your console and execute command:

npm install rsuite
Enter fullscreen mode Exit fullscreen mode

Then run frontend application again:

npm run start
Enter fullscreen mode Exit fullscreen mode

Open frontend application in your favourite IDE. We will use JetBrains IDEA.

Adding settings to access backend APIs

Add settings.js file under frontend src folder with the following content:

frontend/src/settings.js

const backendUrl = 'http://localhost:5139';

const settings = {
    workflowUrl: `${backendUrl}/api/workflow`,
    userUrl: `${backendUrl}/api/user`,
    designerUrl: `${backendUrl}/designer/API`
}

export default settings;
Enter fullscreen mode Exit fullscreen mode

The settings object contains following properties:

  1. workflowUrl - URL to access workflow API, see WorkflowController class.
  2. userUrl - URL to access user API, see UserController class.
  3. designerUrl - URL to access Workflow Designer API, see DesignerController class.

Adding schemes table

We will now create a simple table to show the workflow schemes from our API. Add the Schemes.js file to the frontend src folder with the following content:

frontend/src/Schemes.js

import {Table} from "rsuite";
import {useEffect, useState} from "react";
import settings from "./settings";

const {Column, HeaderCell, Cell} = Table;

const Schemes = (props) => {
    const [data, setData] = useState([]);

    useEffect(() => {
        fetch(`${settings.workflowUrl}/schemes`)
            .then(response => response.json())
            .then(data => setData(data))
    }, []);

    return <Table data={data}
                  height={400}
                  onRowClick={rowData => props.onRowClick?.(rowData)}>
        <Column flexGrow={1}>
            <HeaderCell>Code</HeaderCell>
            <Cell dataKey="code"/>
        </Column>
        <Column flexGrow={1}>
            <HeaderCell>Tags</HeaderCell>
            <Cell dataKey="tags"/>
        </Column>
    </Table>
}

export default Schemes;
Enter fullscreen mode Exit fullscreen mode

The React Schemes component simply shows the data in the Table and retrieves the data from the backend in the useEffect hook. The component calls the props.onRowClick function, if it was passed through props, when the user clicks a table row.

Adding process instance table

Add the Processes.js file to the frontend src folder with the following content:

frontend/src/Processes.js

import {Table} from "rsuite";
import {useEffect, useState} from "react";
import settings from "./settings";

const {Column, HeaderCell, Cell} = Table;

const Processes = (props) => {
    const [data, setData] = useState([]);

    useEffect(() => {
        fetch(`${settings.workflowUrl}/instances`)
            .then(response => response.json())
            .then(data => setData(data))
    }, []);

    return <Table data={data}
                  height={400}
                  onRowClick={rowData => props.onRowClick?.(rowData)}>
        <Column flexGrow={1}>
            <HeaderCell>Id</HeaderCell>
            <Cell dataKey="id"/>
        </Column>
        <Column flexGrow={1}>
            <HeaderCell>Scheme</HeaderCell>
            <Cell dataKey="scheme"/>
        </Column>
        <Column flexGrow={1}>
            <HeaderCell>CreationDate</HeaderCell>
            <Cell dataKey="creationDate"/>
        </Column>
        <Column flexGrow={1}>
            <HeaderCell>StateName</HeaderCell>
            <Cell dataKey="stateName"/>
        </Column>
        <Column flexGrow={1}>
            <HeaderCell>ActivityName</HeaderCell>
            <Cell dataKey="activityName"/>
        </Column>
    </Table>
}

export default Processes;
Enter fullscreen mode Exit fullscreen mode

The React Processes component works the same way as the Schemes component, but for process instances. Pay attention to useState, useEffect hooks and the onRowClick property.

Adding users SelectPicker

Now we need a component in which we can select the current user who will execute the process commands. Add the Users.js file to the frontend src folder with the following content:

frontend/src/Users.js

import {useEffect, useState} from "react";
import {SelectPicker} from "rsuite";
import settings from "./settings";

const Users = (props) => {
    const [users, setUsers] = useState([]);

    const onChangeUser = user =>