Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard skeleton #4

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
70c5fca
Update shadow-cljs configuration
kaffein Apr 19, 2020
fb97f63
Implement app entrypoint in index.html
kaffein Apr 19, 2020
28373a9
Add logging library
kaffein Apr 25, 2020
1f451ba
Add npm deps for bulma, bloomer and a few utils
kaffein Apr 25, 2020
a6b16cc
Implement top nav bar
kaffein Apr 25, 2020
f1f44d7
Implement left pane menu UI
kaffein Apr 25, 2020
36811c6
Make code less verbose when referring to external components
kaffein Apr 26, 2020
50fcb0a
Implement content container with no components
kaffein Apr 26, 2020
be38525
Add re-frame and re-graph dependencies
kaffein Jun 5, 2020
4ab94c3
Add re-frame-10x tooling and configuration
kaffein Jun 5, 2020
85899c0
WIP: Initiate graphql setup and configuration with re-graph
kaffein Jun 5, 2020
f275bb2
Move tooling to :dev dependencies
kaffein Jun 5, 2020
ca89ad4
Upgrade re-graph lib
kaffein Jun 8, 2020
c062247
Refactor code for dashboard statistics fetching
kaffein Jun 8, 2020
f3148a2
Add transit-cljs lib as a dependency for json encoding/decoding
kaffein Jun 9, 2020
f8676b7
Provide an explicit impl parameter for CORS Access-Control-Allow-Cred…
kaffein Jun 9, 2020
7344da8
Refactor code to use re-frame (instead of plain vanilla cljs) for re-…
kaffein Jun 9, 2020
b085f1b
Merge pull request #1 from kaffein/graphql-init
kaffein Jun 9, 2020
928ebc9
Kebab-case incoming data to be more Clojure(script)-compliant
kaffein Jun 9, 2020
1aea3fc
Add subscriptions for dashboard.stats
kaffein Jun 9, 2020
91da706
WIP Implement components for dashboard
kaffein Jun 9, 2020
bcdeac2
Refactor dashboard stat metrics display component
kaffein Jun 10, 2020
f478b07
Fix UI component id
kaffein Jun 10, 2020
0253092
Fix menu nested markup
kaffein Jun 10, 2020
bdd36b9
Refactor content-body
kaffein Jun 10, 2020
dea7e6a
Refactor menu component
kaffein Jun 10, 2020
1a6b415
Update dependencies version to avoid conflicts
kaffein Jul 14, 2020
13ed910
Add leiningen aliases to encapsulate shadow-cljs-related commands
kaffein Jul 14, 2020
a19778a
Rename aliases to avoid shadowing leiningen default commands
kaffein Jul 14, 2020
e0e9161
Update the README file
kaffein Jul 14, 2020
a17cb7f
Refactor component with init code as re-agent 2nd component form
kaffein Jul 24, 2020
65bc46e
Format code
kaffein Jul 24, 2020
8517f67
WIP
kaffein Sep 11, 2020
42ebc30
Refactor project.clj : update lein dependencies
kaffein Dec 4, 2020
b906b4b
Refactor project.clj : add lein-shadow plugin (for shadow-cljs)
kaffein Dec 4, 2020
ccce438
Refactor project.clj : add npm deps (managed by lein-shadow)
kaffein Dec 4, 2020
459f4f2
Move shadow-cljs config to project.clj
kaffein Dec 4, 2020
04c8873
Update profile config and deps
kaffein Dec 4, 2020
1029d43
Remove shadow.cljs.edn from project
kaffein Dec 4, 2020
0b7591d
Remove leiningen from the build pipeline
kaffein Feb 5, 2021
de83c60
Upgrade npm deps
kaffein Feb 5, 2021
e500a26
Update .gitignore following the reverting to a pure shadow-cljs build…
kaffein Feb 5, 2021
1f3421b
Update documentation : shadow-cljs is used for building the project
kaffein Mar 2, 2021
33cd60b
Add metadata on hot-reloading entrypoint
kaffein Mar 2, 2021
ee93524
Add shadow-cljs as dev deps
kaffein Oct 23, 2022
2385200
Fix audit vulnerability issues
kaffein Oct 23, 2022
856cbe6
Add entries to .gitignore
kaffein Oct 23, 2022
c712ecf
Git ignore shadow-cljs compilation outputs
kaffein Oct 23, 2022
0cc0954
Bump dependencies version
kaffein Oct 23, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/resources/public/js/compiled/**
/resources/public/js/**
figwheel_server.log
pom.xml
*jar
Expand All @@ -11,3 +11,6 @@ pom.xml
.lein-plugins/
.repl
.nrepl-port
node_modules/
package-lock.json
.shadow-cljs/
156 changes: 51 additions & 105 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,46 @@ The new (as of 2020) CLJS frontend dashboard for Yetibot

We chose `shadow-cljs` as our main build tool for the project. `shadow-cljs` is easy to use and configure and comes with a very good integration with the other tools that we already use on the other sub-projects under `Yetibot`, for e.g `Leiningen`.

See the `shadow-cljs` _user-guide_ on how to install it.
See the [`shadow-cljs` _user-guide_](https://shadow-cljs.github.io/docs/UsersGuide.html "Shadow-cljs user guide") on how to install it.

## Leiningen
# Development workflow using the shadow-cljs CLI

`Leiningen` is the Clojure build tool that `Yetibot` uses. For `dashboard`, `shadow-cljs` delegates the _dependency management_ to `leiningen`.
There are two (2) main steps to get into the development workflow :

See the `Leiningen` Installation docs to install it.
* Starting the `shadow-cljs` server which will be (re)used by any process to interact with the app.
* Starting a `watch` process which will, as its name suggests, watch and push any changes in the project code to the runtime (_hot reload_).

# Development workflow using the shadow-cljs CLI
> Starting a `watch` process actually starts a server process _automatically_ (step 2).
>
> When the _server_ is launched via the _watch_ process, the _server_ will have to be killed if the _watch_ has to be restarted.
> When launched separately, the `watch` process can be killed and restarted without restarting the _server_ and the `watch` will just reuse the existing server process.

## Running a watch process
## Starting the `shadow-cljs` server

To start a `watch` process which will monitor changes and automatically recompile the `dashboard` code base, run the following from your terminal:
To start the server, just type in :

`$ shadow-cljs watch :dashboard`
`$ shadow-cljs start`

a `watch` will implicitly start a _server process_ which will be re-used by all commands sent by the CLI, instead of starting a new JVM.
It will then spin up a new jvm process for the server and the following output should be displayed on the console.

```shell script
shadow-cljs - config: /home/kaffein/Projects/dashboard/shadow-cljs.edn
shadow-cljs - updating dependencies
shadow-cljs - dependencies updated
shadow-cljs - server starting ........................................................................
ready!
```

> As part of the spinning-up process, the server process will also expose an _nrepl_ server via TCP.
> It can be used to manage the `shadow-cljs` process or interact with the application in its runtime.

## Running a `watch` process

To start a `watch` process which will monitor changes and automatically recompile the `dashboard` code base, run the following incantation from your terminal:

`$ shadow-cljs watch dashboard`

the output on the console should give something like this :

```shell script
+ [email protected]
Expand All @@ -40,7 +63,7 @@ a `watch` will implicitly start a _server process_ which will be re-used by all
[:dashboard] Build completed. (157 files, 156 compiled, 0 warnings, 35.04s)
```

To stop the `watch` process, just type in CTRL-C from the CLI :
To stop the `watch` process, just `CTRL-C` at the command line :

```shell script
...
Expand All @@ -51,109 +74,32 @@ To stop the `watch` process, just type in CTRL-C from the CLI :
Ctrl^C
```

## The REPL

To start the `REPL`, run :

`$ shadow-cljs browser-repl :dashboard`
## Checking the _dev_ setup

It will launch a browser providing the `runtime` used to evaluate the code entered in the `REPL`

```
+ [email protected]
+ [email protected]
updated 2 packages and audited 36 packages in 1.479s
found 0 vulnerabilities

[:browser-repl] Configuring build.
[:browser-repl] Compiling ...
[:browser-repl] Build completed. (157 files, 156 compiled, 0 warnings, 21.91s)
cljs.user=>
```
At this point, to check whether everything works as expected :

# Development workflow using the provided `dev.clj` namespace
* open the application at `http://localhost:3000/` in the browser
* `jack-in`/`connect` your editor to the nrepl process

We also provide a `dev.clj` namespace in `dev/dev.clj` which allows for a more Clojure-_friendly_ workflow during development.
This namespace contains a few utility functions for _programmatically_ interacting with `shadow-cljs` through its Clojure API.
The first step is to `eval` those functions in your REPL.
Once at the `repl` prompt, type in :

```clojure
```shell script
To quit, type: :cljs/quit
...
(defn- compile-build
"Compiles a build `build-id` where `build-id` is a
keyword identifying a build.
This is equivalent to invoking :
$ shadow-cljs compile :build-id"
[build-id]
(shadow/compile build-id))
=> nil
=> #'dev/start-server
=> #'dev/stop-server
=> #'dev/re-init-server
=> #'dev/watch-build
=> #'dev/compile-build

```

You can then `watch` or `compile` a build, `start`, `stop` or `re-init` the `shadow-cljs` server by just calling those functions from within the REPL.

## Starting the shadow-cljs server

```clojure
;; starts a shadow-cljs server
(start-server)
avr. 13, 2020 1:08:25 PM org.xnio.Xnio <clinit>
INFO: XNIO version 3.7.3.Final
avr. 13, 2020 1:08:25 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.7.3.Final
avr. 13, 2020 1:08:25 PM org.jboss.threads.Version <clinit>
INFO: JBoss Threads version 2.3.2.Final
shadow-cljs - server version: 2.8.94 running at http://localhost:9630
shadow-cljs - nREPL server started on port 34619
=> :shadow.cljs.devtools.server/started

;; since a shadow-cljs server is already running
(start-server)
=> :shadow.cljs.devtools.server/already-running
cljs.user> (js/alert "test")
```
a popup should appear from inside the application.

## Shutting down the shadow-cljs server
# Compile the project

```clojure
;; stops the running shadow-cljs server
(stop-server)
shutting down ...
=> nil
```

## Re-initializing the shadow-cljs server
To compile the project once and exit :

```clojure
;; re-initializes the running shadow-cljs server
(re-init-server)
shadow-cljs - server version: 2.8.94 running at http://localhost:9630
shadow-cljs - nREPL server started on port 42915
=> :shadow.cljs.devtools.server/started
```
`$ shadow-cljs compile :dashboard`

## Watching a build
If everything goes right, you should have the following output on the console.

```clojure
;; watches a build (e.g here :dashboard)
(watch-build :dashboard)
[:dashboard] Configuring build.
[:dashboard] Compiling ...
=> :watching
[:dashboard] Build completed. (157 files, 1 compiled, 0 warnings, 2,18s)
...
```

## Compiling a build

```clojure
;; compiles a build (e.g here :dashboard)
(compile-build :dashboard)
[:dashboard] Compiling ...
[:dashboard] Build completed. (59 files, 0 compiled, 0 warnings, 0,58s)
=> :done
```
```shell script
...
[:dashboard] Compiling ...
[:dashboard] Build completed. (567 files, 1 compiled, 3 warnings, 1,96s)
```
34 changes: 34 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "dashboard",
"version": "1.0.0",
"description": "The new (as of 2020) CLJS frontend dashboard for Yetibot",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/kaffein/dashboard.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/kaffein/dashboard/issues"
},
"homepage": "https://github.com/kaffein/dashboard#readme",
"dependencies": {
"bloomer": "^0.6.3",
"bulma": "^0.8.2",
"bulma-checkradio": "^1.1.1",
"create-react-class": "^15.6.3",
"highlight.js": "^11.6.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-highlight.js": "^1.0.0",
"react-router-dom": "^5.1.2"
},
"devDependencies": {
"shadow-cljs": "^2.20.6"
}
}
22 changes: 0 additions & 22 deletions project.clj

This file was deleted.

8 changes: 3 additions & 5 deletions resources/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="css/style.css" rel="stylesheet" type="text/css">
<link rel="icon" href="https://clojurescript.org/images/cljs-logo-icon-32.png">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css">
</head>
<body>
<div id="app">
<h2>Figwheel template</h2>
<p>Checkout your developer console.</p>
</div>
<script src="js/compiled/dashboard.js" type="text/javascript"></script>
<div id="app">If you see this then there must be an issue with the react rendering in dashboard.core/init</div>
<script src="/js/dashboard.js" type="text/javascript"></script>
</body>
</html>
50 changes: 44 additions & 6 deletions shadow-cljs.edn
Original file line number Diff line number Diff line change
@@ -1,8 +1,46 @@
;; shadow-cljs configuration
{:lein true
{:source-paths ["dev" "src"]

:dependencies [;; react
[reagent "1.1.1"]
[re-frame "1.3.0"]

;; graphql
[re-graph/re-graph "0.2.0" :exclusions [re-graph.hato]]
[district0x/graphql-query "1.0.6"]

;; utils
[camel-snake-kebab/camel-snake-kebab "0.4.2"]
[com.cognitect/transit-cljs "0.8.264"]

;; logging
[com.taoensso/timbre "5.2.0"]

;; Tooling
[day8.re-frame/re-frame-10x "1.5.0"]
[day8.re-frame/tracing "0.6.2"]
[binaryage/devtools "1.0.6"]]

:nrepl {:port 8777}

:builds
{:dashboard {:target :browser
:output-dir "public/assets/app/js"
:asset-path "/assets/app/js"
:modules {:main {:entries [dashboard.core]}}}}}
{:dashboard
{:target :browser

;; compiled assets output location configuration
:output-dir "resources/public/js"
:output-to "resources/public/js/dashboard.js"
:asset-path "public/js"

;; module entry point configuration
:modules {:dashboard {:init-fn dashboard.core/init}}

;; Trace-enabling for re-frame-10x tooling
:dev {:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true
"day8.re_frame.tracing.trace_enabled_QMARK_" true}}

:compiler-options {:shadow-keywords true}

:devtools {:http-root "resources/public"
:http-port 3000
:preloads [devtools.preload
day8.re-frame-10x.preload]}}}}
59 changes: 59 additions & 0 deletions src/dashboard/components/dashboard.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
(ns dashboard.components.dashboard
(:require [reagent.core :as r]
[re-frame.core :as rf]
[reagent.dom :as rdom]
[taoensso.timbre :as log
:refer-macros [log trace debug info warn error fatal report
logf tracef debugf infof warnf errorf fatalf reportf
spy get-env]]
["bloomer" :refer (Tile Hero HeroBody Title Subtitle Notification)]
["react-router-dom" :refer (NavLink)]
[dashboard.components.search :refer [search]]
[dashboard.subs.dashboard]))

(defn display
[label value]
[:> Tile {:is-child "true" :class "box"}
[:> Title @value]
[:> Subtitle label]])

(defn expandable-stat-display
[label value path]
[:> NavLink {:class "tile is-parent is-4" :to path}
[display label value]])

(defn stat-display
[label value]
[:> Tile {:is-size 4 :is-parent "true"}
[display label value]])

(defn dashboard
[]
(let [_ (rf/dispatch [:dashboard.stats/fetch 120])
adapter-count (rf/subscribe [:dashboard.stats/adapter-count])
command-count (rf/subscribe [:dashboard.stats/command-count])
command-count-today (rf/subscribe [:dashboard.stats/command-count-today])
user-count (rf/subscribe [:dashboard.stats/user-count])
history-count (rf/subscribe [:dashboard.stats/history-count])
history-count-today (rf/subscribe [:dashboard.stats/history-count-today])
alias-count (rf/subscribe [:dashboard.stats/alias-count])
observer-count (rf/subscribe [:dashboard.stats/observer-count])
cront-count (rf/subscribe [:dashboard.stats/cron-count])
uptime (rf/subscribe [:dashboard.stats/uptime])]
(fn []
[:div
[:> Hero {:is-bold "true" :is-color "info" :is-size "small"}
[:> HeroBody
[:> Title "Dashboard"]
[:> Subtitle (str "Uptime " @uptime)]]]
[:div.tiles
[:> Tile {:is-ancestor "true" :has-text-align "centered"}
[expandable-stat-display "Adapters" adapter-count "/adapters"]
[expandable-stat-display "Commands" command-count "/history?co=1"]
[stat-display "Commands today" command-count-today]
[expandable-stat-display "User" user-count "/users"]
[expandable-stat-display "History items" history-count "/history"]
[stat-display "History items today" history-count-today]
[expandable-stat-display "Aliases" alias-count "/aliases"]
[expandable-stat-display "Observers" observer-count "/observers"]
[expandable-stat-display "Cron tasks" cront-count "/cron"]]]])))
Loading