switched css to bulma, removed all javascript
This commit is contained in:
parent
fe944519ac
commit
2be199a214
File diff suppressed because one or more lines are too long
|
@ -1,9 +1,14 @@
|
||||||
body {
|
body {
|
||||||
font-family: "arial";
|
/* font-family: "arial"; */
|
||||||
font-size: 22px;
|
/* font-size: 22px; */
|
||||||
font-smooth: always;
|
font-smooth: always;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
padding-top: 65px;
|
/* padding-top: 65px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* horizontal margins on wide screens */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.container { width: 36em; }
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
|
@ -31,94 +36,52 @@ code {
|
||||||
|
|
||||||
h1, h2, h3, h4 { }
|
h1, h2, h3, h4 { }
|
||||||
|
|
||||||
|
/* p { */
|
||||||
|
/* letter-spacing: 0.01rem; */
|
||||||
|
/* font-style: normal; */
|
||||||
|
/* line-height: 1.5; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
/* img { */
|
||||||
|
/* width: auto; */
|
||||||
|
/* height: auto; */
|
||||||
|
/* max-width: 100%; */
|
||||||
|
/* vertical-align: middle; */
|
||||||
|
/* overflow: hidden; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
html,body {
|
||||||
|
font-family: 'Open Sans', serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
.hero.is-success {
|
||||||
|
background: #F2F6FA;
|
||||||
|
}
|
||||||
|
.hero .nav, .hero.is-success .nav {
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
margin-top: 5rem;
|
||||||
|
}
|
||||||
|
.avatar {
|
||||||
|
margin-top: -70px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
.avatar img {
|
||||||
|
padding: 5px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
-webkit-box-shadow: 0 2px 3px rgba(10,10,10,.1), 0 0 0 1px rgba(10,10,10,.1);
|
||||||
|
box-shadow: 0 2px 3px rgba(10,10,10,.1), 0 0 0 1px rgba(10,10,10,.1);
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
p {
|
p {
|
||||||
letter-spacing: 0.01rem;
|
font-weight: 700;
|
||||||
font-style: normal;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
}
|
||||||
|
p.subtitle {
|
||||||
img {
|
padding-top: 1rem;
|
||||||
width: auto;
|
|
||||||
height: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
vertical-align: middle;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sortable tables */
|
|
||||||
table.sortable thead {
|
|
||||||
background-color:#eee;
|
|
||||||
color:#666666;
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.sortable td {
|
|
||||||
font-size: .8em;
|
|
||||||
font-family: "arial"
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-form {
|
|
||||||
clear: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
/* padding: .5em; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.secrets {
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.password {
|
|
||||||
font-size: 1.5;
|
|
||||||
padding: 1em;
|
|
||||||
/* display: inline-block; */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.navbar-text {
|
|
||||||
margin-top: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.password .content {
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slices {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.slices ul {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slices .content {
|
|
||||||
font-size: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qrcode {
|
|
||||||
float: left;
|
|
||||||
margin-left: -19px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.card {
|
|
||||||
border: solid 3px #888;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 1.5em 2.2em .8em 2.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card .gravatar {
|
|
||||||
margin-top: 19px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance {
|
|
||||||
font-size: 2em;
|
|
||||||
margin: 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wallet-details {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,302 @@
|
||||||
|
;; Copyright (C) 2015-2018 Dyne.org foundation
|
||||||
|
|
||||||
|
;; Sourcecode designed, written and maintained by
|
||||||
|
;; Denis Roio <jaromil@dyne.org>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU Affero General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU Affero General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
(ns toaster.bulma
|
||||||
|
(:require [clojure.java.io :as io]
|
||||||
|
[clojure.data.csv :as csv]
|
||||||
|
[yaml.core :as yaml]
|
||||||
|
[hiccup.page :as page]
|
||||||
|
[hiccup.form :as hf]))
|
||||||
|
|
||||||
|
(declare render)
|
||||||
|
(declare render-head)
|
||||||
|
(declare navbar-guest)
|
||||||
|
(declare navbar-account)
|
||||||
|
(declare render-footer)
|
||||||
|
(declare render-yaml)
|
||||||
|
(declare render-edn)
|
||||||
|
(declare render-error)
|
||||||
|
(declare render-error-page)
|
||||||
|
(declare render-static)
|
||||||
|
|
||||||
|
|
||||||
|
;; TODO: navbars for bulma
|
||||||
|
(def navbar-brand [:div {:class "navbar"}])
|
||||||
|
(def navbar-guest [:div {:class "navbar"}])
|
||||||
|
(def navbar-account [:div {:class "navbar"}])
|
||||||
|
|
||||||
|
(defn button
|
||||||
|
([url text] (button url text [:p]))
|
||||||
|
|
||||||
|
([url text field] (button url text field "button"))
|
||||||
|
|
||||||
|
([url text field type]
|
||||||
|
(hf/form-to [:post url]
|
||||||
|
field ;; can be an hidden key/value field (project,
|
||||||
|
;; person, etc using hf/hidden-field)
|
||||||
|
[:p {:class "control"}
|
||||||
|
(hf/submit-button {:class (str "button " type)} text)])))
|
||||||
|
|
||||||
|
(defn button-cancel-submit [argmap]
|
||||||
|
[:div
|
||||||
|
{:class
|
||||||
|
(str "row col-md-6 btn-group btn-group-lg "
|
||||||
|
(:btn-group-class argmap))
|
||||||
|
:role "group"}
|
||||||
|
(button
|
||||||
|
(:cancel-url argmap) "Cancel"
|
||||||
|
(:cancel-params argmap)
|
||||||
|
"btn-primary btn-lg btn-danger col-md-3")
|
||||||
|
(button
|
||||||
|
(:submit-url argmap) "Submit"
|
||||||
|
(:submit-params argmap)
|
||||||
|
"btn-primary btn-lg btn-success col-md-3")])
|
||||||
|
|
||||||
|
(defn render
|
||||||
|
([body]
|
||||||
|
{:headers {"Content-Type"
|
||||||
|
"text/html; charset=utf-8"}
|
||||||
|
:body (page/html5
|
||||||
|
(render-head)
|
||||||
|
[:body ;; {:class "static"}
|
||||||
|
;; navbar-guest
|
||||||
|
body
|
||||||
|
(render-footer)])})
|
||||||
|
([account body]
|
||||||
|
{:headers {"Content-Type"
|
||||||
|
"text/html; charset=utf-8"}
|
||||||
|
:body (page/html5
|
||||||
|
(render-head)
|
||||||
|
[:body ;; (if (empty? account)
|
||||||
|
;; navbar-guest
|
||||||
|
;; navbar-account)
|
||||||
|
body
|
||||||
|
(render-footer)])}))
|
||||||
|
|
||||||
|
(defn render-success
|
||||||
|
"render a successful message without ending the page"
|
||||||
|
[succ]
|
||||||
|
[:div {:class "notification is-primary"} succ])
|
||||||
|
|
||||||
|
(defn render-error
|
||||||
|
"render an error message without ending the page"
|
||||||
|
[err]
|
||||||
|
[:div {:class "notification is-danger"} err])
|
||||||
|
|
||||||
|
(defn render-error-page
|
||||||
|
([] (render-error-page {} "Unknown"))
|
||||||
|
([err] (render-error-page {} err))
|
||||||
|
([session error]
|
||||||
|
(render
|
||||||
|
[:div {:class "container"}
|
||||||
|
(render-error error)])))
|
||||||
|
|
||||||
|
|
||||||
|
(defn render-head
|
||||||
|
([] (render-head
|
||||||
|
"toaster.do" ;; default title
|
||||||
|
"From Docker to VM or ARM SDcard in a few clicks, powered by Devuan and the DECODE project" "https://toaster.dyne.org")) ;; default desc
|
||||||
|
|
||||||
|
([title desc url]
|
||||||
|
[:head [:meta {:charset "utf-8"}]
|
||||||
|
[:meta {:http-equiv "X-UA-Compatible" :content "IE=edge,chrome=1"}]
|
||||||
|
[:meta
|
||||||
|
{:name "viewport"
|
||||||
|
:content "width=device-width, initial-scale=1"}]
|
||||||
|
|
||||||
|
[:title title]
|
||||||
|
[:link {:href "https://fonts.googleapis.com/css?family=Open+Sans:300,400,700"
|
||||||
|
:rel "stylesheet"}]
|
||||||
|
;; cascade style sheets
|
||||||
|
(page/include-css "/static/css/bulma.min.css")
|
||||||
|
(page/include-css "/static/css/json-html.css")
|
||||||
|
;; (page/include-css "/static/css/fa-regular.min.css")
|
||||||
|
;; (page/include-css "/static/css/fontawesome.min.css")
|
||||||
|
|
||||||
|
(page/include-css "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css")
|
||||||
|
(page/include-css "/static/css/toaster.css")]))
|
||||||
|
|
||||||
|
(defn render-footer []
|
||||||
|
[:footer {:class "footer"}
|
||||||
|
[:div {:class "content has-text-centered"}
|
||||||
|
[:p {:class "has-text-grey"} "toaster.do transforms your Docker prototype into "
|
||||||
|
"an installable " [:a {:href "https://devuan.org"} "Devuan GNU+Linux"]
|
||||||
|
" image, choose any supported target architecture!"]
|
||||||
|
[:div {:class "columns is-variable is-8"}
|
||||||
|
[:div {:class "column is-one-quarter is-narrow-touch"}
|
||||||
|
[:a {:href "https://www.dyne.org"}
|
||||||
|
[:figure {:class "image"}
|
||||||
|
[:img {:src "/static/img/swbydyne.png"
|
||||||
|
:alt "Software by Dyne.org"
|
||||||
|
:title "Software by Dyne.org"}]]]]
|
||||||
|
[:div {:class "column auto"}]
|
||||||
|
[:div {:class "column is-one-quarter"}
|
||||||
|
[:figure {:class "image"}
|
||||||
|
[:img {:src "/static/img/AGPLv3.png" ;; :style "margin-top: 2.5em"
|
||||||
|
:alt "Affero GPLv3 License"
|
||||||
|
:title "Affero GPLv3 License"}]]]]]])
|
||||||
|
|
||||||
|
(defn render-static [body]
|
||||||
|
(page/html5 (render-head)
|
||||||
|
[:body {:class "fxc static"}
|
||||||
|
|
||||||
|
;; navbar-guest
|
||||||
|
|
||||||
|
[:div {:class "container"} body]
|
||||||
|
|
||||||
|
(render-footer)
|
||||||
|
]))
|
||||||
|
|
||||||
|
|
||||||
|
;; highlight functions do no conversion, take the format they highlight
|
||||||
|
;; render functions take edn and convert to the highlight format
|
||||||
|
;; download functions all take an edn and convert it in target format
|
||||||
|
;; edit functions all take an edn and present an editor in the target format
|
||||||
|
|
||||||
|
|
||||||
|
(defn render-yaml
|
||||||
|
"renders an edn into an highlighted yaml"
|
||||||
|
[data]
|
||||||
|
[:span
|
||||||
|
[:pre [:code {:class "yaml"}
|
||||||
|
(yaml/generate-string data)]]
|
||||||
|
[:script "hljs.initHighlightingOnLoad();"]])
|
||||||
|
|
||||||
|
(defn highlight-yaml
|
||||||
|
"renders a yaml text in highlighted html"
|
||||||
|
[data]
|
||||||
|
[:span
|
||||||
|
[:pre [:code {:class "yaml"}
|
||||||
|
data]]
|
||||||
|
[:script "hljs.initHighlightingOnLoad();"]])
|
||||||
|
|
||||||
|
|
||||||
|
(defn highlight-json
|
||||||
|
"renders a json text in highlighted html"
|
||||||
|
[data]
|
||||||
|
[:span
|
||||||
|
[:pre [:code {:class "json"}
|
||||||
|
data]]
|
||||||
|
[:script "hljs.initHighlightingOnLoad();"]])
|
||||||
|
|
||||||
|
(defn download-csv
|
||||||
|
"takes an edn, returns a csv plain/text for download"
|
||||||
|
[data]
|
||||||
|
{:headers {"Content-Type"
|
||||||
|
"text/plain; charset=utf-8"}
|
||||||
|
:body (with-out-str (csv/write-csv *out* data))})
|
||||||
|
|
||||||
|
(defn edit-edn
|
||||||
|
"renders an editor for the edn in yaml format"
|
||||||
|
[data]
|
||||||
|
[:div;; {:class "form-group"}
|
||||||
|
[:textarea {:class "form-control"
|
||||||
|
:rows "20" :data-editor "yaml"
|
||||||
|
:id "config" :name "editor"}
|
||||||
|
(yaml/generate-string data)]
|
||||||
|
[:script {:src "/static/js/ace.js"
|
||||||
|
:type "text/javascript" :charset "utf-8"}]
|
||||||
|
[:script {:type "text/javascript"}
|
||||||
|
(slurp (io/resource "public/static/js/ace-embed.js"))]
|
||||||
|
;; code to embed the ace editor on all elements in page
|
||||||
|
;; that contain the attribute "data-editor" set to the
|
||||||
|
;; mode language of choice
|
||||||
|
[:input {:class "btn btn-success btn-lg pull-top"
|
||||||
|
:type "submit" :value "submit"}]])
|
||||||
|
|
||||||
|
(def brand-img "/static/img/whale_toast.jpg")
|
||||||
|
(defn- hero-login-box [body]
|
||||||
|
[:section {:class "hero is-fullheight"}
|
||||||
|
[:div {:class "hero-body"}
|
||||||
|
[:div {:class "container has-text-centered"}
|
||||||
|
body
|
||||||
|
]]])
|
||||||
|
|
||||||
|
(def login-form
|
||||||
|
(hero-login-box
|
||||||
|
[:div {:class "column is-4 is-offset-4"}
|
||||||
|
[:h3 {:class "title has-text-grey"} "toaster.do"]
|
||||||
|
[:h4 {:class "subtitle has-text-grey"}
|
||||||
|
"from Docker to VM in a few clicks, powered by "
|
||||||
|
[:a {:href "https://decodeproject.eu"} "DECODEproject.EU"]]
|
||||||
|
[:p {:class "subtitle has-text-grey"}
|
||||||
|
"please login to operate"]
|
||||||
|
[:div {:class "box"}
|
||||||
|
[:figure {:class "avatar"}
|
||||||
|
[:img {:src brand-img }]]
|
||||||
|
[:form {:action "/login"
|
||||||
|
:method "post"}
|
||||||
|
[:div {:class "field"}
|
||||||
|
;; [:label {:class "label is-large"} "Email"]
|
||||||
|
[:div {:class "control has-icons-left"}
|
||||||
|
[:input {:type "email" :name "username"
|
||||||
|
:placeholder "Email"
|
||||||
|
:class "input is-large"}]
|
||||||
|
[:span {:class "icon is-small is-left"}
|
||||||
|
[:i {:class "fa fa-envelope fa-xs"}]]]]
|
||||||
|
[:div {:class "field"}
|
||||||
|
;; [:label {:class "label is-large"} "Password"]
|
||||||
|
[:div {:class "control has-icons-left"}
|
||||||
|
[:input {:type "password" :name "password"
|
||||||
|
:placeholder "Password"
|
||||||
|
:class "input is-large"}]
|
||||||
|
[:span {:class "icon is-small is-left"}
|
||||||
|
[:i {:class "fa fa-lock fa-xs"}]]]]
|
||||||
|
[:div {:class "field"}
|
||||||
|
[:p {:class "control"}
|
||||||
|
[:input {:type "submit" :value "Login"
|
||||||
|
:class "button is-block is-info is-large has-icons-left is-fullwidth"}]]]]]
|
||||||
|
[:p {:class "subtitle has-text-grey"}
|
||||||
|
"...or " [:a {:href "/signup"} "signup for a new account"]]]))
|
||||||
|
|
||||||
|
(def signup-form
|
||||||
|
(hero-login-box
|
||||||
|
[:div {:class "column is-4 is-offset-4"}
|
||||||
|
[:h3 {:class "title has-text-grey"} "toaster.do"]
|
||||||
|
[:h4 {:class "subtitle has-text-grey"}
|
||||||
|
"sign up for a new account"]
|
||||||
|
;; [:p {:class "subtitle has-text-grey"}]
|
||||||
|
[:div {:class "box"}
|
||||||
|
[:figure {:class "avatar"}
|
||||||
|
[:img {:src brand-img}]]
|
||||||
|
[:form {:action "/signup"
|
||||||
|
:method "post"}
|
||||||
|
[:div {:class "field"}
|
||||||
|
[:div {:class "control"}
|
||||||
|
[:input {:type "text" :name "name"
|
||||||
|
:placeholder "Name"
|
||||||
|
:class "input"}]]]
|
||||||
|
[:div {:class "field"}
|
||||||
|
[:div {:class "control"}
|
||||||
|
[:input {:type "email" :name "email"
|
||||||
|
:placeholder "Email"
|
||||||
|
:class "input"}]]]
|
||||||
|
[:div {:class "field"}
|
||||||
|
[:div {:class "control"}
|
||||||
|
[:input {:type "password" :name "password"
|
||||||
|
:placeholder "Password"
|
||||||
|
:class "input"}]]]
|
||||||
|
[:div {:class "field"}
|
||||||
|
[:div {:class "control"}
|
||||||
|
[:input {:type "password" :name "repeat-password"
|
||||||
|
:placeholder "Repeat password"
|
||||||
|
:class "input"}]]]
|
||||||
|
[:div {:class "field"}
|
||||||
|
[:div {:class "control"}
|
||||||
|
[:input {:type "submit" :value "Sign In"
|
||||||
|
:class "button is-block is-info is-large is-fullwidth"}]]]]]]))
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
[toaster.session :as s]
|
[toaster.session :as s]
|
||||||
[toaster.config :as conf]
|
[toaster.config :as conf]
|
||||||
[toaster.webpage :as web]
|
[toaster.bulma :as web]
|
||||||
[toaster.ring :as ring]
|
[toaster.ring :as ring]
|
||||||
[toaster.views :as views]
|
[toaster.views :as views]
|
||||||
[toaster.jobs :as job])
|
[toaster.jobs :as job])
|
||||||
|
@ -45,10 +45,24 @@
|
||||||
|
|
||||||
(defonce config (conf/load-config "toaster" conf/default-settings))
|
(defonce config (conf/load-config "toaster" conf/default-settings))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- login-page [request form]
|
||||||
|
(f/attempt-all
|
||||||
|
[acct (s/check-account request)]
|
||||||
|
(web/render acct
|
||||||
|
[:div {:class "container"}
|
||||||
|
[:h1 {:class "title"}
|
||||||
|
(str "Already logged in with account: "
|
||||||
|
(:email acct))]
|
||||||
|
[:h2 {:class "subtitle"}
|
||||||
|
[:a {:href "/logout"} "Logout"]]])
|
||||||
|
(f/when-failed [e]
|
||||||
|
(web/render form))))
|
||||||
|
|
||||||
(defroutes
|
(defroutes
|
||||||
app-routes
|
app-routes
|
||||||
|
|
||||||
(GET "/" request (web/render "Hello there!")) ;; web/readme))
|
(GET "/" request (login-page request web/login-form))
|
||||||
|
|
||||||
;; NEW ROUTES HERE
|
;; NEW ROUTES HERE
|
||||||
(GET "/upload" request
|
(GET "/upload" request
|
||||||
|
@ -63,11 +77,6 @@
|
||||||
(web/render acct (views/dockerfile-upload-post req conf acct)))
|
(web/render acct (views/dockerfile-upload-post req conf acct)))
|
||||||
(s/check request)))
|
(s/check request)))
|
||||||
|
|
||||||
(GET "/edit" request
|
|
||||||
(->> (fn [req conf acct]
|
|
||||||
(web/render acct views/dockerfile-edit-form))
|
|
||||||
(s/check request)))
|
|
||||||
|
|
||||||
(GET "/list" request
|
(GET "/list" request
|
||||||
(->> (fn [req conf acct]
|
(->> (fn [req conf acct]
|
||||||
(web/render acct (views/list-jobs acct)))
|
(web/render acct (views/list-jobs acct)))
|
||||||
|
@ -96,16 +105,8 @@
|
||||||
(s/check request)))
|
(s/check request)))
|
||||||
|
|
||||||
;; JUST-AUTH ROUTES
|
;; JUST-AUTH ROUTES
|
||||||
(GET "/login" request
|
(GET "/login" request (login-page request web/login-form))
|
||||||
(f/attempt-all
|
|
||||||
[acct (s/check-account request)]
|
|
||||||
(web/render acct
|
|
||||||
[:div
|
|
||||||
[:h1 (str "Already logged in with account: "
|
|
||||||
(:email acct))]
|
|
||||||
[:h2 [:a {:href "/logout"} "Logout"]]])
|
|
||||||
(f/when-failed [e]
|
|
||||||
(web/render web/login-form))))
|
|
||||||
(POST "/login" request
|
(POST "/login" request
|
||||||
(f/attempt-all
|
(f/attempt-all
|
||||||
[username (s/param request :username)
|
[username (s/param request :username)
|
||||||
|
@ -123,15 +124,15 @@
|
||||||
;; [:h1 "Logged in: " username]
|
;; [:h1 "Logged in: " username]
|
||||||
;; views/welcome-menu])))
|
;; views/welcome-menu])))
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(web/render-error-page
|
(web/render (web/render-error
|
||||||
(str "Login failed: " (f/message e))))))
|
(str "Login failed: " (f/message e)))))))
|
||||||
(GET "/session" request
|
|
||||||
(-> (:session request) web/render-yaml web/render))
|
|
||||||
(GET "/logout" request
|
(GET "/logout" request
|
||||||
(conj {:session {:config config}}
|
(conj {:session {:config config}}
|
||||||
(web/render [:h1 "Logged out."])))
|
(web/render [:div {:class "container"}
|
||||||
(GET "/signup" request
|
[:h1 {:class "title"} "Logged out."]])))
|
||||||
(web/render web/signup-form))
|
|
||||||
|
(GET "/signup" request (login-page request web/signup-form))
|
||||||
(POST "/signup" request
|
(POST "/signup" request
|
||||||
(f/attempt-all
|
(f/attempt-all
|
||||||
[name (s/param request :name)
|
[name (s/param request :name)
|
||||||
|
@ -160,8 +161,10 @@
|
||||||
(web/render-error
|
(web/render-error
|
||||||
"Repeat password didnt match")))
|
"Repeat password didnt match")))
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(web/render-error-page
|
(web/render
|
||||||
(str "Sign-up failure: " (f/message e))))))
|
(web/render-error
|
||||||
|
(str "Sign-up failure: " (f/message e)))))))
|
||||||
|
|
||||||
(GET "/activate/:email/:activation-id"
|
(GET "/activate/:email/:activation-id"
|
||||||
[email activation-id :as request]
|
[email activation-id :as request]
|
||||||
(let [activation-uri
|
(let [activation-uri
|
||||||
|
@ -189,7 +192,8 @@
|
||||||
(s/param request :message)]))
|
(s/param request :message)]))
|
||||||
|
|
||||||
(route/resources "/")
|
(route/resources "/")
|
||||||
(route/not-found (web/render-error-page "Page Not Found"))
|
(route/not-found (web/render (web/render-error "Page Not Found")))
|
||||||
|
|
||||||
) ;; end of routes
|
) ;; end of routes
|
||||||
|
|
||||||
(def app
|
(def app
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.contrib.humanize :as humanize :refer [datetime]]
|
[clojure.contrib.humanize :as humanize :refer [datetime]]
|
||||||
;; [clojure.data.json :as json :refer [read-str]]
|
;; [clojure.data.json :as json :refer [read-str]]
|
||||||
[toaster.webpage :as web]
|
[toaster.bulma :as web]
|
||||||
[toaster.session :as s]
|
[toaster.session :as s]
|
||||||
[toaster.ring :as ring]
|
[toaster.ring :as ring]
|
||||||
[toaster.jobs :as job]
|
[toaster.jobs :as job]
|
||||||
|
@ -20,24 +20,33 @@
|
||||||
[hiccup.form :as hf]))
|
[hiccup.form :as hf]))
|
||||||
|
|
||||||
(def dockerfile-upload-form
|
(def dockerfile-upload-form
|
||||||
[:div {:class "container-fluid"}
|
[:div {:class "container"}
|
||||||
[:h1 "Upload a Dockerfile to toast"]
|
[:h1 {:class "title"} "Upload a Dockerfile to toast"]
|
||||||
[:p " Choose the file in your computer and click 'Submit' to
|
[:p " Choose the file in your computer and click 'Submit' to
|
||||||
proceed to validation."]
|
proceed to validation."]
|
||||||
[:div {:class "form-group"}
|
|
||||||
[:form {:action "dockerfile" :method "post"
|
[:form {:action "dockerfile" :method "post"
|
||||||
:class "form-shell"
|
:class "form-shell"
|
||||||
:enctype "multipart/form-data"}
|
:enctype "multipart/form-data"}
|
||||||
[:fieldset {:class "fieldset btn btn-default btn-file btn-lg"}
|
[:div {:class "file has-label is-fullwidth"}
|
||||||
[:input {:name "file" :type "file"}]]
|
[:label {:class "file-label"}
|
||||||
|
[:input {:class "file-input" :name "file" :type "file"}]
|
||||||
|
[:span {:class "file-cta"}
|
||||||
|
[:span {:class "file-icon"}
|
||||||
|
[:i {:class "fa fa-upload"}]]
|
||||||
|
[:span {:class "file-label"}
|
||||||
|
"Docker file..."]]
|
||||||
|
[:span {:class "file-name"}]]]
|
||||||
;; [:fieldset {:class "fieldset-submit"}
|
;; [:fieldset {:class "fieldset-submit"}
|
||||||
[:input {:class "btn btn-primary btn-lg"
|
|
||||||
:id "field-submit" :type "submit"
|
[:div {:class "field"}
|
||||||
:name "submit" :value "submit"}]]]])
|
[:div {:class "control"}
|
||||||
|
[:input {:class "button is-block is-info is-large is-fullwidth"
|
||||||
|
:type "submit"
|
||||||
|
:name "submit" :value "submit"}]]]]])
|
||||||
|
|
||||||
(def dockerfile-edit-form
|
(def dockerfile-edit-form
|
||||||
[:div {:class "container-fluid"}
|
[:div {:class "container"}
|
||||||
[:h1 "Edit your Dockerfile to toast"]
|
[:h1 {:class "title"} "Edit your Dockerfile to toast"]
|
||||||
[:div {:class "form-group"}
|
[:div {:class "form-group"}
|
||||||
[:form {:action "dockerfile" :method "post"
|
[:form {:action "dockerfile" :method "post"
|
||||||
:class "form-shell"
|
:class "form-shell"
|
||||||
|
@ -53,13 +62,6 @@ proceed to validation."]
|
||||||
editor.session.setMode(\"ace/mode/dockerfile\");"]])
|
editor.session.setMode(\"ace/mode/dockerfile\");"]])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(def welcome-menu
|
|
||||||
[:div {:class "container-fluid"}
|
|
||||||
[:div {:class "row-fluid"}
|
|
||||||
[:div {:class "row"} [:a {:href "/list"} "List all your toaster jobs"]]
|
|
||||||
[:div {:class "row"} [:a {:href "/upload"} "Upload a new toaster job"]]]])
|
|
||||||
|
|
||||||
(defn dockerfile-upload-post [request config account]
|
(defn dockerfile-upload-post [request config account]
|
||||||
(let
|
(let
|
||||||
[tempfile (get-in request [:params :file :tempfile])
|
[tempfile (get-in request [:params :file :tempfile])
|
||||||
|
@ -79,17 +81,19 @@ proceed to validation."]
|
||||||
(log/spy :error
|
(log/spy :error
|
||||||
[:h1 (str "Uploaded file not found: " filename)]))
|
[:h1 (str "Uploaded file not found: " filename)]))
|
||||||
;; file is now in 'tmp' var
|
;; file is now in 'tmp' var
|
||||||
[:div {:class "container-fluid"}
|
[:div {:class "container"}
|
||||||
[:h1 "Job uploaded and added"]
|
[:h1 {:class "title"} "Job uploaded and added"]
|
||||||
[:p "Log messages:"]
|
[:p "Log messages:"]
|
||||||
(web/render-yaml (job/add path config account))])))))
|
(web/render-yaml (job/add path config account))])))))
|
||||||
|
|
||||||
(defn list-jobs [account]
|
(defn list-jobs [account]
|
||||||
(f/attempt-all
|
(f/attempt-all
|
||||||
[joblist (db/query @ring/jobs {:email (:email account)})]
|
[joblist (db/query @ring/jobs {:email (:email account)})]
|
||||||
[:div {:class "container-fluid"}
|
[:div {:class "container has-text-centered"}
|
||||||
[:h1 (str "List all toaster jobs for " (:name account))]
|
[:h1 {:class "title"} (str "List all toaster jobs for " (:name account))]
|
||||||
[:table {:class "sortable table"}
|
|
||||||
|
[:div {:class "box"}
|
||||||
|
[:table {:class "table is-fullwidth is-hoverable"}
|
||||||
[:thead nil
|
[:thead nil
|
||||||
[:tr nil [:th nil "Date"] [:th nil "Type"] [:th nil "Status"] [:th nil "Actions"]]]
|
[:tr nil [:th nil "Date"] [:th nil "Type"] [:th nil "Status"] [:th nil "Actions"]]]
|
||||||
[:tbody nil
|
[:tbody nil
|
||||||
|
@ -104,11 +108,11 @@ proceed to validation."]
|
||||||
[:td {:class "status"} [:a {:href (str "https://sdk.dyne.org:4443/job/" joburl "/lastBuild/console")}
|
[:td {:class "status"} [:a {:href (str "https://sdk.dyne.org:4443/job/" joburl "/lastBuild/console")}
|
||||||
[:img {:src (str "https://sdk.dyne.org:4443/job/" joburl "/badge/icon")}]]]
|
[:img {:src (str "https://sdk.dyne.org:4443/job/" joburl "/badge/icon")}]]]
|
||||||
[:td {:class "actions"}
|
[:td {:class "actions"}
|
||||||
[:div {:class "btn-toolbar" :role "toolbar" :arial-label "Actions"}
|
[:div {:class "field is-grouped"}
|
||||||
(web/button "/view" "\uD83D\uDC41" (hf/hidden-field "jobid" jobid))
|
(web/button "/view" "\uD83D\uDC41" (hf/hidden-field "jobid" jobid))
|
||||||
(web/button "/start" "▶" (hf/hidden-field "jobid" jobid))
|
(web/button "/start" "▶" (hf/hidden-field "jobid" jobid))
|
||||||
(web/button "/remove" "\uD83D\uDDD1" (hf/hidden-field "jobid" jobid))]]]
|
(web/button "/remove" "\uD83D\uDDD1" (hf/hidden-field "jobid" jobid))]]]
|
||||||
))]]]
|
))]]]]
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(web/render-error
|
(web/render-error
|
||||||
(str "Job list failure: " (f/message e))))))
|
(str "Job list failure: " (f/message e))))))
|
||||||
|
@ -120,7 +124,10 @@ proceed to validation."]
|
||||||
jobfound (db/query @ring/jobs {:jobid jobid})
|
jobfound (db/query @ring/jobs {:jobid jobid})
|
||||||
r_rmjob (db/delete! @ring/jobs jobid)
|
r_rmjob (db/delete! @ring/jobs jobid)
|
||||||
r_sync (job/trash jobid config)]
|
r_sync (job/trash jobid config)]
|
||||||
[:h1 (str "Job removed: " jobid)]
|
[:span
|
||||||
|
[:div {:class "notification is-primary has-text-centered"}
|
||||||
|
(str "Job removed: " jobid)]
|
||||||
|
(list-jobs account)]
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(web/render-error (str "Failure removing job: " (f/message e))))))
|
(web/render-error (str "Failure removing job: " (f/message e))))))
|
||||||
|
|
||||||
|
@ -129,7 +136,7 @@ proceed to validation."]
|
||||||
[jobid (s/param request :jobid)
|
[jobid (s/param request :jobid)
|
||||||
jobfound (db/query @ring/jobs {:jobid jobid})
|
jobfound (db/query @ring/jobs {:jobid jobid})
|
||||||
r_sync (job/start jobid config)]
|
r_sync (job/start jobid config)]
|
||||||
[:div {:class "container-fluid"}
|
[:div {:class "container"}
|
||||||
[:h1 (str "Job started: " jobid)]
|
[:h1 (str "Job started: " jobid)]
|
||||||
[:p [:a {:href (str "https://sdk.dyne.org:4443/view/web-sdk-builds/job/"
|
[:p [:a {:href (str "https://sdk.dyne.org:4443/view/web-sdk-builds/job/"
|
||||||
(str/replace jobid #"@" "AT"))}]]]
|
(str/replace jobid #"@" "AT"))}]]]
|
||||||
|
@ -141,8 +148,8 @@ proceed to validation."]
|
||||||
[jobid (s/param request :jobid)
|
[jobid (s/param request :jobid)
|
||||||
jobfound (db/fetch @ring/jobs jobid)
|
jobfound (db/fetch @ring/jobs jobid)
|
||||||
dockerfile (log/spy (-> jobfound :dockerfile))]
|
dockerfile (log/spy (-> jobfound :dockerfile))]
|
||||||
(web/render account [:div
|
[:div {:class "container"}
|
||||||
[:h1 (str "Viewing job: " jobid)]
|
[:h1 {:class "title"} (str "Viewing job: " jobid)]
|
||||||
[:pre dockerfile]])
|
[:pre dockerfile]]
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(web/render-error (str "Failure viewing job: " (f/message e))))))
|
(web/render-error (str "Failure viewing job: " (f/message e))))))
|
||||||
|
|
|
@ -301,7 +301,7 @@
|
||||||
;; (defonce readme
|
;; (defonce readme
|
||||||
;; (slurp (io/resource "public/static/README.html")))
|
;; (slurp (io/resource "public/static/README.html")))
|
||||||
|
|
||||||
(defonce login-form
|
(def login-form
|
||||||
[:div
|
[:div
|
||||||
[:h1 "Login for your account"
|
[:h1 "Login for your account"
|
||||||
[:form {:action "/login"
|
[:form {:action "/login"
|
||||||
|
@ -318,7 +318,7 @@
|
||||||
:class "btn btn-primary btn-lg btn-block"
|
:class "btn btn-primary btn-lg btn-block"
|
||||||
:style "margin-top: 1em"}]]]])
|
:style "margin-top: 1em"}]]]])
|
||||||
|
|
||||||
(defonce signup-form
|
(def signup-form
|
||||||
[:div
|
[:div
|
||||||
[:h1 "Sign Up for a toaster account"
|
[:h1 "Sign Up for a toaster account"
|
||||||
[:form {:action "/signup"
|
[:form {:action "/signup"
|
||||||
|
|
Loading…
Reference in New Issue