Skip to content

EricGebhart/prod-inv-ui

Repository files navigation

prod-inv-ui

A re-frame / clojurescript / react application. This is a ui for a backend server which contains product inventory levels and history.

But it also runs standalone as an SPA with generated data.

I obviously went a little overboard. You can choose to use the server or not.

Both Bonus features listed in the goals below are present.

  • The ability to add a new inventory record for the currently selected product.
  • The ability to choose any number of product for the chart.

The server side project written in python/flask/sqlalchemy is here.

improvments left.

Some CSS would be nice. I'm not sure it makes too much sense here. Feel free to knock yourself out. Maybe I'll add a little. On verra.

I stored the timestamps as epoch numbers. This makes it easy to do a lot of different things easily with the dates.

The graphs want epoch numbers so that was easy. And it's easy to convert them back into dates which can be manipulated easily. The re-frame-datatable takes a render function so I just turned it back into a date and formated it right there into a basic date-time format. I think the same thing would have happened if I just converted it to a string. But there are a lot of formats to choose from and this code would handle that.

There are a few things which I would extract out of this to make more useful react components. The charts could be made much more generic and reusable. The component is reusable, but creating the data for the chart is a matter of creating a datastructure with all the right settings. I think that a refactor is needed for the chart data translate, it could be simpler. Still it works fine. And my goal here was to just create a UI not a set of reusable libraries.

I could also do more with co-effects and interceptors but thats not a path I need to take at the moment.

Testing is reasonable. I could go further, but there really isn't much to test. subscriptions are all direct, the views do almost nothing, I don't see any reason to make sure hiccup is working. events are mostly very simple assigments mostly. Some scenarios with sequences of event dispatches could be interesting to ensure the behaviors of the interface stay consistent as things change, as if they would for this silly thing.

I would like to have an example of using dispatch-sync in a test.

these are the goals. On verra.

Front (client side)

It should include three main elements:

1- A graph of inventory level(y-axis) vs. date(x-axis) of the selected product

2- Table of data filtered on the selected product: product_id; product_name; date; inventory_level

3- Dropdown/Select option to choose the product ID or product name to visualize

4- (Bonus) Add a button that allows data table editing. Add the possibility to change the "inventory level" and send request to change it in the back-end

5- (Bonus) Add the possibility to choose multiple products and visualize them in the same graph

Back (server side)

Storing the data in a simple flat file. Implement a simple API (post, get,...).

Unit test

Write some basic unit test (client and server side)

Annexe

Constraints

  1. front-end code and back-end code are separated in two different projects

  2. Communication between back and front is done by a rest API or GaphQL

Type of data

You can create the sample of data you want with at least those elements:

product_id(int); product_name(String); date(String: "dd-mm-yyyy"); inventory_level(int)

To start.

Install leiningen

get the dependencies.

   yarn install
   ## or npm install
   npm install highcharts

The project template

This command was used to create this initial project.

lein new re-frame prod-inv-ui +re-com +cider +garden +10x +test

You can read about the re-frame template here.

  • re-com are components, I may not have used them.
  • cider is the clojure repl and debugging interface in emacs.
  • garden is a way to create CSS with clojure data. It is to css as hiccup is to html.
  • re-frame-10x is a way to see inside react, read about it here.
  • test integrates basic testing as in cljs.test..

Development

I developed this in isolation of the backend in the product_inventory server project. Then switched the data events to send requests to the server once everything was working with mocked data. So ideally, you'll want to be running that server too.

Development Mode

Start Cider from Emacs:

Refer to the shadow-cljs Emacs / CIDER documentation.

The mentioned dir-local.el file has been created.

Compile css:

Compile css file once.

lein garden once

Automatically recompile css file on change.

lein garden auto

Run application:

lein clean
lein dev

shadow-cljs will automatically push cljs changes to the browser.

Wait a bit, then browse to http://localhost:8280.

Open 10x Panel :

To use re-frame-10x for debugging your app:

  1. click on the application, minimal through it is, to give it "input focus" (you want to be sure that any key presses are going to your new app)
  2. press Ctrl-H and you should see the re-frame-10x panel appear on the right side of the window

Sometimes achieving Step 1 on a really simple app - one without widgets - can be fiddly, because the browser itself hogs "input focus" and grabs all the keystrokes (like Ctrl-H) which don't then make it through to your app. You may need to be determined and creative with Step 1.

Hot Reloading Is Now Go

If you now edit files, like perhaps /src/cljs/<project-name>/views.cljs, Figwheel will automatically recompile your changes and "hot load" them into your running app, without your app needing to be re-started. The resulting fast, iterative workflow tends to make you very productive, and is cherished by those lucky enough to experience it.

debug?:

In project-name.config, there is a variable called debug?, which defaults to true. However, for the min build (look inside of project.clj), this variable is re-defined to false.

When debug? is true, we include (enable-console-print!). If you, for example, you wrap your printlns with a when block as show below, then you will get logs printed to the browser's console for the dev build and not the min build.

(when config/debug?
  (println "dev mode"))

Run tests:

Install karma and headless chrome

npm install -g karma-cli

And then run your tests

lein clean
lein run -m shadow.cljs.devtools.cli compile karma-test
karma start --single-run --reporters junit,dots

Production Build

This will compile the project into javascript for production use.

lein prod

About

An example UI for a product inventory history using react.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published