diff --git a/.gitignore b/.gitignore index 99b78ef..e560793 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ pom.xml.asc /checkouts/ /resources/public/content/.git /resources/public/vendor +/bower_components/ .lein-deps-sum .lein-repl-history .lein-plugins/ diff --git a/followup.cljs b/followup.cljs new file mode 100644 index 0000000..836d622 --- /dev/null +++ b/followup.cljs @@ -0,0 +1,72 @@ +(ns youyesyet.views.followup + (:require [reagent.core :as r] + [re-frame.core :refer [reg-sub subscribe]] +;; [re-frame-forms.core :as form] +;; [re-frame-forms.input :as input] +;; [re-com.core :refer [h-box v-box box gap single-dropdown input-text checkbox label title hyperlink-href p]] +;; [re-com.dropdown :refer [filter-choices-by-keyword single-dropdown-args-desc]] + [youyesyet.ui-utils :as ui] +)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; +;;;; youyesyet.views.followup: followup-request view for youyesyet. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU General Public License +;;;; as published by the Free Software Foundation; either version 2 +;;;; 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 General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with this program; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +;;;; USA. +;;;; +;;;; Copyright (C) 2016 Simon Brooke for Radical Independence Campaign +;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;; The pattern from the re-com demo (https://github.com/Day8/re-com) is to have +;;; one source file/namespace per view. Each namespace contains a function 'panel' +;;; whose output is an enlive-style specification of the view to be redered. +;;; I propose to follow this pattern. This file will (eventually) provide the followup-request view. + +;;; See https://github.com/simon-brooke/youyesyet/blob/master/doc/specification/userspec.md#followup-request-form + +(defn panel + "Generate the followup-request panel." + [] + (js/console.log (str "Rendering follow-up form")) + + (let [issue @(subscribe [:issue]) + issues @(subscribe [:issues]) + elector @(subscribe [:elector]) + address @(subscribe [:address]) + form (form/make-form {:elector (:id elector) + :issue (:id issue)})] + [:div + [:h1 "Followup Request"] + (let [selected-elector-id (r/atom (:id elector)) + selected-issue (r/atom (:id issue))] + [:form {} + [:p.widget + [:label {:for "elector"} "Elector"] + [single-dropdown + :id elector + :choices (:electors address) + :model selected-elector-id + :label-fn #(:name %)]] + [:p.widget + [:label {:for "issue"} "Issue"] + [single-dropdown + :id issue + :choices (map #({:id % :label %}) (keys issues)) + :model issue]] + + ])])) diff --git a/src/cljs/youyesyet/core.cljs b/src/cljs/youyesyet/core.cljs index 6864752..fa274f3 100644 --- a/src/cljs/youyesyet/core.cljs +++ b/src/cljs/youyesyet/core.cljs @@ -12,10 +12,10 @@ [youyesyet.ui-utils :as ui] [youyesyet.views.about :as about] [youyesyet.views.electors :as electors] + [youyesyet.views.followup :as followup] [youyesyet.views.issue :as issue] [youyesyet.views.issues :as issues] - [youyesyet.views.map :as maps] - [youyesyet.views.followup-request :as request]) + [youyesyet.views.map :as maps]) (:import goog.History)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -50,6 +50,9 @@ (defn electors-page [] (electors/panel)) +(defn followup-page [] + (followup/panel)) + (defn issues-page [] (issues/panel)) @@ -59,12 +62,10 @@ (defn map-page [] (maps/panel)) -(defn request-page [] - (request/panel)) - (def pages {:about #'about-page :electors #'electors-page + :followup #'followup-page :issues #'issues-page :issue #'issue-page :map #'map-page @@ -89,11 +90,14 @@ (secretary/defroute "/electors" [] (rf/dispatch [:set-active-page :electors])) +(secretary/defroute "/followup" [] + (rf/dispatch [:set-active-page :followup])) + (secretary/defroute "/issues" [] (rf/dispatch [:set-active-page :issues])) -(secretary/defroute "/issues/:elector" {elector :elector} - (rf/dispatch (list [:set-elector elector] [:set-active-page :issues]))) +(secretary/defroute "/issues/:elector" {elector-id :elector} + (rf/dispatch [:set-elector-and-page elector-id :issues])) (secretary/defroute "/issue/:issue" {issue :issue} (rf/dispatch [:set-issue issue])) diff --git a/src/cljs/youyesyet/db.cljs b/src/cljs/youyesyet/db.cljs index 02cca2d..820dcae 100644 --- a/src/cljs/youyesyet/db.cljs +++ b/src/cljs/youyesyet/db.cljs @@ -31,7 +31,11 @@ (def default-db {;;; the currently selected address, if any. - :address {:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2590944} + :address {:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2590944 + :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} + {:id 2 :name "Ann Anderson" :gender :female} + {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} + {:id 4 :name "Andy Anderson" :intention :yes}]} ;;; a list of the addresses in the current location at which there ;;; are electors registered. :addresses [{:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2590944 @@ -40,10 +44,7 @@ {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} {:id 4 :name "Andy Anderson" :intention :yes}]}] ;;; electors at the currently selected address - :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} - {:id 2 :name "Ann Anderson" :gender :female} - {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} - {:id 4 :name "Andy Anderson" :intention :yes}] + :elector {:id 1 :name "Alan Anderson" :gender :male :intention :no} ;;; the issue from among the issues which is currently selected. :issue "Currency" ;;; the issues selected for the issues page on this day. diff --git a/src/cljs/youyesyet/handlers.cljs b/src/cljs/youyesyet/handlers.cljs index 95346e6..8df5adb 100644 --- a/src/cljs/youyesyet/handlers.cljs +++ b/src/cljs/youyesyet/handlers.cljs @@ -35,6 +35,16 @@ (fn [db [_ page]] (assoc db :page page))) +(reg-event-db + :set-elector-and-page + (fn [db [_ [elector-id page]]] + (let [elector + (remove nil? + (map + #(if (= elector-id (:id %)) %) + (:electors (:address db))))] + (merge db {:elector elector :page page})))) + (reg-event-db :set-issue (fn [db [_ issue]] diff --git a/src/cljs/youyesyet/subscriptions.cljs b/src/cljs/youyesyet/subscriptions.cljs index eb392b7..d31e1a3 100644 --- a/src/cljs/youyesyet/subscriptions.cljs +++ b/src/cljs/youyesyet/subscriptions.cljs @@ -40,9 +40,9 @@ (:addresses db))) (reg-sub - :electors + :elector (fn [db _] - (:electors db))) + (:elector db))) (reg-sub :issue diff --git a/src/cljs/youyesyet/ui_utils.cljs b/src/cljs/youyesyet/ui_utils.cljs index 862856a..c25ab2a 100644 --- a/src/cljs/youyesyet/ui_utils.cljs +++ b/src/cljs/youyesyet/ui_utils.cljs @@ -45,6 +45,14 @@ :on-click #(reset! collapsed? true)} title]])) +(defn error-panel + [message] + [:div + [:h1.error message] + [:div.container {:id "main-container"} + (ui/back-link)]]) + + (defn navbar [] (r/with-let [collapsed? (r/atom true)] [:div {:id "nav"} diff --git a/src/cljs/youyesyet/views/electors.cljs b/src/cljs/youyesyet/views/electors.cljs index e04d6fd..e6de69b 100644 --- a/src/cljs/youyesyet/views/electors.cljs +++ b/src/cljs/youyesyet/views/electors.cljs @@ -95,22 +95,25 @@ "Generate the electors panel." [] (let [address @(subscribe [:address]) - electors @(subscribe [:electors]) + electors (:electors address) options @(subscribe [:options])] - [:div - [:h1 (:address address) (count electors) " electors"] - [:div.container {:id "main-container"} - [:table - ;; genders row - (genders-row electors) - ;; names row - (names-row electors) - ;; options rows - (map - #(options-row electors %) - options) - ;; issues row - (issues-row electors)] - (ui/back-link)]])) + (if address + [:div + [:h1 (:address address) (count electors) " electors"] + [:div.container {:id "main-container"} + [:table + [:tbody + ;; genders row + (genders-row electors) + ;; names row + (names-row electors) + ;; options rows + (map + #(options-row electors %) + options) + ;; issues row + (issues-row electors)]] + (ui/back-link)]] + (ui/error-panel "No address selected")))) diff --git a/src/cljs/youyesyet/views/followup_request.cljs b/src/cljs/youyesyet/views/followup.cljs similarity index 55% rename from src/cljs/youyesyet/views/followup_request.cljs rename to src/cljs/youyesyet/views/followup.cljs index 0ba9455..a09034c 100644 --- a/src/cljs/youyesyet/views/followup_request.cljs +++ b/src/cljs/youyesyet/views/followup.cljs @@ -1,5 +1,6 @@ -(ns youyesyet.views.followup-request - (:require [re-frame.core :refer [reg-sub]])) +(ns youyesyet.views.followup + (:require [re-frame.core :refer [reg-sub subscribe]] + [youyesyet.ui-utils :as ui])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; @@ -35,4 +36,34 @@ (defn panel "Generate the followup-request panel." [] - []) + (let [issue @(subscribe [:issue]) + issues @(subscribe [:issues]) + elector @(subscribe [:elector]) + address @(subscribe [:address])] + (cond + (nil? address) + (ui/error-panel "No address selected") + (nil? issues) + (ui/error-panel "No issues loaded") + true + [:div + [:h1 "Followup Request"] + [:div.container {:id "main-container"} + [:form {} + [:p.widget + [:label {:for "elector"} "Elector"] + [:select {:id "elector" :name "elector"} + (map + #(let [selkey (if (= (:id elector) (:id %)) :selected :not-selected)] + [:option {:value (:id %) selkey "true"} (:name %)]) (:electors address))]] + [:p.widget + [:label {:for "issue"} "Issue"] + [:select {:id "issue" :name "issue"} + (map + #(let [selkey (if (= (:id issue) (:id %)) :selected :not-selected)] + [:option {selkey "true"} %]) (keys issues))]] + [:p.widget + [:label {:for "submit"} " "] + [:input {:id "submit" :name "submit" :type "submit" :value "Request Call"}]] + ] + (ui/back-link)]]))) diff --git a/src/cljs/youyesyet/views/issue.cljs b/src/cljs/youyesyet/views/issue.cljs index c611572..f86be91 100644 --- a/src/cljs/youyesyet/views/issue.cljs +++ b/src/cljs/youyesyet/views/issue.cljs @@ -43,4 +43,5 @@ [:div {:id "issue"} [:div {:id "issue-text"} (issues issue)]] + (ui/big-link "Request call" "#/followup") (ui/back-link)]])) diff --git a/src/cljs/youyesyet/views/issues.cljs b/src/cljs/youyesyet/views/issues.cljs index 6003395..ea8f383 100644 --- a/src/cljs/youyesyet/views/issues.cljs +++ b/src/cljs/youyesyet/views/issues.cljs @@ -38,9 +38,11 @@ "Generate the issues panel." [] (let [issues @(subscribe [:issues])] - [:div - [:h1 "Issues"] - [:div.container {:id "main-container"} - (ui/back-link) - [:div {:id "issue-list"} - (map (fn [k] (ui/big-link k (str "#/issue/" k))) (keys issues))]]])) + (if issues + [:div + [:h1 "Issues"] + [:div.container {:id "main-container"} + (ui/back-link) + [:div {:id "issue-list"} + (map (fn [k] (ui/big-link k (str "#/issue/" k))) (keys issues))]]] + (ui/error-panel "No issues loaded")))) diff --git a/src/cljs/youyesyet/views/map.cljs b/src/cljs/youyesyet/views/map.cljs index f573a7f..30ea9a9 100644 --- a/src/cljs/youyesyet/views/map.cljs +++ b/src/cljs/youyesyet/views/map.cljs @@ -73,8 +73,6 @@ (.addTp (.marker js/L [latitude longitude] {:icon pin})) view)) - - ;; My gods mapbox is user-hostile! (defn map-did-mount-mapbox "Did-mount function loading map tile data from MapBox (proprietary)." @@ -96,7 +94,8 @@ (clj->js {:attribution osm-attrib :maxZoom 18})) view) - (map #(add-map-pin (:latitude %) (:longitude %) (pin-image %) view) addresses))) +;; (map #(add-map-pin (:latitude %) (:longitude %) (pin-image %) view) addresses) + )) (defn map-did-mount