summaryrefslogtreecommitdiff
path: root/lisp/webapps/dns-admin/clojurescript/dnsadmin/src
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/webapps/dns-admin/clojurescript/dnsadmin/src')
-rw-r--r--lisp/webapps/dns-admin/clojurescript/dnsadmin/src/core.cljs673
1 files changed, 673 insertions, 0 deletions
diff --git a/lisp/webapps/dns-admin/clojurescript/dnsadmin/src/core.cljs b/lisp/webapps/dns-admin/clojurescript/dnsadmin/src/core.cljs
new file mode 100644
index 0000000..8b760de
--- /dev/null
+++ b/lisp/webapps/dns-admin/clojurescript/dnsadmin/src/core.cljs
@@ -0,0 +1,673 @@
+(ns dnsadmin.core
+ (:require-macros [hiccups.core :as hiccups :refer [html]])
+ (:require [ajax.core :refer [GET POST]]
+ [dommy.core :as dommy]
+ [hiccups.runtime :as hiccupsrt]))
+
+;; declarations
+
+(enable-console-print!)
+
+(declare null-or-empty-p)
+(declare reduce-checkboxes)
+(declare template-message)
+(declare maybe-errormsg)
+(declare maybe-message)
+(declare notifications)
+(declare auth-notifications)
+(declare template-generic-form)
+(declare template-dns)
+(declare handler-dns)
+(declare render-dns)
+(declare navigate-to)
+(declare handler-location)
+(declare goto-location)
+(declare reset-app)
+(declare template-dns-login-get)
+(declare handler-dns-login-get)
+(declare render-dns-login-get)
+(declare on-dns-login-get-clicked)
+(declare handler-dns-login-post)
+(declare render-dns-login-post)
+(declare template-dns-headers)
+(declare handler-dns-headers)
+(declare render-dns-headers)
+(declare on-dns-select-recordtype-changed)
+(declare template-dns-api-search-get)
+(declare handler-dns-api-search-get)
+(declare render-dns-api-search-get)
+(declare on-dns-api-search-get-clicked)
+(declare template-dns-api-search-post-loading)
+(declare template-dns-api-search-post)
+(declare handler-dns-api-search-post)
+(declare render-dns-api-search-post)
+(declare on-dns-api-add-clicked)
+(declare template-dns-api-add-get)
+(declare handler-dns-api-add-get)
+(declare render-dns-api-add-get)
+(declare on-dns-add-get-clicked)
+(declare handler-dns-api-add-post)
+(declare render-dns-api-add-post)
+(declare on-dns-modify-api-clicked)
+(declare template-dns-api-modify-get)
+(declare handler-dns-api-modify-get)
+(declare render-dns-api-modify-get)
+(declare on-dns-api-modify-post-clicked)
+(declare handler-dns-api-modify-post)
+(declare render-dns-api-modify-post)
+(declare on-dns-api-delete-clicked)
+(declare handler-dns-api-delete-post)
+(declare render-dns-api-delete-post)
+(declare on-dns-api-ttl-clicked)
+(declare template-dns-api-ttl-get)
+(declare handler-dns-api-ttl-get)
+(declare render-dns-api-ttl-get)
+(declare on-dns-api-ttl-post-clicked)
+(declare handler-dns-api-ttl-post)
+(declare render-dns-api-ttl-post)
+
+(def jquery (js* "$"))
+
+(defn null-or-empty-p [arg]
+ (or (not arg)
+ (= arg "")))
+
+(defn reduce-checkboxes [selector]
+ "Reduces the names of all checked checkboxes to a pipe-separated
+ list. Assumes that the checkboxes are named via the convention
+ `chk_something-more'. The important thing is the underscore
+ separating the throwaway prefix and the remaining useful
+ bit. `selector' will likely be something like: [id^='chk_']"
+ (reduce (fn [x y]
+ (cond (and x y) (str x "|" y)
+ (and x (not y)) x
+ (and (not x) y) y
+ :else ""))
+ (map (fn [elem]
+ (let [this (jquery (str "#" (dommy/attr elem :id)))]
+ (when (-> this (.prop "checked"))
+ (second (clojure.string/split (-> this (.prop "id")) "_")))))
+ (.toArray (jquery selector)))))
+
+;; notifications
+
+(hiccups/defhtml template-authmsg [authmsg]
+ [:div {:class "alert alert-danger"} authmsg])
+
+(hiccups/defhtml template-errormsg [errormsg]
+ [:div {:class "alert alert-danger"} errormsg])
+
+(hiccups/defhtml template-message [message]
+ [:div {:class "alert alert-success"} message])
+
+(defn maybe-authmsg [jsonobj]
+ (let [authmsg (get jsonobj "authmsg")]
+ (cond (null-or-empty-p authmsg)
+ (do
+ (dommy/set-style! (dommy/sel1 :#authmsg) :display "none")
+ (dommy/set-html! (dommy/sel1 :#authmsg) "")
+ true)
+ :else
+ (do
+ (dommy/set-style! (dommy/sel1 :#authmsg) :display "block")
+ (dommy/set-html! (dommy/sel1 :#authmsg)
+ (template-authmsg authmsg))
+ false))))
+
+(defn maybe-errormsg [jsonobj]
+ (let [errormsg (get jsonobj "errormsg")]
+ (cond (null-or-empty-p errormsg)
+ (do
+ (dommy/set-style! (dommy/sel1 :#errormsg) :display "none")
+ (dommy/set-html! (dommy/sel1 :#errormsg) "")
+ true)
+ :else
+ (do
+ (dommy/set-style! (dommy/sel1 :#errormsg) :display "block")
+ (dommy/set-html! (dommy/sel1 :#errormsg)
+ (template-errormsg errormsg))
+ false))))
+
+(defn maybe-message [jsonobj]
+ (let [message (get jsonobj "message")]
+ (cond (null-or-empty-p message)
+ (do
+ (dommy/set-style! (dommy/sel1 :#message) :display "none")
+ (dommy/set-html! (dommy/sel1 :#message) ""))
+ :else
+ (do
+ (dommy/set-style! (dommy/sel1 :#message) :display "block")
+ (dommy/set-html! (dommy/sel1 :#message)
+ (template-message message))))
+ true))
+
+(defn notifications [jsonobj]
+ (let [authmsg-result (maybe-authmsg jsonobj)
+ errormsg-result (maybe-errormsg jsonobj)
+ message-result (maybe-message jsonobj)]
+ (and authmsg-result errormsg-result message-result)))
+
+(defn auth-notifications [jsonobj]
+ (let [result (notifications jsonobj)]
+ (cond (get jsonobj "authmsg")
+ (render-dns-login-get))
+ result))
+
+;; forms
+
+(hiccups/defhtml template-generic-form [jsonobj]
+ [:div {:id "form-errormsg"}]
+ [:form {:name (get jsonobj "name")
+ :id (get jsonobj "name")
+ :method (get jsonobj "httpMethod")
+ :action (when (get jsonobj "action")
+ (str "javascript:" (namespace ::x) "." (get jsonobj "action")))}
+ (for [form-field (get jsonobj "formFields")]
+ (cond (= (get form-field "fieldType") "button")
+ [:div {:class "form-group row"}
+ [:div {:class "offset-sm-2 col-sm-10"}
+ [:button {:class "btn btn-primary"
+ :data-dismiss (get jsonobj "dismiss")
+ :type (cond (get form-field "onclick") "button" :else "submit")
+ :onclick (when (get form-field "onclick")
+ (str (namespace ::x) "." (get form-field "onclick")))}
+ (get form-field "label")]]]
+ (= (get form-field "fieldType") "hidden")
+ [:input {:name (get form-field "name")
+ :id (get form-field "name")
+ :value (get form-field "value")
+ :type (get form-field "fieldType")}]
+ (= (get form-field "fieldType") "checkbox")
+ [:div {:class "form-check"}
+ [:input {:type "checkbox"
+ :class "form-check-input"
+ :name (get form-field "name")
+ :id (get form-field "name")
+ :value (get form-field "value")
+ :checked (get form-field "checked")
+ :required (get form-field "required")}]
+ [:label {:class "form-check-label"
+ :for (get form-field "name")}
+ (get form-field "label")]]
+ (= (get form-field "fieldType") "radio")
+ [:div {:class "form-check"}
+ [:input {:type "radio"
+ :class "form-check-input"
+ :name (get form-field "name")
+ :id (get form-field "name")
+ :value (get form-field "value")
+ :checked (get form-field "checked")
+ :required (get form-field "required")}]
+ [:label {:class "form-check-label"
+ :for (get form-field "name")}
+ (get form-field "label")]]
+ (= (get form-field "fieldType") "select")
+ [:div {:class "form-group"}
+ [:label {:for (get form-field "name")}
+ (get form-field "label")]
+ [:select {:class "form-control"
+ :name (get form-field "name")
+ :id (get form-field "name")
+ :required (get form-field "required")
+ :onchange (when (get form-field "onchange")
+ (str (namespace ::x) "." (get form-field "onchange")))}
+ (for [option (get form-field "options")]
+ [:option {:value (get option "value")}
+ (get option "label")])]]
+ :else
+ [:div {:class "form-group row"}
+ [:label {:for (get form-field "name")
+ :class "col-form-label col-sm-2"
+ :style "text-align: right"}
+ (get form-field "label")]
+ [:div {:class "col-sm-10"}
+ [:input {:name (get form-field "name")
+ :id (get form-field "name")
+ :value (get form-field "value")
+ :type (get form-field "fieldType")
+ :class "form-control"
+ :required (get form-field "required")}]]]))]
+ (when (get jsonobj "requiredP")
+ [:div "* Required"]))
+
+;; dns
+
+(hiccups/defhtml template-dns [jsonobj]
+ [:div {:class "container-fluid"}
+ [:div {:class "row"}
+ [:div {:class "col-2"}
+ [:h4 (get jsonobj "title")]
+ (template-generic-form (get jsonobj "form"))
+ [:div {:id "search"}]]
+ [:div {:class "col"}
+ [:div {:style "text-align: right"}
+ [:button {:class "btn btn-primary"
+ :type "button"
+ :onclick (str (namespace ::x) ".on_dns_api_add_clicked()")}
+ "Add New Record"]]
+ [:div {:id "results"}]]]]
+ [:div {:id "add"
+ :class "modal fade"
+ :role "dialog"}
+ [:div {:class "modal-dialog modal-lg"}
+ [:div {:class "modal-content"}
+ [:div {:class "modal-header"}
+ [:h5 {:class "modal-title"} "DNS - Add"]
+ [:button {:type "button"
+ :class "close"
+ :data-dismiss "modal"}
+ "×"]]
+ [:div {:id "add-body"
+ :class "modal-body"
+ :style "height: 460px;"}]
+ [:div {:class "modal-footer"}
+ [:button {:type "submit"
+ :class "btn btn-danger btn-default"
+ :data-dismiss "modal"}
+ [:span {:class "glyphicon glyphicon-remove"}]
+ "Cancel"]]]]]
+ [:div {:id "modify"
+ :class "modal fade"
+ :role "dialog"}
+ [:div {:class "modal-dialog modal-lg"}
+ [:div {:class "modal-content"}
+ [:div {:class "modal-header"}
+ [:h5 {:class "modal-title"} "DNS - Modify"]
+ [:button {:type "button"
+ :class "close"
+ :data-dismiss "modal"}
+ "×"]]
+ [:div {:id "modify-body"
+ :class "modal-body"
+ :style "height: 460px;"}]
+ [:div {:class "modal-footer"}
+ [:button {:type "submit"
+ :class "btn btn-danger btn-default"
+ :data-dismiss "modal"}
+ [:span {:class "glyphicon glyphicon-remove"}]
+ "Cancel"]]]]]
+ [:div {:id "ttl"
+ :class "modal fade"
+ :role "dialog"}
+ [:div {:class "modal-dialog modal-lg"}
+ [:div {:class "modal-content"}
+ [:div {:class "modal-header"}
+ [:h5 {:class "modal-title"} "DNS - TTL"]
+ [:button {:type "button"
+ :class "close"
+ :data-dismiss "modal"}
+ "×"]]
+ [:div {:id "ttl-body"
+ :class "modal-body"
+ :style "height: 200px;"}]
+ [:div {:class "modal-footer"}
+ [:button {:type "submit"
+ :class "btn btn-danger btn-default"
+ :data-dismiss "modal"}
+ [:span {:class "glyphicon glyphicon-remove"}]
+ "Cancel"]]]]]
+ [:div {:id "login"
+ :class "modal fade"
+ :role "dialog"}
+ [:div {:class "modal-dialog modal-lg"}
+ [:div {:class "modal-content"}
+ [:div {:class "modal-header"}
+ [:h5 {:class "modal-title"} "DNS - Authentication"]
+ [:button {:type "button"
+ :class "close"
+ :data-dismiss "modal"}
+ "×"]]
+ [:div {:id "login-body"
+ :class "modal-body"
+ :style "height: 460px;"}]
+ [:div {:class "modal-footer"}
+ [:button {:type "submit"
+ :class "btn btn-danger btn-default"
+ :data-dismiss "modal"}
+ [:span {:class "glyphicon glyphicon-remove"}]
+ "Cancel"]]]]])
+
+(defn handler-dns [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#body) (template-dns jsonobj))
+ (render-dns-api-search-get)
+ (render-dns-headers))))
+
+(defn render-dns []
+ (GET "/dns" {:handler handler-dns}))
+
+;; location
+
+(defn navigate-to [handler]
+ (dommy/set-html! (dommy/sel1 :#location) handler)
+ (cond (= handler "/dns") (render-dns)))
+
+(defn handler-location [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (navigate-to (get jsonobj "location"))
+ (notifications jsonobj)))
+
+(defn goto-location [location]
+ (POST "/location" {:format :raw
+ :params {:location location}
+ :handler handler-location}))
+
+(defn reset-app []
+ (set! (.-location js/document) "/"))
+
+;; dns-login-get
+
+(hiccups/defhtml template-dns-login-get [jsonobj]
+ [:h5 (get jsonobj "title")]
+ (template-generic-form (get jsonobj "form")))
+
+(defn handler-dns-login-get [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (dommy/set-html! (dommy/sel1 :#login-body) (template-dns-login-get jsonobj))
+ (.modal (jquery "#login"))))
+
+(defn render-dns-login-get []
+ (GET "/dns/login" {:handler handler-dns-login-get}))
+
+(defn on-dns-login-get-clicked []
+ (when (-> (jquery "#dns-login-get-form")
+ (.get "0")
+ (.checkValidity))
+ (.modal (jquery "#login") "hide")
+ (apply render-dns-login-post
+ (map (fn [field]
+ (when (jquery (str "#dns-login-get-form input[id=" field "]"))
+ (.val (jquery (str "#dns-login-get-form input[id=" field "]")))))
+ ["username" "pwd" "keypath"]))))
+
+;; dns-login-post
+
+(defn handler-dns-login-post [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (render-dns-api-search-post))))
+
+(defn render-dns-login-post [username pwd keypath]
+ (POST "/dns/login/post" {:format :raw
+ :params {:username username
+ :pwd pwd
+ :keypath keypath}
+ :handler handler-dns-login-post}))
+
+;; dns-headers
+
+(hiccups/defhtml template-dns-headers [jsonobj]
+ [:table {:class "table table-hover"}
+ [:thead
+ [:tr
+ (for [header (remove (fn [x] (= x "ttl")) (get jsonobj "headers"))]
+ [:th header])
+ [:th "TTL"]
+ [:th "Del"]]]])
+
+(defn handler-dns-headers [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#results) (template-dns-headers jsonobj)))))
+
+(defn render-dns-headers []
+ (POST "/dns/headers" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))}
+ :handler handler-dns-headers}))
+
+;; dns-api-search-get
+
+(defn on-dns-select-recordtype-changed []
+ (render-dns-api-search-get)
+ (render-dns-headers))
+
+(hiccups/defhtml template-dns-api-search-get [jsonobj]
+ [:h4 (get jsonobj "title")]
+ (template-generic-form (get jsonobj "form")))
+
+(defn handler-dns-api-search-get [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#search) (template-dns-api-search-get jsonobj)))))
+
+(defn render-dns-api-search-get []
+ (POST "/dns/api/search" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))}
+ :handler handler-dns-api-search-get}))
+
+(defn on-dns-api-search-get-clicked []
+ (when (-> (jquery "#dns-api-search-get-form")
+ (.get "0")
+ (.checkValidity))
+ (dommy/set-html! (dommy/sel1 :#results) (template-dns-api-search-post-loading))
+ (render-dns-api-search-post)))
+
+;; dns-api-search-post
+
+(hiccups/defhtml template-dns-api-search-post-loading []
+ [:h5 "Loading..."])
+
+(hiccups/defhtml template-dns-api-search-post [jsonobj]
+ (let [results (get jsonobj "results")
+ keys (remove (fn [x] (or (= x "Recordtype") (= x "ttl"))) (keys (first results)))]
+ [:table {:class "table table-hover"}
+ [:thead
+ [:tr
+ (for [key keys]
+ [:th key])
+ [:th "TTL"]
+ [:th "Del"]]]
+ [:tbody
+ (for [rec results]
+ (let [onclick (str (namespace ::x) ".on_dns_api_modify_clicked('" (get rec "_ref") "','" (get rec "name") "','" (get rec "ipv4Addr") "','" (get rec "ipv6Addr") "','" (get rec "canonical") "','" (get rec "ptrdname") "')")]
+ [:tr
+ (for [key keys]
+ [:td {:onclick onclick} (get rec key)])
+ [:td [:img {:src "/static/images/clock.png"
+ :onclick (str (namespace ::x) ".on_dns_api_ttl_clicked('" (get rec "_ref") "','" (get rec "name") "')")}]]
+ [:td [:img {:src "/static/images/delete.png"
+ :onclick (str (namespace ::x) ".on_dns_api_delete_clicked('" (get rec "_ref") "','" (get rec "name") "')")}]]]))]]))
+
+(defn handler-dns-api-search-post [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#results) (template-dns-api-search-post jsonobj)))))
+
+(defn render-dns-api-search-post []
+ (let [fields ["ref" "name" "ipv4addr" "ipv6addr" "canonical" "ptrdname"]
+ params (merge {:recordtype (dommy/value (dommy/sel1 :#recordtype))}
+ (into {} (map vector
+ (map (fn [field]
+ (keyword field))
+ fields)
+ (map (fn [field]
+ (when (jquery (str "#dns-api-search-get-form input[id=" field "]"))
+ (let [val (.val (jquery (str "#dns-api-search-get-form input[id=" field "]")))]
+ (cond (null-or-empty-p val) nil
+ :else val))))
+ fields))))]
+ (POST "/dns/api/search/post" {:format :raw
+ :params params
+ :handler handler-dns-api-search-post})))
+
+;; dns-api-add-get
+
+(defn on-dns-api-add-clicked []
+ (render-dns-api-add-get))
+
+(hiccups/defhtml template-dns-api-add-get [jsonobj]
+ [:h5 (get jsonobj "title")]
+ (template-generic-form (get jsonobj "form")))
+
+(defn handler-dns-api-add-get [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#add-body) (template-dns-api-add-get jsonobj))
+ (.modal (jquery "#add")))))
+
+(defn render-dns-api-add-get []
+ (POST "/dns/api/add" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))}
+ :handler handler-dns-api-add-get}))
+
+(defn on-dns-api-add-get-clicked []
+ (when (-> (jquery "#dns-api-add-get-form")
+ (.get "0")
+ (.checkValidity))
+ (cond (and (= (dommy/value (dommy/sel1 :#recordtype)) "a")
+ (let [ipv4addr (when (jquery "#dns-api-add-get-form input[id=ipv4addr]")
+ (.val (jquery "#dns-api-add-get-form input[id=ipv4addr]")))
+ ipv6addr (when (jquery "#dns-api-add-get-form input[id=ipv6addr]")
+ (.val (jquery "#dns-api-add-get-form input[id=ipv6addr]")))]
+ (and (null-or-empty-p ipv4addr)
+ (null-or-empty-p ipv6addr))))
+ (js/alert "One or both of the following fields must be populated: IPv4 Address, IPv6 Address")
+ :else
+ (do
+ (.modal (jquery "#add") "hide")
+ (dommy/set-html! (dommy/sel1 :#results) (template-dns-api-search-post-loading))
+ (apply render-dns-api-add-post
+ (map (fn [field]
+ (when (jquery (str "#dns-api-add-get-form input[id=" field "]"))
+ (.val (jquery (str "#dns-api-add-get-form input[id=" field "]")))))
+ ["name" "ipv4addr" "ipv6addr" "canonical" "ptrdname"]))))))
+
+;; dns-api-add-post
+
+(defn handler-dns-api-add-post [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (render-dns-api-search-post))))
+
+(defn render-dns-api-add-post [name ipv4addr ipv6addr canonical ptrdname]
+ (POST "/dns/api/add/post" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))
+ :name name
+ :ipv4addr ipv4addr
+ :ipv6addr ipv6addr
+ :canonical canonical
+ :ptrdname ptrdname}
+ :handler handler-dns-api-add-post}))
+
+;; dns-api-modify-get
+
+(defn on-dns-api-modify-clicked [ref name ipv4addr ipv6addr canonical ptrdname]
+ (render-dns-api-modify-get ref name ipv4addr ipv6addr canonical ptrdname))
+
+(hiccups/defhtml template-dns-api-modify-get [jsonobj]
+ [:h5 (get jsonobj "title")]
+ (template-generic-form (get jsonobj "form")))
+
+(defn handler-dns-api-modify-get [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#modify-body) (template-dns-api-modify-get jsonobj))
+ (.modal (jquery "#modify")))))
+
+(defn render-dns-api-modify-get [ref name ipv4addr ipv6addr canonical ptrdname]
+ (POST "/dns/api/modify" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))
+ :ref ref
+ :name name
+ :ipv4addr ipv4addr
+ :ipv6addr ipv6addr
+ :canonical canonical
+ :ptrdname ptrdname}
+ :handler handler-dns-api-modify-get}))
+
+(defn on-dns-api-modify-get-clicked [ref name ipv4addr ipv6addr canonical ptrdname]
+ (when (-> (jquery "#dns-api-modify-get-form")
+ (.get "0")
+ (.checkValidity))
+ (.modal (jquery "#modify") "hide")
+ (dommy/set-html! (dommy/sel1 :#results) (template-dns-api-search-post-loading))
+ (apply render-dns-api-modify-post
+ (map (fn [field]
+ (when (jquery (str "#dns-api-modify-get-form input[id=" field "]"))
+ (.val (jquery (str "#dns-api-modify-get-form input[id=" field "]")))))
+ ["ref" "name" "ipv4addr" "ipv6addr" "canonical" "ptrdname"]))))
+
+;; dns-api-modify-post
+
+(defn handler-dns-api-modify-post [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (render-dns-api-search-post))))
+
+(defn render-dns-api-modify-post [ref name ipv4addr ipv6addr canonical ptrdname]
+ (POST "/dns/api/modify/post" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))
+ :ref ref
+ :name name
+ :ipv4addr ipv4addr
+ :ipv6addr ipv6addr
+ :canonical canonical
+ :ptrdname ptrdname}
+ :handler handler-dns-api-modify-post}))
+
+;; dns-api-delete-post
+
+(defn on-dns-api-delete-clicked [ref name]
+ (when (js/confirm (str "Are you sure that you want to delete the record for " name "?"))
+ (dommy/set-html! (dommy/sel1 :#results) (template-dns-api-search-post-loading))
+ (render-dns-api-delete-post ref)))
+
+(defn handler-dns-api-delete-post [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (render-dns-api-search-post))))
+
+(defn render-dns-api-delete-post [ref]
+ (POST "/dns/api/delete/post" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))
+ :ref ref}
+ :handler handler-dns-api-delete-post}))
+
+;; dns-api-ttl-get
+
+(defn on-dns-api-ttl-clicked [ref name]
+ (render-dns-api-ttl-get ref name))
+
+(hiccups/defhtml template-dns-api-ttl-get [jsonobj]
+ [:h5 (get jsonobj "title")]
+ (template-generic-form (get jsonobj "form")))
+
+(defn handler-dns-api-ttl-get [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#ttl-body) (template-dns-api-ttl-get jsonobj))
+ (.modal (jquery "#ttl")))))
+
+(defn render-dns-api-ttl-get [ref name]
+ (POST "/dns/api/ttl" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))
+ :ref ref
+ :name name}
+ :handler handler-dns-api-ttl-get}))
+
+(defn on-dns-api-ttl-get-clicked [ref ttl]
+ (when (-> (jquery "#dns-api-ttl-get-form")
+ (.get "0")
+ (.checkValidity))
+ (.modal (jquery "#ttl") "hide")
+ (dommy/set-html! (dommy/sel1 :#results) (template-dns-api-search-post-loading))
+ (apply render-dns-api-ttl-post
+ (map (fn [field]
+ (when (jquery (str "#dns-api-ttl-get-form input[id=" field "]"))
+ (.val (jquery (str "#dns-api-ttl-get-form input[id=" field "]")))))
+ ["ref" "ttl"]))))
+
+;; dns-api-ttl-post
+
+(defn handler-dns-api-ttl-post [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (when (auth-notifications jsonobj)
+ (render-dns-api-search-post))))
+
+(defn render-dns-api-ttl-post [ref ttl]
+ (POST "/dns/api/ttl/post" {:format :raw
+ :params {:recordtype (dommy/value (dommy/sel1 :#recordtype))
+ :ref ref
+ :ttl ttl}
+ :handler handler-dns-api-ttl-post}))