(ns com.fulcrologic.rad.rendering.semantic-ui.controls.instant-inputs (:require [clojure.string :as str] [com.fulcrologic.guardrails.core :refer [>defn => ?]] [com.fulcrologic.rad.type-support.date-time :as dt] [com.fulcrologic.rad.rendering.semantic-ui.controls.control :as control] [cljc.java-time.local-time :as lt] [com.fulcrologic.fulcro.dom.events :as evt] #?(:clj [com.fulcrologic.fulcro.dom-server :as dom] :cljs [com.fulcrologic.fulcro.dom :as dom]) [cljc.java-time.local-date-time :as ldt] [cljc.java-time.local-date :as ld] #?@(:cljs [[ch.lyrion.carbon.date-picker.ui-date-picker :refer [ui-date-picker]] [ch.lyrion.carbon.date-picker-input.ui-date-picker-input :refer [ui-date-picker-input]]]))) (defn ui-date-instant-input [{::keys [default-local-time]} {:keys [value onChange local-time] :as props}] #?(:cljs (let [value (dt/inst->html-date (or value (dt/now))) local-time (or local-time default-local-time)] (ui-date-picker {:id (str (hash props) "-picker") :datePickerType "single" :dateFormat "Y-m-d" :value value :onChange (fn [evt] (when onChange (let [date (.toJSON (first evt)) date-string (first (str/split date "T")) instant (dt/html-date->inst date-string local-time)] (onChange instant))))} (ui-date-picker-input {:id (str (dt/now) "ui-date-instant-input")}))))) (defn ui-ending-date-instant-input "Display the date the user selects, but control a value that is midnight on the next date. Used for generating ending instants that can be used for a proper non-inclusive end date." [_ {:keys [value onChange] :as props}] #?(:cljs (let [today (dt/inst->local-datetime (or value (dt/now))) display-date (ldt/to-local-date (ldt/minus-days today 1)) value (dt/local-date->html-date-string display-date)] (ui-date-picker {:id (str (hash props) "-picker") :datePickerType "single" :dateFormat "Y-m-d" :value value :onChange (fn [evt] (when onChange (let [date (.toJSON (first evt)) date-string (first (str/split date "T")) tomorrow (ld/at-time (ld/plus-days (dt/html-date-string->local-date date-string) 1) lt/midnight) instant (dt/local-datetime->inst tomorrow)] (onChange instant))))} (ui-date-picker-input {:id (str (hash props) "-picker-input")}))))) (defn ui-date-time-instant-input [_ {:keys [disabled? value onChange] :as props}] (let [value (dt/inst->html-datetime-string (or value (dt/now)))] (dom/input (merge props (cond-> {:value value :type "date" :onChange (fn [evt] (when onChange (let [date-time-string (evt/target-value evt) instant (dt/html-datetime-string->inst date-time-string)] (onChange instant))))} disabled? (assoc :readOnly true)))))) (defn date-time-control [render-env] (control/ui-control (assoc render-env :input-factory ui-date-time-instant-input))) (defn midnight-on-date-control [render-env] (control/ui-control (assoc render-env :input-factory ui-date-instant-input ::default-local-time lt/midnight))) (defn midnight-next-date-control [render-env] (control/ui-control (assoc render-env :input-factory ui-ending-date-instant-input))) (defn date-at-noon-control [render-env] (control/ui-control (assoc render-env ::default-local-time lt/noon :input-factory ui-date-instant-input)))