Ab sofort ist der Login auf der Weboberfläche von git.fh-muenster.de bevorzugt über FH Muenster SSO möglich.

Commit b6a69968 authored by Bruno Burke's avatar Bruno Burke 😁

restructure bulma component files

parent 8b075062
(ns lernmeister.components.bulma.card)
(defn card-panel [& content]
[:div.card
[:div.card-content
(apply vector
:div.content
content)]])
(defn card [{:keys [title footer-items class]} content]
[:div.card {:class class}
(when title
[:header.card-header
[:p.card-header-title
title]])
[:div.card-content content]
(when (pos? (count footer-items))
[:footer.card-footer
(for [fi footer-items]
^{:key (hash fi)} [:span.card-footer-item fi])])])
(ns lernmeister.components.bulma.core
(:require [reagent.core :as reagent]
[clojure.string :refer [lower-case split]]
[lernmeister.components.jshelper :refer [execute-and-reset]]
[lernmeister.components.bulma.table :as bulma-table]
[lernmeister.components.bulma.common :refer [icon]]
[oops.core :refer [oget]]))
(def table bulma-table/table)
(defonce toastcounter (atom 0))
(defn card-panel [& content]
[:div.card
[:div.card-content
(apply vector
:div.content
content)]])
(defn card [{:keys [title footer-items class]} content]
[:div.card {:class class}
(when title
[:header.card-header
[:p.card-header-title
title]])
[:div.card-content content]
(when (pos? (count footer-items))
[:footer.card-footer
(for [fi footer-items]
^{:key (hash fi)} [:span.card-footer-item fi])])])
(defn radiobutton
[{:keys [name disabled? on-change checked? label]}]
(let [id (gensym "radiobutton")]
......@@ -167,286 +142,6 @@
[:span.lever]
(or label-right "")]])})))
(defn select
[{:keys [value on-change options label multiple
choose-option-label]}]
(let [id (gensym "select")
instance (reagent/atom nil)
change-fn (reagent/atom on-change)]
(reagent/create-class
{:display-name "input-select-component"
:reagent-render
(fn [{:keys [value on-change options label disabled multiple
choose-option-label]}]
[:div.field
[:label.label {:for id} label]
[:div.select.control.is-fullwidth
{:class (when multiple
"is-multiple")}
[:select
{:id id
:disabled disabled
:multiple multiple
:value (if multiple
(or value [])
(or value ""))
:on-change (fn [event]
(js/console.log multiple)
(let [value (-> event
.-target
.-value)]
(when on-change
(on-change
(if multiple
(set (map (fn [o]
(keyword (.-value o)))
(-> event
.-target
.-selectedOptions
array-seq)))
(keyword value))))))}
[:option {:value ""
:disabled true}
(or choose-option-label "Bitte wählen")]
(when options
(doall
(for [o options]
(let [key (or (:key o) (first o))
title (or (:title o) (:label o) (second o))]
[:option {:value (name key)
:key (str id "-" key)}
title]))))]]])})))
(defn select*
[{:keys [cursor options label multiple
choose-option-label on-change]}]
(let [id (gensym "select")
instance (reagent/atom nil)
get-element #(js/document.querySelector (str "#" id))]
(reagent/create-class
{:display-name "select*-component"
:reagent-render
(fn [{:keys [cursor options label multiple
choose-option-label on-change]}]
[select
{:value @cursor
:options options
:label label
:multiple multiple
:choose-option-label choose-option-label
:on-change (fn [value]
(reset! cursor value)
(when on-change
(on-change cursor)))}])})))
(defn tags-editor
[{:keys [tags label placeholder prefix-icon]}]
(let [add-element? (reagent/atom nil)
new-element (reagent/atom "")]
(reagent/create-class
{:reagent-render
(fn [{:keys [tags label placeholder prefix-icon]}]
(let [tags-set (into #{} (filter (comp not clojure.string/blank?) @tags))]
[:div.field.is-grouped.is-grouped-multiline
(for [t tags-set]
^{:key (str "tags" t)}
[:div.control
[:div.tags.has-addons
[:span.tag
t]
[:a.tag.is-delete {:on-click #(swap! tags (fn [tags]
(set (remove (partial = t) tags))))}]]])
(if @add-element?
[:div.control.level
[:div.level-item
[input-text
{:value @new-element
:on-change #(reset! new-element %)}]]
[:div.level-item
[:button.button {:on-click #(do
(swap! tags (fn [t]
(-> t
(conj @new-element)
set)))
(reset! new-element "")
(swap! add-element? not))}
[:span.icon [:i.fas.fa-check]]]]
[:div.level-item
[:button.button {:on-click #(do
(reset! new-element "")
(swap! add-element? not))}
[:span.icon [:i.fas.fa-times]]]]]
[:div.control
[:div.tags
[:a.tag {:on-click #(swap! add-element? not)}
[:span.icon [:i.fas.fa-plus]]]]])]))})))
(defn tags
[{:keys [tags label placeholder prefix-icon]}]
(reagent/create-class
{:reagent-render
(fn [{:keys [tags label placeholder prefix-icon]}]
(let [tags-set (into #{} (filter (comp not clojure.string/blank?) tags))]
[:div.field.is-grouped.is-grouped-multiline
(for [t tags-set]
^{:key (str "tags" t)}
[:div.control
[:div.tags.has-addons
[:span.tag t]]])]))}))
(def chips tags-editor) ;;fallback
(defn navbar
[{:keys [links active-link brand brand-align
links-position
side-nav
side-nav-id
color
font-color
fixed
side-nav-trigger-position :left
side-nav-trigger-position]
:or {brand false
brand-align "right"
side-nav false
color "purple"
font-color "black"}}]
(let [navbar-id (gensym "navbar")]
(reagent/create-class
{:reagent-render
(fn [{:keys [links active-link brand brand-align
links-position
side-nav
side-nav-id
color
font-color
fixed
side-nav-trigger-position]
:or {brand false
side-nav false
side-nav-trigger-position :left
color "purple"
font-color "black"}}]
[:nav.navbar {:class (when fixed "navbar-fixed")}
(when brand
[:div.navbar-brand {:class (str "brand-logo " (when brand-align
(name brand-align)))}
[:a.navbar-item brand]])
[:div.navbar-menu
[:div.navbar-start
(when (and side-nav (= (keyword side-nav-trigger-position) :left))
[:a.navbar-burger {:href "#"
:data-target side-nav-id}
[:i.material-icons "menu"]])
(for [nl links]
[:a.navbar-item {:key (hash nl)
:href (:route nl)
:style {:color font-color}}
(when (:icon nl)
[icon (:icon nl) :class "left"]) (:label nl)])]
[:div.navbar-end
(when (and side-nav (= (keyword side-nav-trigger-position) :right))
[:a.sidenav-trigger.right {:href "#"
:data-target side-nav-id}
[:i.material-icons "menu"]])]]])})))
(defn side-nav [& {:keys [links active-link
side-nav-id
edge]
:or {side-nav-id (gensym "side-nav")
edge "left"}}]
(let [instance (reagent/atom nil)
id side-nav-id]
(reagent/create-class
{:component-did-mount #(let [elem (js/document.querySelector (str "#" id))]
#_(reset! instance
(js/M.Sidenav.init elem (clj->js {:closeOnClick true
:draggable true
:edge edge}))))
:reagent-render
(fn [& {:keys [links active-link
side-nav-id
edge]
:or {side-nav-id (gensym "side-nav")
edge "left"}}]
[:p ""]
#_[:ul.sidenav {:id id}
(for [nl links]
[:li {:class (when (= (:panel nl) active-link) ["active"])
:key (str id "_" (:label nl))}
[:a {:href (:route nl)
:on-click #(.close @instance)}
(when (:icon nl)
[icon (:icon nl) :class "left"]) (:label nl)]])])})))
(defonce toastbox-id (str (gensym "toastbox")))
(defn get-toastbox []
(if-let [toastbox (js/document.getElementById toastbox-id)]
toastbox
(let [div (js/document.createElement "div")]
(set! (.-id div) toastbox-id)
(set! (.-classList div) (str "toastbox"))
(js/document.body.appendChild div)
(recur))))
(defn toast
[& {:keys [html displayLength classes]}]
(let [div (js/document.createElement "div")
initial-classes (str "notification toast " classes)]
(set! (.-innerHTML div) html)
(set! (.-classList div) initial-classes)
(js/setTimeout #(do
(set! (.-classList div) initial-classes)
;;;wait css fade-out
(js/setTimeout (fn []
(.remove div)) 1000))
(or displayLength 1000))
(.appendChild (get-toastbox) div)
(set! (.-classList div) (str (.-classList div) " active")))
#_(js/M.toast (clj->js (merge {:html html}
(when displayLength
{:displayLength displayLength})
(when classes
{:classes classes})))))
(defn modal-panel [{:keys [title state footer subject on-close-fn]} & content]
(let [close-fn (fn []
(execute-and-reset on-close-fn subject)
(reset! state false))]
[:div.modal {:class (str (when @state
"is-active"))}
[:div.modal-background {:on-click close-fn}]
[:div.modal-card
[:header.modal-card-head
[:span.modal-card-title (or title "")]
[:button.delete {:on-click close-fn}]]
(into [:div.modal-card-body]
content)
(when footer
[:footer.modal-card-foot
footer])]]))
(defn open-modal [selector-tag]
#_(.open (js/M.Modal.getInstance (js/document.querySelector selector-tag))))
(defn close-modal [selector-tag]
#_(.close (js/M.Modal.getInstance (js/document.querySelector selector-tag))))
(defn modal-exists? [selector-tag]
#_(try
(js/M.Modal.getInstance (js/document.querySelector selector-tag))
(catch js/Error. e
nil)))
(defn init-modal [selector-tag]
#_(if-let [instance (modal-exists? selector-tag)]
instance
(js/M.Modal.init (js/document.querySelector selector-tag))))
(defn tooltip [{:keys [selector-tag label]}]
(js/M.Tooltip.init (js/document.querySelector selector-tag) (clj->js {:html label})))
......@@ -508,203 +203,6 @@
(when-let [td (nth tabs @selected-tab)]
(:component td))]])})))
(defn parseDate [date]
(if (not-empty date)
(let [parts (split (js->clj date) ".")
parsed-date (js/Date. (js/Number. (get parts 2))
(- (js/Number. (get parts 1)) 1)
(js/Number. (get parts 0)))]
parsed-date)
(new js/Date)))
(def weekdays ["Sonntag"
"Montag"
"Dienstag"
"Mittwoch"
"Donnerstag"
"Freitag"
"Samstag"])
(def calendar-settings
{:i18n {:months ["Januar"
"Februar"
"März"
"April"
"Mai"
"Juni"
"Juli"
"August"
"September"
"Oktober"
"November"
"Dezember"]
:monthsShort ["Jan"
"Feb"
"Mär"
"Apr"
"Mai"
"Jun"
"Jul"
"Aug"
"Sep"
"Okt"
"Nov"
"Dez"]
:weekdays weekdays
:weekdaysShort ["So"
"Mo"
"Di"
"Mi"
"Do"
"Fr"
"Sa"]
:weekdaysAbbrev ["S"
"M"
"D"
"M"
"D"
"F"
"S"]}
:firstDay 1
:format "dd.mm.yyyy"
:parse parseDate
:showDaysInNextAndPreviousMonths true})
(defn format-date [date]
(let [month (+ (.getMonth date) 1)
day (.getDate date)]
(str (.getFullYear date)
"-"
(when-not (>= month 10)
0)
(+ (.getMonth date) 1)
"-"
(when-not (>= day 10)
0)
day)))
(defn datepicker [{:keys [field-class icon input-class input-size
label-icon value placeholder on-change
label disabled tooltip autocomplete]}]
(fn [{:keys [field-class icon input-class input-size
label-icon value placeholder on-change
label disabled tooltip autocomplete]}]
[:div.field
[:label.label
label]
[:div.control
[:input {:type :date
:disabled disabled
:value (when value
(format-date value))
:on-change #(on-change
(-> %
.-target
.-valueAsDate))}]]]))
#_(defn datepicker
[{:keys [field-class icon input-class input-size
label-icon value placeholder on-change
label disabled tooltip autocomplete]}]
(let [id (gensym "datepicker")
instance (reagent/atom nil)]
(reagent/create-class
{:component-did-mount
(fn []
(let [elems (js/document.querySelectorAll (str "#" id))]
(reset! instance
(.attach js/bulmaCalendar (str "[id=" id "]")
(clj->js {:displayMode "dialog"})))
(when-let [calendar (first @instance)]
(.value calendar value)
(.on calendar "select"
(fn [event]
(on-change (oget event "data.date.start")))))))
:component-did-update (fn [this _]
#_(let [[{:keys [value]}] (rest (reagent/argv this))]
(when-let [calendar (first @instance)]
(.value calendar value))))
:reagent-render
(fn [{:keys [field-class icon input-class input-size
label-icon value placeholder on-change
label disabled tooltip autocomplete]}]
[:div.field
;;;TODO https://reactjs.org/docs/integrating-with-other-libraries.html
(when label
[:label.label {:for id} label])
[:div.control.has-icons-left
[:span.icon.is-left [:i.fas.fa-calendar]]
[:input.input {:type "date"
:id id
:disabled disabled
:class input-class
:data-date value
:placeholder (or placeholder "")
:default-value (when value
(str (.getFullYear value)
"-"
(+ (.getMonth value) 1)
"-"
(.getDate value)))
;;:on-change #(on-change (js/Date. (-> % .-target .-value)))
}]]])})))
(defn timepicker [{:keys [field-class icon input-class input-size
label-icon value placeholder on-change
label disabled tooltip autocomplete]}]
(fn [{:keys [field-class icon input-class input-size
label-icon value placeholder on-change
label disabled tooltip autocomplete]}]
[:div.field
[:label.label
label]
[:div.control
[:input {:type :time
:value value
:on-change #(on-change
(-> %
.-target
.-value))}]]]))
#_(defn timepicker
[{:keys [field-class icon input-class input-size
value on-change placeholder label
disabled tooltip autocomplete]}]
(let [id (gensym "timepicker")
instances (reagent/atom nil)]
(reagent/create-class
{:component-did-mount
(fn []
(let [elems (js/document.querySelectorAll (str "#" id))]
(reset! instances
(first (js/M.Timepicker.init
elems
(clj->js {:twelveHour false
:autoClose true
:onCloseEnd #(when-let [time (.-time @instances)]
(on-change time))}))))))
:reagent-render
(fn [{:keys [field-class icon input-class input-size
placeholder value on-change label
disabled tooltip autocomplete]}]
[:div.input-field
(when icon
[:i.material-icons.prefix
icon])
[:input {:type "text"
:id id
:class input-class
:disabled disabled
:placeholder (or placeholder "")
:read-only true
:value (or value "")}]
(when label
[:label.active {:for id} label])])})))
(defn indeterminate-progress []
(let [percentage (str (+ 5 (rand-int 50)) "%")]
[:progress.progress.is-info {:max "100"}
......
(ns lernmeister.components.bulma.datetime)
(defn parseDate [date]
(if (not-empty date)
(let [parts (split (js->clj date) ".")
parsed-date (js/Date. (js/Number. (get parts 2))
(- (js/Number. (get parts 1)) 1)
(js/Number. (get parts 0)))]
parsed-date)
(new js/Date)))
(def weekdays ["Sonntag"
"Montag"
"Dienstag"
"Mittwoch"
"Donnerstag"
"Freitag"
"Samstag"])
(def calendar-settings
{:i18n {:months ["Januar"
"Februar"
"März"
"April"
"Mai"
"Juni"
"Juli"
"August"
"September"
"Oktober"
"November"
"Dezember"]
:monthsShort ["Jan"
"Feb"
"Mär"
"Apr"
"Mai"
"Jun"
"Jul"
"Aug"
"Sep"
"Okt"
"Nov"
"Dez"]
:weekdays weekdays
:weekdaysShort ["So"