Now actually pulling data from server, but some regressions.

The map isn't rendering, and there's something wrong with options. But a lot is working.
This commit is contained in:
Simon Brooke 2018-07-03 19:50:19 +01:00
parent d4f0f4aa5c
commit 3a49e50a51
59 changed files with 1263 additions and 3166 deletions

View file

@ -8,10 +8,12 @@
[ch.qos.logback/logback-classic "1.2.2"]
[clj-oauth "1.5.5"]
[cljsjs/react-leaflet "0.12.3-4"]
[cljs-ajax "0.5.8"]
[cljs-ajax "0.7.3"]
[com.cemerick/url "0.1.1"]
[compojure "1.5.2"]
[conman "0.6.3"]
[cprop "0.1.10"]
[day8.re-frame/http-fx "0.1.6"]
[korma "0.4.3"]
[lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]]
[luminus/ring-ttl-session "0.3.1"]

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

View file

Before

Width:  |  Height:  |  Size: 983 B

After

Width:  |  Height:  |  Size: 983 B

View file

Before

Width:  |  Height:  |  Size: 511 B

After

Width:  |  Height:  |  Size: 511 B

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -1,10 +1,10 @@
------------------------------------------------------------------------
-- File queries.sql
--
-- autogenerated by adl.to-hugsql-queries at 2018-07-01T22:15:28.111Z
--
-- See [Application Description
-- Language](https://github.com/simon-brooke/adl).
-- File queries.sql
--
-- autogenerated by adl.to-hugsql-queries at 2018-07-03T12:23:50.486Z
--
-- See [Application Description
-- Language](https://github.com/simon-brooke/adl).
------------------------------------------------------------------------
-- :name create-address! :! :n
@ -143,9 +143,11 @@ returning Id
-- :doc creates a new issue record
INSERT INTO issues (url,
current,
brief,
id)
VALUES (:url,
:current,
:brief,
:id)
returning id
@ -405,7 +407,7 @@ ORDER BY lv_addresses.address,
-- :name list-addresses-by-district :? :*
-- :doc lists all existing address records related to a given district
SELECT *
SELECT *
FROM lv_addresses, addresses
WHERE lv_addresses.id = addresses.id
AND addresses.district_id = :id
@ -433,7 +435,7 @@ ORDER BY lv_canvassers.username,
-- :name list-canvassers-by-address :? :*
-- :doc lists all existing canvasser records related to a given address
SELECT *
SELECT *
FROM lv_canvassers, canvassers
WHERE lv_canvassers.id = canvassers.id
AND canvassers.address_id = :id
@ -446,7 +448,7 @@ ORDER BY lv_canvassers.username,
-- :name list-canvassers-by-authority :? :*
-- :doc lists all existing canvasser records related to a given authority
SELECT *
SELECT *
FROM lv_canvassers, canvassers
WHERE lv_canvassers.id = canvassers.id
AND canvassers.authority_id = :id
@ -459,7 +461,7 @@ ORDER BY lv_canvassers.username,
-- :name list-canvassers-by-elector :? :*
-- :doc lists all existing canvasser records related to a given elector
SELECT *
SELECT *
FROM lv_canvassers, canvassers
WHERE lv_canvassers.id = canvassers.id
AND canvassers.elector_id = :id
@ -472,7 +474,7 @@ ORDER BY lv_canvassers.username,
-- :name list-canvassers-by-role :? :*
-- :doc links all existing canvasser records related to a given role
SELECT *
SELECT *
FROM canvassers, ln_canvassers_roles
WHERE canvassers.id = ln_canvassers_roles.canvasser_id
AND ln_canvassers_roles.role_id = :id
@ -502,7 +504,7 @@ ORDER BY lv_dwellings.address_id,
-- :name list-dwellings-by-address :? :*
-- :doc lists all existing dwelling records related to a given address
SELECT *
SELECT *
FROM lv_dwellings, dwellings
WHERE lv_dwellings.id = dwellings.id
AND dwellings.address_id = :id
@ -523,7 +525,7 @@ ORDER BY lv_electors.name,
-- :name list-electors-by-dwelling :? :*
-- :doc lists all existing elector records related to a given dwelling
SELECT *
SELECT *
FROM lv_electors, electors
WHERE lv_electors.id = electors.id
AND electors.dwelling_id = :id
@ -535,7 +537,7 @@ ORDER BY lv_electors.name,
-- :name list-electors-by-gender :? :*
-- :doc lists all existing elector records related to a given gender
SELECT *
SELECT *
FROM lv_electors, electors
WHERE lv_electors.id = electors.id
AND electors.gender = :id
@ -556,7 +558,7 @@ ORDER BY lv_followupactions.date,
-- :name list-followupactions-by-canvasser :? :*
-- :doc lists all existing followupaction records related to a given canvasser
SELECT *
SELECT *
FROM lv_followupactions, followupactions
WHERE lv_followupactions.id = followupactions.id
AND followupactions.actor = :id
@ -566,7 +568,7 @@ ORDER BY lv_followupactions.date,
-- :name list-followupactions-by-followuprequest :? :*
-- :doc lists all existing followupaction records related to a given followuprequest
SELECT *
SELECT *
FROM lv_followupactions, followupactions
WHERE lv_followupactions.id = followupactions.id
AND followupactions.request_id = :id
@ -592,7 +594,7 @@ ORDER BY lv_followuprequests.elector_id,
-- :name list-followuprequests-by-elector :? :*
-- :doc lists all existing followuprequest records related to a given elector
SELECT *
SELECT *
FROM lv_followuprequests, followuprequests
WHERE lv_followuprequests.id = followuprequests.id
AND followuprequests.elector_id = :id
@ -603,7 +605,7 @@ ORDER BY lv_followuprequests.elector_id,
-- :name list-followuprequests-by-followupmethod :? :*
-- :doc lists all existing followuprequest records related to a given followupmethod
SELECT *
SELECT *
FROM lv_followuprequests, followuprequests
WHERE lv_followuprequests.id = followuprequests.id
AND followuprequests.method_id = :id
@ -614,7 +616,7 @@ ORDER BY lv_followuprequests.elector_id,
-- :name list-followuprequests-by-issue :? :*
-- :doc lists all existing followuprequest records related to a given issue
SELECT *
SELECT *
FROM lv_followuprequests, followuprequests
WHERE lv_followuprequests.id = followuprequests.id
AND followuprequests.issue_id = :id
@ -625,7 +627,7 @@ ORDER BY lv_followuprequests.elector_id,
-- :name list-followuprequests-by-visit :? :*
-- :doc lists all existing followuprequest records related to a given visit
SELECT *
SELECT *
FROM lv_followuprequests, followuprequests
WHERE lv_followuprequests.id = followuprequests.id
AND followuprequests.visit_id = :id
@ -648,21 +650,21 @@ SELECT DISTINCT * FROM lv_intentions
-- :name list-intentions-by-elector :? :*
-- :doc lists all existing intention records related to a given elector
SELECT *
SELECT *
FROM lv_intentions, intentions
WHERE lv_intentions.Id = intentions.Id
AND intentions.elector_id = :id
-- :name list-intentions-by-option :? :*
-- :doc lists all existing intention records related to a given option
SELECT *
SELECT *
FROM lv_intentions, intentions
WHERE lv_intentions.Id = intentions.Id
AND intentions.option_id = :id
-- :name list-intentions-by-visit :? :*
-- :doc lists all existing intention records related to a given visit
SELECT *
SELECT *
FROM lv_intentions, intentions
WHERE lv_intentions.Id = intentions.Id
AND intentions.visit_id = :id
@ -689,7 +691,7 @@ ORDER BY lv_roles.name,
-- :name list-roles-by-canvasser :? :*
-- :doc links all existing role records related to a given canvasser
SELECT *
SELECT *
FROM roles, ln_canvassers_roles
WHERE roles.id = ln_canvassers_roles.role_id
AND ln_canvassers_roles.canvasser_id = :id
@ -706,7 +708,7 @@ ORDER BY lv_teams.name,
-- :name list-teams-by-canvasser :? :*
-- :doc links all existing team records related to a given canvasser
SELECT *
SELECT *
FROM teams, ln_canvassers_teams
WHERE teams.id = ln_canvassers_teams.team_id
AND ln_canvassers_teams.canvasser_id = :id
@ -715,7 +717,7 @@ ORDER BY teams.name,
-- :name list-teams-by-district :? :*
-- :doc lists all existing team records related to a given district
SELECT *
SELECT *
FROM lv_teams, teams
WHERE lv_teams.id = teams.id
AND teams.district_id = :id
@ -733,7 +735,7 @@ ORDER BY lv_visits.address_id,
-- :name list-visits-by-address :? :*
-- :doc lists all existing visit records related to a given address
SELECT *
SELECT *
FROM lv_visits, visits
WHERE lv_visits.id = visits.id
AND visits.address_id = :id
@ -743,7 +745,7 @@ ORDER BY lv_visits.address_id,
-- :name list-visits-by-canvasser :? :*
-- :doc lists all existing visit records related to a given canvasser
SELECT *
SELECT *
FROM lv_visits, visits
WHERE lv_visits.id = visits.id
AND visits.canvasser_id = :id
@ -912,6 +914,7 @@ SELECT DISTINCT * FROM lv_issues
WHERE false
--~ (if (:url params) "OR url LIKE '%:url%'")
--~ (if (:current params) "OR current = :current")
--~ (if (:brief params) "OR brief LIKE '%:brief%'")
--~ (if (:id params) "OR id LIKE '%:id%'")
--~ (if (:offset params) "OFFSET :offset ")
--~ (if (:limit params) "LIMIT :limit" "LIMIT 100")
@ -1055,6 +1058,7 @@ WHERE intentions.Id = :Id
UPDATE issues
SET url = :url,
current = :current,
brief = :brief,
id = :id
WHERE issues.id = :id
@ -1079,4 +1083,4 @@ UPDATE visits
SET address_id = :address_id,
canvasser_id = :canvasser_id,
date = :date
WHERE visits.id = :id
WHERE visits.id = :id

View file

@ -5,7 +5,7 @@
--
-- auto-generated by [Application Description Language framework]
--
-- (https://github.com/simon-brooke/adl) at 20180701T221532.672Z
-- (https://github.com/simon-brooke/adl) at 20180703T122351.367Z
--
--
-- A web-app intended to be used by canvassers campaigning for a
@ -338,7 +338,8 @@ CREATE TABLE issues
(
id VARCHAR(32) NOT NULL PRIMARY KEY,
url VARCHAR(256),
current BOOLEAN DEFAULT true
current BOOLEAN DEFAULT true,
brief TEXT
);
GRANT SELECT ON issues TO admin,
analysts,
@ -676,6 +677,7 @@ GRANT SELECT ON lv_intentions TO admin,
CREATE VIEW lv_issues AS
SELECT issues.url,
issues.current,
issues.brief,
issues.id
FROM issues
;

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File application-index.html generated 2018-07-01T22:15:35.347Z by adl.to-selmer-templates.
<!-- File application-index.html generated 2018-07-03T12:23:51.915Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-addresses-Address.html generated 2018-07-01T22:15:35.320Z by adl.to-selmer-templates.
<!-- File form-addresses-Address.html generated 2018-07-03T12:23:51.902Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-authorities-Authority.html generated 2018-07-01T22:15:35.364Z by adl.to-selmer-templates.
<!-- File form-authorities-Authority.html generated 2018-07-03T12:23:51.923Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-canvassers-Canvasser.html generated 2018-07-01T22:15:35.371Z by adl.to-selmer-templates.
<!-- File form-canvassers-Canvasser.html generated 2018-07-03T12:23:51.926Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-districts-District.html generated 2018-07-01T22:15:35.303Z by adl.to-selmer-templates.
<!-- File form-districts-District.html generated 2018-07-03T12:23:51.891Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-dwellings-Dwelling.html generated 2018-07-01T22:15:35.401Z by adl.to-selmer-templates.
<!-- File form-dwellings-Dwelling.html generated 2018-07-03T12:23:51.938Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-electors-Elector.html generated 2018-07-01T22:15:35.355Z by adl.to-selmer-templates.
<!-- File form-electors-Elector.html generated 2018-07-03T12:23:51.920Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-followupactions-Followupaction.html generated 2018-07-01T22:15:35.407Z by adl.to-selmer-templates.
<!-- File form-followupactions-Followupaction.html generated 2018-07-03T12:23:51.940Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-followupmethods-Followupmethod.html generated 2018-07-01T22:15:35.414Z by adl.to-selmer-templates.
<!-- File form-followupmethods-Followupmethod.html generated 2018-07-03T12:23:51.943Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-followuprequests-Followuprequest.html generated 2018-07-01T22:15:35.309Z by adl.to-selmer-templates.
<!-- File form-followuprequests-Followuprequest.html generated 2018-07-03T12:23:51.895Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-genders-Gender.html generated 2018-07-01T22:15:35.292Z by adl.to-selmer-templates.
<!-- File form-genders-Gender.html generated 2018-07-03T12:23:51.886Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-intentions-Intention.html generated 2018-07-01T22:15:35.391Z by adl.to-selmer-templates.
<!-- File form-intentions-Intention.html generated 2018-07-03T12:23:51.935Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-issues-Issue.html generated 2018-07-01T22:15:35.330Z by adl.to-selmer-templates.
<!-- File form-issues-Issue.html generated 2018-07-03T12:23:51.907Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
@ -61,6 +61,24 @@ You are not permitted to view current of issues
{% endifmemberof %}
{% endifmemberof %}
</p>
<p class='widget'>
<label for='brief'>
brief
</label>
{% ifmemberof issueeditors admin %}
<input id='brief' name='brief' type='text' value='{{record.brief}}' maxlength='' size='16'/>
{% else %}
{% ifmemberof canvassers teamorganisers issueexperts analysts issueeditors admin %}
<span id='brief' name='brief' class='pseudo-widget disabled'>
{{record.brief}}
</span>
{% else %}
<span id='brief' name='brief' class='pseudo-widget not-authorised'>
You are not permitted to view brief of issues
</span>
{% endifmemberof %}
{% endifmemberof %}
</p>
<p class='widget action-safe'>
<label for='save-button' class='action-safe'>
To save this issues record

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-options-Option.html generated 2018-07-01T22:15:35.389Z by adl.to-selmer-templates.
<!-- File form-options-Option.html generated 2018-07-03T12:23:51.934Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-roles-Role.html generated 2018-07-01T22:15:35.334Z by adl.to-selmer-templates.
<!-- File form-roles-Role.html generated 2018-07-03T12:23:51.910Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-teams-Team.html generated 2018-07-01T22:15:35.349Z by adl.to-selmer-templates.
<!-- File form-teams-Team.html generated 2018-07-03T12:23:51.915Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
<!-- File form-visits-Visit.html generated 2018-07-01T22:15:35.342Z by adl.to-selmer-templates.
<!-- File form-visits-Visit.html generated 2018-07-03T12:23:51.913Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-addresses-Addresses.html generated 2018-07-01T22:15:35.368Z by adl.to-selmer-templates.
<!-- File list-addresses-Addresses.html generated 2018-07-03T12:23:51.926Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-addresses-Address' class='big-link'>
<a href='form-addresses-Address'>
Add a new Address
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-addresses-Addresses' class='list' action='{{servlet-context}}/list-addresses-Addresses' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='addresses'>
<thead>
<tr>
@ -87,7 +58,7 @@ longitude
<input id='longitude' type='number' name='longitude' value='{{ params.longitude }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -125,30 +96,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-addresses-Addresses');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset \"0\" %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-authorities-Authorities.html generated 2018-07-01T22:15:35.307Z by adl.to-selmer-templates.
<!-- File list-authorities-Authorities.html generated 2018-07-03T12:23:51.893Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-authorities-Authority' class='big-link'>
<a href='form-authorities-Authority'>
Add a new Authority
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-authorities-Authorities' class='list' action='{{servlet-context}}/list-authorities-Authorities' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='authorities'>
<thead>
<tr>
@ -69,7 +40,7 @@ authorize-uri
<input id='authorize_uri' type='text' name='authorize_uri' value='{{ params.authorize_uri }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -96,30 +67,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-authorities-Authorities');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-canvassers-Canvassers.html generated 2018-07-01T22:15:35.398Z by adl.to-selmer-templates.
<!-- File list-canvassers-Canvassers.html generated 2018-07-03T12:23:51.938Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-canvassers-Canvasser' class='big-link'>
<a href='form-canvassers-Canvasser'>
Add a new Canvasser
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-canvassers-Canvassers' class='list' action='{{servlet-context}}/list-canvassers-Canvassers' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='canvassers'>
<thead>
<tr>
@ -99,7 +70,7 @@ authorised
<input id='authorised' type='text' name='authorised' value='{{ params.authorised }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -147,30 +118,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-canvassers-Canvassers');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-districts-Districts.html generated 2018-07-01T22:15:35.384Z by adl.to-selmer-templates.
<!-- File list-districts-Districts.html generated 2018-07-03T12:23:51.932Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-districts-District' class='big-link'>
<a href='form-districts-District'>
Add a new District
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-districts-Districts' class='list' action='{{servlet-context}}/list-districts-Districts' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='districts'>
<thead>
<tr>
@ -57,7 +28,7 @@ name
<input id='name' type='text' name='name' value='{{ params.name }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -78,30 +49,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-districts-Districts');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-dwellings-Dwellings.html generated 2018-07-01T22:15:35.361Z by adl.to-selmer-templates.
<!-- File list-dwellings-Dwellings.html generated 2018-07-03T12:23:51.923Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-dwellings-Dwelling' class='big-link'>
<a href='form-dwellings-Dwelling'>
Add a new Dwelling
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-dwellings-Dwellings' class='list' action='{{servlet-context}}/list-dwellings-Dwellings' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='dwellings'>
<thead>
<tr>
@ -63,7 +34,7 @@ sub-address
<input id='sub_address' type='text' name='sub_address' value='{{ params.sub_address }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -89,30 +60,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-dwellings-Dwellings');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-electors-Electors.html generated 2018-07-01T22:15:35.326Z by adl.to-selmer-templates.
<!-- File list-electors-Electors.html generated 2018-07-03T12:23:51.906Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-electors-Elector' class='big-link'>
<a href='form-electors-Elector'>
Add a new Elector
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-electors-Electors' class='list' action='{{servlet-context}}/list-electors-Electors' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='electors'>
<thead>
<tr>
@ -81,7 +52,7 @@ gender
<input id='gender_expanded' type='text' name='gender_expanded' value='{{ params.gender_expanded }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -118,30 +89,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-electors-Electors');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-followupactions-Followupactions.html generated 2018-07-01T22:15:35.396Z by adl.to-selmer-templates.
<!-- File list-followupactions-Followupactions.html generated 2018-07-03T12:23:51.937Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-followupactions-Followupaction' class='big-link'>
<a href='form-followupactions-Followupaction'>
Add a new Followupaction
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-followupactions-Followupactions' class='list' action='{{servlet-context}}/list-followupactions-Followupactions' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='followupactions'>
<thead>
<tr>
@ -81,7 +52,7 @@ closed
<input id='closed' type='text' name='closed' value='{{ params.closed }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -118,30 +89,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-followupactions-Followupactions');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-followupmethods-Followupmethods.html generated 2018-07-01T22:15:35.341Z by adl.to-selmer-templates.
<!-- File list-followupmethods-Followupmethods.html generated 2018-07-03T12:23:51.912Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-followupmethods-Followupmethod' class='big-link'>
<a href='form-followupmethods-Followupmethod'>
Add a new Followupmethod
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-followupmethods-Followupmethods' class='list' action='{{servlet-context}}/list-followupmethods-Followupmethods' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='followupmethods'>
<thead>
<tr>
@ -51,7 +22,7 @@ id
<input id='id' type='text' name='id' value='{{ params.id }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -69,30 +40,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-followupmethods-Followupmethods');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-followuprequests-Followuprequests.html generated 2018-07-01T22:15:35.297Z by adl.to-selmer-templates.
<!-- File list-followuprequests-Followuprequests.html generated 2018-07-03T12:23:51.889Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-followuprequests-Followuprequest' class='big-link'>
<a href='form-followuprequests-Followuprequest'>
Add a new Followuprequest
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-followuprequests-Followuprequests' class='list' action='{{servlet-context}}/list-followuprequests-Followuprequests' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='followuprequests'>
<thead>
<tr>
@ -75,7 +46,7 @@ method_id
<input id='method_id_expanded' type='text' name='method_id_expanded' value='{{ params.method_id_expanded }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -113,30 +84,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-followuprequests-Followuprequests');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-genders-Genders.html generated 2018-07-01T22:15:35.275Z by adl.to-selmer-templates.
<!-- File list-genders-Genders.html generated 2018-07-03T12:23:51.883Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-genders-Gender' class='big-link'>
<a href='form-genders-Gender'>
Add a new Gender
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-genders-Genders' class='list' action='{{servlet-context}}/list-genders-Genders' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='genders'>
<thead>
<tr>
@ -51,7 +22,7 @@ id
<input id='id' type='text' name='id' value='{{ params.id }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -69,30 +40,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-genders-Genders');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-intentions-Intentions.html generated 2018-07-01T22:15:35.404Z by adl.to-selmer-templates.
<!-- File list-intentions-Intentions.html generated 2018-07-03T12:23:51.940Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-intentions-Intention' class='big-link'>
<a href='form-intentions-Intention'>
Add a new Intention
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-intentions-Intentions' class='list' action='{{servlet-context}}/list-intentions-Intentions' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='intentions'>
<thead>
<tr>
@ -69,7 +40,7 @@ locality
<input id='locality' type='number' name='locality' value='{{ params.locality }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -102,30 +73,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-intentions-Intentions');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-issues-Issues.html generated 2018-07-01T22:15:35.386Z by adl.to-selmer-templates.
<!-- File list-issues-Issues.html generated 2018-07-03T12:23:51.933Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-issues-Issue' class='big-link'>
<a href='form-issues-Issue'>
Add a new Issue
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-issues-Issues' class='list' action='{{servlet-context}}/list-issues-Issues' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='issues'>
<thead>
<tr>
@ -51,6 +22,9 @@ url
<th>
current
</th>
<th>
brief
</th>
</tr>
<tr>
<th>
@ -63,7 +37,10 @@ current
<input id='current' type='text' name='current' value='{{ params.current }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input id='brief' type='text' name='brief' value='{{ params.brief }}'/>
</th>
<th>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -80,6 +57,9 @@ current
{{ record.current }}
</td>
<td>
{{ record.brief }}
</td>
<td>
<a href='form-issues-Issue?id={{ record.id }}'>
View
</a>
@ -87,30 +67,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-issues-Issues');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-options-Options.html generated 2018-07-01T22:15:35.300Z by adl.to-selmer-templates.
<!-- File list-options-Options.html generated 2018-07-03T12:23:51.890Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-options-Option' class='big-link'>
<a href='form-options-Option'>
Add a new Option
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-options-Options' class='list' action='{{servlet-context}}/list-options-Options' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='options'>
<thead>
<tr>
@ -51,7 +22,7 @@ id
<input id='id' type='text' name='id' value='{{ params.id }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -69,30 +40,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-options-Options');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-roles-Roles.html generated 2018-07-01T22:15:35.338Z by adl.to-selmer-templates.
<!-- File list-roles-Roles.html generated 2018-07-03T12:23:51.912Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-roles-Role' class='big-link'>
<a href='form-roles-Role'>
Add a new Role
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-roles-Roles' class='list' action='{{servlet-context}}/list-roles-Roles' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='roles'>
<thead>
<tr>
@ -57,7 +28,7 @@ name
<input id='name' type='text' name='name' value='{{ params.name }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -78,30 +49,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-roles-Roles');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-teams-Teams.html generated 2018-07-01T22:15:35.287Z by adl.to-selmer-templates.
<!-- File list-teams-Teams.html generated 2018-07-03T12:23:51.885Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-teams-Team' class='big-link'>
<a href='form-teams-Team'>
Add a new Team
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-teams-Teams' class='list' action='{{servlet-context}}/list-teams-Teams' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='teams'>
<thead>
<tr>
@ -75,7 +46,7 @@ longitude
<input id='longitude' type='number' name='longitude' value='{{ params.longitude }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -107,30 +78,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-teams-Teams');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -1,44 +1,15 @@
{% extends "base.html" %}
<!-- File list-visits-Visits.html generated 2018-07-01T22:15:35.283Z by adl.to-selmer-templates.
<!-- File list-visits-Visits.html generated 2018-07-03T12:23:51.884Z by adl.to-selmer-templates.
See [Application Description Language](https://github.com/simon-brooke/adl).-->
{% block back-links %}
<div>
<div class='back-link-container'>
{% ifunequal params.offset "0" %}
<a id='prev-selector' class='back-link'>
Previous
</a>
{% else %}
<a id='back-link' class='back-link' href='{{servlet-context}}/admin'>
Back
</a>
{% endifunequal %}
</div>
</div>
{% endblock %}
{% block big-links %}
<div>
{% block content %}
<form id='content' class='list'>
<div class='big-link-container'>
<a id='next-selector' role='button' class='big-link'>
Next
</a>
</div>
<div class='big-link-container'>
<a href='form-visits-Visit' class='big-link'>
<a href='form-visits-Visit'>
Add a new Visit
</a>
</div>
</div>
{% endblock %}
{% block content %}
<form id='list-visits-Visits' class='list' action='{{servlet-context}}/list-visits-Visits' method='POST'>
{% csrf-field %}
<input id='offset' type='hidden' value='{{params.offset|default:0}}'/>
<input id='limit' type='hidden' value='{{params.limit|default:50}}'/>
<table caption='visits'>
<thead>
<tr>
@ -69,7 +40,7 @@ date
<input id='date' type='date' name='date' value='{{ params.date }}'/>
</th>
<th>
<input type='submit' id='search-widget' value='Search'/>
<input type='submit' id='search' value='Search'/>
</th>
</tr>
</thead>
@ -100,30 +71,15 @@ View
</tr>
{% endfor %}
</tbody>
<tfoot>
<div class='back-link-container'>
<input id='page' name='page' disabled='{% ifequal offset 0 %} false {% else %} true {% endifequal %}' value='Previous'/>
</div>
<div class='big-link-container'>
<input id='page' name='page' disabled='false' value='Next'/>
</div>
</tfoot>
</table>
</form>
{% endblock %}
{% block extra-script %}
var form = document.getElementById('list-visits-Visits');
var ow = document.getElementById('offset');
var lw = document.getElementById('limit');
form.addEventListener('submit', function() {
ow.value='0';
});
{% ifunequal offset 0 %}
document.getElementById('prev-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)-parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endifunequal %}
document.getElementById('next-selector').addEventListener('click', function () {
ow.value=(parseInt(ow.value)+parseInt(lw.value));
console.log('Updated offset to ' + ow.value);
form.submit();
});
{% endblock %}

View file

@ -72,6 +72,8 @@
(-> #'auto-selmer-routes
(wrap-routes middleware/wrap-csrf)
(wrap-routes middleware/wrap-formats))
(-> #'auto-rest-routes
(wrap-routes middleware/wrap-formats))
(-> #'rest-routes
(wrap-routes middleware/wrap-formats))
'oauth-routes

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
(ns ^{:doc "Routes which handle data transfer to/from the canvasser app."
(ns ^{:doc "Manually maintained routes which handle data transfer to/from the canvasser app."
:author "Simon Brooke"} youyesyet.routes.rest
(:require [clojure.core.memoize :as memo]
[clojure.java.io :as io]
@ -36,6 +36,7 @@
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; See also src/clj/youyesyet/routes/auto-json.clj
(def in-get-local-data
"Local data is volatile, because hopefully canvassers are updating it as they
@ -82,13 +83,8 @@
(in-get-local-data here)))
(defn get-issues
"Get current issues. No arguments expected."
[request])
(defroutes rest-routes
(GET "/rest/get-local-data" request (get-local-data request))
(GET "/rest/get-local-data" request (route/restricted (get-local-data request)))
;; (GET "/rest/get-issues" request (route/restricted (get-issues request)))
;; (GET "/rest/set-intention" request (route/restricted (set-intention request)))
;; (GET "/rest/request-followup" request (route/restricted (request-followup request))))

View file

@ -1,10 +1,10 @@
(ns youyesyet.utils
#?(:clj (require [clojure.tools.logging :as log]))
)
#?(:clj (:require [clojure.tools.logging :as log])
:cljs (:require [cljs.reader :refer [read-string]])))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;; youyesyet.locality: small utility functions.
;;;; youyesyet.utils: small utility functions.
;;;;
;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License
@ -27,9 +27,11 @@
(defn coerce-to-number [v]
"If it is possible to do so, coerce `v` to a number"
;; TODO: this doesn't work in cljs.
(if (number? v) v
(try
(read-string (str v))
#?(:clj (catch Exception any
(log/error (str "Could not coerce '" v "' to number: " any)))
:cljs (js/console.log (str "Could not coerce '" v "' to number: " any))))))
:cljs (catch js/Object any
(js/console.log (str "Could not coerce '" v "' to number: " any)))))))

View file

@ -104,8 +104,10 @@
(if content [content]
[:div.error (str "No content in page " @(rf/subscribe [:page]))])
[:footer
[:div.error {:style [:display (if error "block" "none")]} (str error)]
[:div.feedback {:style [:display (if feedback :block :none)]} (str feedback)]
[:div.error {:style [:display (if (empty? error) :none :block)]} (apply str error)]
[:div.feedback
{:style [:display (if (empty? feedback) :none :block)]}
(apply str (map #(h/feedback-messages %) (distinct feedback)))]
[:div.queue (if
(nil? outqueue) ""
(str (count outqueue) " items queued to send"))]]]))
@ -190,6 +192,9 @@
(defn init! []
(rf/dispatch-sync [:initialize-db])
(h/get-current-location)
(rf/dispatch [:fetch-locality])
(rf/dispatch [:fetch-options])
(rf/dispatch [:fetch-issues])
(load-interceptors!)
(hook-browser-navigation!)
(mount-components))

View file

@ -2,9 +2,12 @@
:author "Simon Brooke"}
youyesyet.canvasser-app.handlers
(:require [cljs.reader :refer [read-string]]
[re-frame.core :refer [dispatch reg-event-db]]
[cemerick.url :refer (url url-encode)]
[day8.re-frame.http-fx]
[re-frame.core :refer [dispatch reg-event-db reg-event-fx subscribe]]
[ajax.core :refer [GET]]
[ajax.json :refer [json-request-format json-response-format]]
[youyesyet.canvasser-app.state :as db]
[youyesyet.utils :refer :all]
))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -34,9 +37,47 @@
"Return a state like this state except with the error and feedback messages
set nil"
[state]
(merge state {:error nil :feedback nil}))
(merge state {:error '() :feedback '()}))
(def source-host (assoc
(url js/window.location)
:path "/"
:query nil
:anchor nil))
(def feedback-messages
{:fetch-locality "Fetching local data."
:send-request "Request has been queued."
})
(defn add-to-feedback
"Add the value of `k` in `feedback-messages` to the feedback in this `db`."
[db k]
(assoc db :feedback (cons k (:feedback db))))
(defn remove-from-feedback
"Remove the value of `k` in `feedback-messages` to the feedback in this `db`."
[db k]
(assoc db
:feedback
(remove
#(= % k)
(:feedback db))))
(defn coerce-to-number [v]
"If it is possible to do so, coerce `v` to a number.
NOTE: I tried to do this in *cljc*, but it did not work. Leave it alone."
(if (number? v) v
(try
(read-string (str v))
(catch js/Object any
(js/console.log (str "Could not coerce '" v "' to number: " any))
v))))
(defn get-elector
@ -60,17 +101,250 @@
(:electors state) "'")))))
;; map stuff. If we do this in canvasser-app.views.map we get circular
;; references, so do it here.
(defn pin-image
"select the name of a suitable pin image for this address"
[address]
(let [intentions
(set
(remove
nil?
(map
:intention
(mapcat :electors
(:dwellings address)))))]
(case (count intentions)
0 "unknown-pin"
1 (str (name (first intentions)) "-pin")
"mixed-pin")))
(defn map-pin-click-handler
"On clicking on the pin, navigate to the electors at the address.
This way of doing it adds an antry in the browser location history,
so back links work."
[id]
(js/console.log (str "Click handler for address #" id))
(let [view @(subscribe [:view])
centre (.getCenter view)]
(dispatch [:set-zoom (.getZoom view)])
(dispatch [:set-latitude (.-lat centre)])
(dispatch [:set-longitude (.-lng centre)]))
(set! window.location.href (str "#building/" id)))
(defn add-map-pin
"Add a map-pin at this address in this map view"
[address view]
(let [lat (:latitude address)
lng (:longitude address)
pin (.icon js/L
(clj->js
{:iconAnchor [16 41]
:iconSize [32 42]
:iconUrl (str "img/map-pins/" (pin-image address) ".png")
:riseOnHover true
:shadowAnchor [16 23]
:shadowSize [57 24]
:shadowUrl "img/map-pins/shadow_pin.png"}))
marker (.marker js/L
(.latLng js/L lat lng)
(clj->js {:icon pin
:title (:address address)}))]
(.on (.addTo marker view) "click" (fn [_] (map-pin-click-handler (str (:id address)))))
marker))
(defn map-remove-pins
"Remove all pins from this map `view`. Side-effecty; liable to be problematic."
[view]
(try
(if
view
(.eachLayer
view
(fn [layer]
(if
(instance? layer js/L.Marker)
(.removeLayer view layer)))))
(catch js/Object any (js/console.log (str "Failed to remove pins from map: " any))))
view)
(defn refresh-map-pins
"Refresh the map pins on this map. Side-effecty; liable to be problematic."
[]
(let [view (map-remove-pins @(subscribe [:view]))
addresses @(subscribe [:addresses])]
(if
view
(do
(js/console.log (str "Adding " (count addresses) " pins"))
(doall (map #(add-map-pin % view) addresses)))
(js/console.log "View is not yet ready"))
view))
(reg-event-db
:initialize-db
(fn [_ _]
db/default-db))
(defn get-current-location []
"Get the current location from the device."
(try
(if (.-geolocation js/navigator)
(.getCurrentPosition
(.-geolocation js/navigator)
(fn [position]
(js/console.log "Current location is: " + position)
(dispatch [:set-latitude (.-latitude (.-coords position))])
(dispatch [:set-longitude (.-longitude (.-coords position))])))
(js/console.log "Geolocation not available"))
(catch js/Object any
(js/console.log "Exception while trying to access location: " + any))))
;; (reg-event-fx
;; :feedback
;; (fn [x y]
;; (js/console.log (str "Feedback event called with x = " x "; y = " y))
;; (:db x)))
;; (reg-event-fx
;; :issues
;; (fn [x y]
;; (js/console.log (str "Issues event called with x = " x "; y = " y))
;; (:db x)))
;; (reg-event-fx
;; :options
;; (fn [x y]
;; (js/console.log (str "Options event called with x = " x "; y = " y))
;; (:db x)))
;; (reg-event-fx
;; :event
;; (fn [x y]
;; (js/console.log (str "Event event called with x = " x "; y = " y))
;; (:db x)))
(reg-event-fx
:fetch-locality
(fn [{db :db} _]
(js/console.log "Fetching locality data")
;; we return a map of (side) effects
{:http-xhrio {:method :get
:uri (str source-host
"rest/get-local-data?latitude="
(:latitude db)
"&longitude="
(:longitude db))
:format (json-request-format)
:response-format (json-response-format {:keywords? true})
:on-success [:process-locality]
:on-failure [:bad-locality]}
:db (add-to-feedback db :fetch-locality)}))
(reg-event-db
:process-locality
(fn
[db [_ response]]
(js/console.log "Updating locality data")
(assoc
(remove-from-feedback db :fetch-locality)
(refresh-map-pins)
:addresses (js->clj response))))
(reg-event-db
:bad-locality
(fn [db _]
;; TODO: signal something has failed? It doesn't matter very much, unless it keeps failing.
(js/console.log "Failed to fetch locality data")
(assoc
(remove-from-feedback db :fetch-locality)
:error (cons :fetch-locality (:error db)))))
(reg-event-fx
:fetch-options
(fn [{db :db} _]
(js/console.log "Fetching options")
;; we return a map of (side) effects
{:http-xhrio {:method :get
:uri (str source-host "json/auto/list-options")
:format (json-request-format)
:response-format (json-response-format {:keywords? true})
:on-success [:process-options]
:on-failure [:bad-options]}
:db (add-to-feedback db :fetch-options)}))
(reg-event-db
:process-options
(fn
[db [_ response]]
(js/console.log "Updating options")
(assoc
(remove-from-feedback db :fetch-options)
:options (js->clj response))))
(reg-event-db
:bad-options
(fn [db _]
(js/console.log "Failed to fetch options")
(assoc
(remove-from-feedback db :fetch-options)
:error (cons :fetch-options (:error db)))))
(reg-event-fx
:fetch-issues
(fn [{db :db} _]
(js/console.log "Fetching issues")
;; we return a map of (side) effects
{:http-xhrio {:method :get
:uri (str source-host "json/auto/list-issues")
:format (json-request-format)
:response-format (json-response-format {:keywords? true})
:on-success [:process-issues]
:on-failure [:bad-issues]}
:db (add-to-feedback db :fetch-issues)}))
(reg-event-db
:process-issues
(fn
[db [_ response]]
(js/console.log "Updating issues")
(assoc
(remove-from-feedback db :fetch-issues)
:issues (js->clj response))))
(reg-event-db
:bad-issues
(fn [db _]
(js/console.log "Failed to fetch issues")
(assoc
(remove-from-feedback db :fetch-issues)
:error (cons :fetch-issues (:error db)))))
(reg-event-db
:send-intention
(fn [db [_ args]]
(let [intention (:intention args)
elector-id (coerce-to-number (:elector-id args))
elector-id (:elector-id args)
old-elector (first
(remove nil?
(map
@ -97,11 +371,11 @@
(:dwellings old-address))))]
(cond
(nil? old-elector)
(assoc db :error "No elector found; not setting intention")
(= intention (:intention old-elector))
(do
(js/console.log "Elector's intention hasn't changed; not setting intention")
db)
(assoc db :error (cons "No elector found; not setting intention" (:error db))
(= intention (:intention old-elector))
(do
(js/console.log "Elector's intention hasn't changed; not setting intention")
db))
true
(do
(js/console.log (str "Setting intention of elector " old-elector " to " intention))
@ -125,8 +399,7 @@
(if (and (:elector db) (:issue db) (:telephone db))
(do
(js/console.log "Sending request")
(assoc db
:feedback "Request has been queued"
(assoc (add-to-feedback db :send-request)
:outqueue (cons
{:elector-id (:id (:elector db))
:issue (:issue db)
@ -136,15 +409,16 @@
(reg-event-db
:set-active-page
(fn [db [_ page]]
(if page
(assoc (clear-messages db) :page page))))
(fn [db [_ k]]
(if k
(assoc (clear-messages db) :page k)
db)))
(reg-event-db
:set-address
(fn [db [_ address-id]]
(let [id (coerce-to-number address-id)
(let [id (coerce-to-number address-id)
address (first (remove nil? (map #(if (= id (:id %)) %) (:addresses db))))]
(if
(= (count (:dwellings address)) 1)
@ -167,7 +441,7 @@
consent (:consent args)
elector-id (coerce-to-number (:elector-id args))
elector (get-elector elector-id db)]
(js/console.log (str "Setting page to " page ", consent to " consent " for " elector))
(js/console.log (str "Setting page to " page ", consent to " consent " for " (:name elector)))
(assoc (clear-messages db) :elector (assoc elector :consent true) :page page))))
@ -200,7 +474,7 @@
:set-elector-and-page
(fn [db [_ args]]
(let [page (:page args)
elector-id (coerce-to-number (:elector-id args))
elector-id (:elector-id args)
elector (get-elector elector-id db)]
(js/console.log (str "Setting page to " page ", elector to " elector))
(assoc (clear-messages db) :elector elector :page page))))
@ -252,18 +526,3 @@
(if (integer? zoom)
(assoc db :zoom zoom)
db)))
(defn get-current-location []
"Get the current location from the device."
(try
(if (.-geolocation js/navigator)
(.getCurrentPosition
(.-geolocation js/navigator)
(fn [position]
(js/console.log "Current location is: " + position)
(dispatch [:set-latitude (.-latitude (.-coords position))])
(dispatch [:set-longitude (.-longitude (.-coords position))])))
(js/console.log "Geolocation not available"))
(catch js/Object any
(js/console.log "Exception while trying to access location: " + any))))

View file

@ -29,59 +29,128 @@
;;; The atom gets updated by 'events' registered in handler.cljs, q.v.
(def default-db
{;;; the currently selected address, if any.
:address {:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2569057
:dwellings [{:id 1
: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.2570944
:dwellings [{:id 1
: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}]}]}
{:id 2 :address "15 Imaginary Terrace, IM1 3TE" :latitude 55.8252354 :longitude -4.2572778
:dwellings [{:id 2
:electors [{:id 5 :name "Beryl Brown" :gender :female}
{:id 6 :name "Betty Black" :gender :female}]}]}
{
:addresses
[{:locality 548223905,
:address
"HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF",
:phone nil,
:postcode "DG7 1RF",
:longitude -3.905045374625994,
:district_id 1,
:dwellings
[{:address_id_expanded
"HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF",
:address_id 18,
:sub_address "",
:id 17,
:id_2 17,
:address_id_2 18,
:sub_address_2 "",
:electors
[{:email nil,
:dwelling_id_2 17,
:dwelling_id_expanded
"HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, ",
:intentions
[{:locality 548223905,
:visit_id_expanded
"HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, 2018-06-14 20:29:34.721522",
:option_id_expanded "Yes",
:option_id "Yes",
:option_id_2 "Yes",
:visit_id_2 1,
:elector_id_2 61,
:visit_id 1,
:elector_id 61,
:id 1,
:elector_id_expanded nil,
:id_2 1}],
:phone nil,
:phone_2 nil,
:gender_expanded "Female",
:name "Alice Sutherland",
:dwelling_id 17,
:id 61,
:gender "Female",
:gender_2 "Female",
:name_2 "Alice Sutherland",
:email_2 nil,
:id_2 61}
{:email nil,
:dwelling_id_2 17,
:dwelling_id_expanded
"HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, ",
:intentions [],
:phone nil,
:phone_2 nil,
:gender_expanded "Female",
:name "Charlie Sutherland",
:dwelling_id 17,
:id 62,
:gender "Female",
:gender_2 "Female",
:name_2 "Charlie Sutherland",
:email_2 nil,
:id_2 62}
{:email nil,
:dwelling_id_2 17,
:dwelling_id_expanded
"HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, ",
:intentions [],
:phone nil,
:phone_2 nil,
:gender_expanded "Male",
:name "Keith Sutherland",
:dwelling_id 17,
:id 64,
:gender "Male",
:gender_2 "Male",
:name_2 "Keith Sutherland",
:email_2 nil,
:id_2 64}
{:email nil,
:dwelling_id_2 17,
:dwelling_id_expanded
"HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, ",
:intentions [],
:phone nil,
:phone_2 nil,
:gender_expanded "Female",
:name "Lucy Sutherland",
:dwelling_id 17,
:id 63,
:gender "Female",
:gender_2 "Female",
:name_2 "Lucy Sutherland",
:email_2 nil,
:id_2 63}]}],
:id 18,
:latitude 54.8222716877376}]
{:id 3 :address "17 Imaginary Terrace, IM1 3TE" :latitude 55.825166 :longitude -4.257026
:dwellings [{:id 3 :sub-address "Flat 1"
:electors [{:id 7 :name "Catriona Crathie" :gender :female :intention :yes}
{:id 8 :name "Colin Caruthers" :gender :male :intention :yes}
{:id 9 :name "Calum Crathie" :intention :yes}]}
{:id 4 :sub-address "Flat 2"
:electors [{:id 1 :name "David Dewar" :gender :male :intention :no}]}]}]
;;; the currently selected address, if any.
:address nil
;;; electors at the currently selected dwelling
: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}]
:electors nil
;;; any error to display
:error nil
;;; the issue from among the issues which is currently selected.
;;; any confirmation message to display
:feedback nil
:feedback '()
;;; the currently selected issue
:issue "Currency"
:issue nil
;;; the issues selected for the issues page on this day.
:issues {"Currency" "Scotland could keep the Pound, or use the Euro. But we could also set up a new currency of our own. Yada yada yada"
"Monarchy" "Scotland could keep the Queen. This is an issue to be decided after independence. Yada yada yada"
"Defence" "Scotland will not have nuclear weapons, and will probably not choose to engage in far-off wars. But we could remain members of NATO"}
:issues nil
;;; message of the day
:motd "This is a test version only. There is no real data."
;;; the options from among which electors can select.
:options [{:id :yes :description "Yes"} {:id :no :description "No"}]
:options nil
;;; the queue of items waiting to be transmitted.
:outqueue ()
;;; the currently displayed page within the app.
:page :home
:view nil
:latitude 55.82
:longitude -4.25
:latitude 54.82
:longitude -3.90
:zoom 12})

View file

@ -37,15 +37,16 @@
[:div.back-link-container {:key (gensym "back-link")}
[:a.back-link {:href target} "Back"]]))
(defn big-link
[text & {:keys [target handler]}]
(js/console.log (str "Constructing big link; target is '" target "'; handler is '" handler "'"))
[:div.big-link-container {:key (gensym "big-link")}
[:a.big-link (merge
(if target {:href target}{})
(if handler {:on-click handler}{}))
text]])
(defn nav-link [uri title page collapsed?]
(let [selected-page @(rf/subscribe [:page])]
[:li.nav-item

View file

@ -50,12 +50,10 @@
(defn gender-cell
[elector]
(let [gender (:gender elector)
image (if gender (name gender) "unknown")]
image (if gender (name gender) "Unknown")]
[:td {:key (str "gender-" (:id elector))}
[:a {:href (str "#gdpr/" (:id elector))}
[:img {:src (str "img/gender/" image ".png") :alt image
;; :on-click #(go-to-gdpr-for-elector elector)
}]]]))
[:img {:src (str "img/gender/" image ".png") :alt image}]]]))
(defn genders-row

View file

@ -70,7 +70,7 @@
[elector]
[:tr
[:td {:key (:id elector)}
[:a {:href (str "#/issues/" (:id elector))}
[:a {:href (str "#issues/" (:id elector))}
[:img {:src "img/issues.png" :alt "Issues"}]]]])

View file

@ -38,14 +38,13 @@
(defn panel
"Generate the issue panel."
[]
(let [issue @(subscribe [:issue])
issues @(subscribe [:issues])]
(let [issue @(subscribe [:issue])]
[:div
[:h1 issue]
[:h1 (:id issue)]
[:div.container {:id "main-container"}
[:div {:id "issue"}
[:div {:id "issue-text"
:dangerouslySetInnerHTML
{:__html (md->html (issues issue))}}]]
{:__html (md->html (:brief issue))}}]]
(ui/big-link "Request call" :target "#/followup")
(ui/back-link)]]))

View file

@ -46,5 +46,5 @@
[:div.container {:id "main-container"}
(ui/back-link)
[:div {:id "issue-list"}
(map (fn [k] (ui/big-link k :target (str "#/issue/" k))) (keys issues))]]]
(map (fn [i] (ui/big-link (:id i) :target (str "#issue/" (:id i)))) issues)]]]
(ui/error-panel "No issues loaded"))))

View file

@ -1,9 +1,9 @@
(ns ^{:doc "Canvasser app map view panel."
:author "Simon Brooke"}
youyesyet.canvasser-app.views.map
(:require [re-frame.core :refer [reg-sub subscribe dispatch]]
(:require [re-frame.core :refer [reg-sub subscribe dispatch dispatch-sync]]
[reagent.core :as reagent]
[youyesyet.canvasser-app.handlers :refer [get-current-location]]))
[youyesyet.canvasser-app.handlers :refer [get-current-location refresh-map-pins]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
@ -54,66 +54,6 @@
(def osm-url "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png")
(def osm-attrib "Map data &copy; <a href='http://openstreetmap.org'>OpenStreetMap</a> contributors")
(defn pin-image
"select the name of a suitable pin image for this address"
[address]
(let [intentions
(set
(remove
nil?
(map
:intention
(mapcat :electors
(:dwellings address)))))]
(case (count intentions)
0 "unknown-pin"
1 (str (name (first intentions)) "-pin")
"mixed-pin")))
(defn map-pin-click-handler
"On clicking on the pin, navigate to the electors at the address.
This way of doing it adds an antry in the browser location history,
so back links work."
[id]
(js/console.log (str "Click handler for address #" id))
(let [view @(subscribe [:view])
centre (.getCenter view)]
(dispatch [:set-zoom (.getZoom view)])
(dispatch [:set-latitude (.-lat centre)])
(dispatch [:set-longitude (.-lng centre)]))
(set! window.location.href (str "#building/" id)))
;; This way is probably more idiomatic React, but history doesn't work:
;; (defn map-pin-click-handler
;; [id]
;; (dispatch [:set-address id]))
(defn add-map-pin
"Add a map-pin at this address in this map view"
[address view]
(let [lat (:latitude address)
lng (:longitude address)
pin (.icon js/L
(clj->js
{:iconAnchor [16 41]
:iconSize [32 42]
:iconUrl (str "img/map-pins/" (pin-image address) ".png")
:riseOnHover true
:shadowAnchor [16 23]
:shadowSize [57 24]
:shadowUrl "img/map-pins/shadow_pin.png"}))
marker (.marker js/L
(.latLng js/L lat lng)
(clj->js {:icon pin
:title (:address address)}))
]
(.on (.addTo marker view) "click" (fn [_] (map-pin-click-handler (str (:id address)))))
))
;; My gods mapbox is user-hostile!
(defn map-did-mount-mapbox
"Did-mount function loading map tile data from MapBox (proprietary)."
@ -123,8 +63,8 @@
;; NEED TO REPLACE FIXME with your mapID!
(.addTo (.tileLayer js/L "http://{s}.tiles.mapbox.com/v3/FIXME/{z}/{x}/{y}.png"
(clj->js {:attribution "Map data &copy; [...]"
:maxZoom 18}))
view)))
:maxZoom 18})))
view))
(defn map-did-mount-osm
@ -132,28 +72,24 @@
[]
(get-current-location)
(let [view (.setView
(.map js/L "map" (clj->js {:zoomControl false}))
(.map js/L
"map"
(clj->js {:zoomControl false}))
#js [@(subscribe [:latitude]) @(subscribe [:longitude])]
@(subscribe [:zoom]))
addresses @(subscribe [:addresses])]
(js/console.log (str "Adding " (count addresses) " pins"))
(doall (map #(add-map-pin % view) addresses))
(.addTo (.tileLayer js/L osm-url
(clj->js {:attribution osm-attrib
:maxZoom 18}))
view)
(dispatch [:set-view view])
@(subscribe [:zoom]))]
(dispatch-sync [:set-view view])
(refresh-map-pins)
view))
(defn map-did-mount
"Select the actual map provider to use."
[]
(case *map-provider*
:mapbox (map-did-mount-mapbox)
:osm (map-did-mount-osm))
;; potentially others
)
(dispatch-sync [:set-view (case *map-provider*
:mapbox (map-did-mount-mapbox)
:osm (map-did-mount-osm)
;; potentially others
)]))
(defn map-render

View file

@ -290,8 +290,11 @@
<property name="current" type="boolean" default="true">
<prompt prompt="Is current?" locale="en-GB"/>
</property>
<list properties="listed" name="Issues"><field property="id"><prompt prompt="id" locale="en-GB"/></field><field property="url"><prompt prompt="url" locale="en-GB"/></field><field property="current"><prompt prompt="Is current?" locale="en-GB"/></field></list>
<form properties="listed" name="Issue"><field property="id"><prompt prompt="id" locale="en-GB"/></field><field property="url"><prompt prompt="url" locale="en-GB"/></field><field property="current"><prompt prompt="Is current?" locale="en-GB"/></field></form>
<property type="text" name="brief">
<prompt prompt="Brief response to issue" locale="en-GB"/>
</property>
<list properties="listed" name="Issues"><field property="id"><prompt prompt="id" locale="en-GB"/></field><field property="url"><prompt prompt="url" locale="en-GB"/></field><field property="current"><prompt prompt="Is current?" locale="en-GB"/></field><field property="brief"><prompt prompt="Brief response to issue" locale="en-GB"/></field></list>
<form properties="listed" name="Issue"><field property="id"><prompt prompt="id" locale="en-GB"/></field><field property="url"><prompt prompt="url" locale="en-GB"/></field><field property="current"><prompt prompt="Is current?" locale="en-GB"/></field><field property="brief"><prompt prompt="Brief response to issue" locale="en-GB"/></field></form>
<permission group="canvassers" permission="read"/>
<permission group="teamorganisers" permission="read"/>
<permission group="issueexperts" permission="read"/>