Commit 14ca1dcc authored by Michael Vrána's avatar Michael Vrána


parent cfaf5b2b
Pipeline #79948 passed with stages
in 4 minutes and 46 seconds
......@@ -4,7 +4,7 @@
# testing
#debug files
# Algorithms Library Toolkit - Web UI Client
# WebUI
## Requirements
Web GUI for [Algorithms Library Toolkit](
- node.js
- yarn
This project is split into 3 subprojects:
## Scripts
1. [WebUI](webui/ - [React]( frontend
2. [API Server](server/ - [Ktor]( API Server with embedded [ActiveMQ]( broker
3. [Worker](worker/ - Evaluate requests from the broker
`npm install` - install dependencies
`npm start` - run app in development mode
`npm run build` - build application
`npm run doc` - generate TypeDoc documentation
`npm test` - run app tests
`npm run test:coverage` - run app tests and generate coverage report
## Folder Structure
### `src`
- `index.tsx` - Application root and initializing
#### `components`
Contains react components.
#### `hooks`
Contains react hooks and react context providers.
#### `interfaces`
Contains typescript interfaces and models used in application.
Most of the data structures in app are defined here unless they are very specific and used only once.
Also contains helper functions tied to interfaces.
#### `reducers`
Contains application data state modules. Actions, reducers and initial states are defined here.
#### `utils`
Contains general application utility functions.
- `export/` - File export modules
- `import/` - File import modules
- `positioning/` - Positioning modules
- `validation/` - Validation modules
- `errors.ts` - Evaluating if element is correctly defined and generating application errors
- `export.ts` - Mapping state machine to suitable output formats and managing machine download
- `persist.ts` - Saving, loading and removing state from local browser storage
- `positioning.ts` - Computing relative positions based on distance and angles
- `redux.ts` - Generator functions, types and interfaces used in managing application state
## Application data state
Most of the application state is managed with redux. Only some parts that affect one component are managed locally.
Data state is split into three modules.
The modules independently of each other, but usually when triggering action in one module, some action needs to get triggered in other module. This means that it requires more code when triggering actions, but it allows for more modular experience and the triggered actions are mostly very simple. This leads to less confusion about what is the action's purpose.
### Canvas
Canvas state manages actions performed on the drawing canvas.
It manages displaying ghost elements when in build mode to indicate the possible placement.
Also selecting elements is managed here. All element interaction when element is selected gets displayed on canvas.
It also keeps track about the number of states and transitions built to help generating automated element numbering.
### Data
Data state keeps track of all information required for the state machine definition.
It manages adding, updating and deleting states and transitions and defining initial and final states.
States and transitions are saved in maps rather than arrays for easier lookup.
Accessing elements by it's id is much faster than iterating over array and searching for the element. This operation is done many times in the rendering process and would be very costly when the state machine gets more complicated.
Each element has unique uuid which is used as its key. The element is then saved under it's key.
State keeps track of it's name, position and size.
Transition keeps track of it's name, start state and end state.
Initial and final states are saved in string arrays of state ids.
#### Structure
interface IState {
id: string
name: string
position: Position
size: Size
interface ITransition {
id: string
name: string
startState: string
endState: string
interface State {
initialStates: string[]
finalStates: string[]
states: { [key: string]: IState }
transitions: { [key: string]: ITransition }
### Toolbar
Toolbar state is rather simple and is mainly used for the purpose of indicating currently performed task.
It also manages changing input, so elements can use the value.
The most important part is managing the setting of build state indicator that gets used in the app to hide/show elements and allowing certain actions.
## Architecture
The application is built with react using the newest features of react hooks. With react it is very easy to manage the application components.
Application is split into several parts.
### Toolbar
Enables most of user interaction. It displays buttons for performing actions and drag and drop. There is also hidden part that gets showed when elements are selected and it enables to configure those elements.
### Canvas
Canvas is used for the data visualization of the state machine.
It uses svg HTML element and all the states and transitions are defined as svg elements.
It draws the whole state machine and enables interaction with the elements.
When build mode is active it shows ghost state or transition that after placing gets turned into actual data element.
Data states are mapped over and are defined as svg group elements. The base is visualized as rectangle with text in it displayed as its name.
Grouping the elements allows for easier interaction when hovering over and selecting the element.
There are mouse events tied to the svg elements that after firing dispatch actions to reducers that are provided by the contexts. This enables to edit data state by the HTML elements. The elements don't usually have local state and all data that is displayed is grabbed from the data state. This unidirectional data flow enables that the application always shows current data state.
Data transitions behave similarly. On top of that the transition, which is visualized by arrow, computes it's positional properties based on the states it connects.
Transition looks up in data state the states by ids and uses their size and position to show the arrow from the closest edge of the starting state to the closest edge of the end state.
## Controls
App combines drag and drop controls with point and click.
Both methods allow to build states and transitions.
States and transitions are created in build mode triggered by `MouseDown` action or by `Keyboard` event.
### Building state
1. Drag and drop
1. Drag from state icon on toolbar (entering build mode)
2. Drop state on canvas
2. Point and click
1. Click on toolbar state icon / press `S` (entering build mode)
2. Click on canvas
### Building transition
1. Drag and drop
1. Drag from transition icon on starting state (entering build mode)
2. Drop arrow on end state
2. Point and click
1. Click on toolbar transition icon / press `T` (entering build mode)
2. Click on start state
3. Click on end state
### Selecting element
Element can be selected by clicking on it.
When selected, additional tools will appear next to toolbar.
Input box for renaming element and delete button.
On selected state there will also be buttons for toggling initial and final state attributes.
### Importing and Exporting
State can be exported by clicking on export button in toolbar.
Browser will download a file containing the definition of the state machine.
### Saving and loading state
Current state machine can be saved to local browser storage with save button in toolbar. Saved state can be loaded from storage even after browser reload by the load button.
State machine can also be reset by the reset button.
### Hints
Application shows hints for keyboard shortcuts on bottom right and also hints when building elements on top right.
Hints can be disabled by the toggle hint button on toolbar.
## About
Forked from, which is an application developed as a bachelor's project at the CTU FIT by Petr Svoboda
## Authors
- Michael Vrána:
\ No newline at end of file
# API Server
API Server accepts evaluate requests on the `/evaluate` endpoint and passes them to broker.
The API Server is built using the [Ktor]( framework. Requests are sent to the embedded [ActiveMQ]( brokers `request` queue. Responses are consumed form the `response` queue.
The server is listening for HTTP requests on port `3001`.
The broker is listening for TCP connections on port `61616`.
## Building
To build the API Server `jar`, run `./gradlew build jar` from the server directory. The `jar` is then located in `build/libs`.
## Docker
This subproject contains a `Dockerfile` for deployment. The Docker image exposes TCP ports `3001` and `61616`.
\ No newline at end of file
# Algorithms Library Toolkit - WebUI
React frontend for the [Algorithms Library Toolkit](
## Requirements
- node.js
- npm
## Scripts
`npm install` - install dependencies
`npm start` - run app in development mode
`npm run build` - build application
`npm run doc` - generate TypeDoc documentation
`npm test` - run app tests
`npm run test:coverage` - run app tests and generate coverage report
## Development
To run an application in development mode use `npm start`.
The application needs an API server for evaluation. In development mode the API requests are proxied to - see `proxy` in `package.json`
## Building
To make a production build use `npm run build`
## Algorithms JSON
To generate the algorithms JSON use the generator in the `algorithmsJSONGenerator` directory.
### Compiling
1. Install `g++` and `cmake`
2. Install [ALT]( and [jsoncpp]( libraries
3. `cd <project_dir>/algorithmsJSONGenerator`
4. `cmake .`
5. `make`
6. Run `./algorithms_JSON_generator` to print a new algorithms JSON. To update algorithms JSON in the src directory run `./algorithms_JSON_generator > ../src/algorithms.json`
## Docker
The repository contains a `Dockerfile` to build and deploy the app. It uses nginx to host the app. The nginx server can be configured by the `nginx/default.conf` config.
## About
The application was forked from [Statemaker](, which is an application developed as a bachelor's project at the CTU FIT by Petr Svoboda. The Statemaker is used for creating and displaying finite automaton inputs/outputs.
# Worker
Worker consumes requests from the [ActiveMQ]( brokers `request` queue and evaluates them. Responses are then sent to the `response` queue.
## Dependencies
- g++
- cmake
- pkg-config
- [ALT](
- [activemq-cpp](
- [jsoncpp](
## Compiling
1. `cd <project_dir>/worker`
2. `cmake .`
3. `make`
## Running
To run the worker, pass the broker address as the first argument and the evaluation timeout in miliseconds as the second argument. For example `./alib_web_worker tcp://localhost:61616 30000`
## Tests
Test are using the [catch2]( library. To run the tests build the `catch_tests` cmake target and the run `./catch_tests`.
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment