Compare commits
61 commits
Author | SHA1 | Date | |
---|---|---|---|
|
ef786024d7 | ||
|
f5282a686b | ||
|
10bb2416af | ||
|
ed2dc5a7fb | ||
|
ae0c383365 | ||
|
71d8174869 | ||
|
3f0491d4c5 | ||
|
316c57745b | ||
|
e411eb38b2 | ||
|
918a8205e9 | ||
|
254ee9854a | ||
|
b9f685b528 | ||
|
b21c275157 | ||
|
dcba862b27 | ||
|
b94fa5596d | ||
|
35920a256b | ||
|
e7432e62a4 | ||
|
23591952b8 | ||
|
388bb3fb7d | ||
|
c575b52d01 | ||
|
57182eb9a6 | ||
|
c1dcd33d82 | ||
|
af7a8f7c25 | ||
|
bee88f502d | ||
|
dd471015eb | ||
|
28e00b476b | ||
|
9076e29eb5 | ||
|
a12330b01e | ||
|
7380fc51cf | ||
|
93bd4dbd99 | ||
|
2fddb28ae8 | ||
|
33686d0db5 | ||
|
84a0f07d5f | ||
|
17baf7e800 | ||
|
7d3d4b5d47 | ||
|
237a44ff40 | ||
|
3f337a4d02 | ||
|
7a791f50f4 | ||
|
7ce041ad0c | ||
|
adcdacc6c1 | ||
|
2d4f7a897d | ||
|
dc1195bcbe | ||
|
5b78192190 | ||
|
c22c34ff16 | ||
|
046aa2660f | ||
|
cb9e38cdc8 | ||
|
863a7e3c0e | ||
|
3a8b5be15a | ||
|
54ad57349c | ||
|
3df314ecfc | ||
|
53122b69b1 | ||
|
872fc2b6a8 | ||
|
439f5a2546 | ||
|
b7c745a0a4 | ||
|
7724a2514a | ||
|
028022fd75 | ||
|
33cdd67154 | ||
|
b275000632 | ||
|
72184d2c3c | ||
|
eab2a35cda | ||
|
02b120fb63 |
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -43,3 +43,9 @@ resources/sql/youyesyet\.postgres\.sql
|
|||
/dumps/
|
||||
|
||||
youyesyet\.canonical\.adl\.xml
|
||||
|
||||
youyesyet\.dump\.20180816
|
||||
|
||||
*.tar
|
||||
|
||||
src/clj/youyesyet/cache\.clj
|
||||
|
|
10
CHANGELOG.md
Normal file
10
CHANGELOG.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Change Log
|
||||
All notable changes to this project will be documented in this file. This change log is intended to follow the conventions of [keepachangelog.com](http://keepachangelog.com/).
|
||||
|
||||
# 0.2.1, 2018-09-21
|
||||
|
||||
(Hopefully) fixed map regression in 0.2.0
|
||||
|
||||
# 0.2.0, 2018-09-20
|
||||
|
||||
Second public alpha, most features complete.
|
60
README.md
60
README.md
|
@ -43,6 +43,30 @@ If you're thinking of joining in development on this I'd strongly recommend you
|
|||
You should also read the [User-Oriented Specification](doc/specification/userspec.md) and any other documentation which appears under the *doc/specification* hierarchy.
|
||||
|
||||
|
||||
## Building this
|
||||
|
||||
This application is built using [Application Description Language](https://github.com/simon-brooke/adl/). The `adl` pre-processor is run as a prep task to building the `uberjar`, which in turn is preparatory to building the `uberwar`.
|
||||
|
||||
This will generate a large number of the source files required by YouYesYet, **including** the database initialisation scripts. These generated source files are not, as a matter of policy, held in the repository.
|
||||
|
||||
### What is auto-generated, and how to override it
|
||||
|
||||
The following files are generated from the master file `youyesyet.adl.xml`:
|
||||
|
||||
* `resources/sql/queries.auto.sql` - [HugSQL](https://www.hugsql.org/) queries for selection, insertion, modification and deletion of records of all entities described in the ADL file.
|
||||
* `resources/sql/[application-name].postgres.sql` - [Postgres](https://www.postgresql.org/) database initialisation script including tables for all entities, convenience views for all entities, all necessary link tables and referential integrity constraints.
|
||||
* `resources/templates/auto/*.html` - [Selmer](https://github.com/yogthos/Selmer) templates for each form or list list specified in the ADL file (pages are not yet handled).
|
||||
* `src/clj/[application-name]/routes/auto.clj` - [Compojure]() routes for each form or list list specified in the ADL file (pages are not yet handled).
|
||||
* `src/clj/[application-name]/routes/auto-json.clj` - [Compojure]() routes returning JSON responses for each query generated in `resources/sql/queries.auto.sql`.
|
||||
|
||||
*You are strongly advised never to edit any of these files*.
|
||||
|
||||
* To override any query, add that query to a file `resources/sql/queries.sql`
|
||||
* To add additional material (for example reference data) to the database initialisation, add it to a separate file or a family of separate files.
|
||||
* To override any template, copy the template file from `resources/templates/auto/` to `resources/templates/` and edit it there.
|
||||
* To override any route, write a function of the same name in the namespace `[application-name].routes.manual`.
|
||||
|
||||
|
||||
## Getting the database up
|
||||
|
||||
You'll need a file *profiles.clj*, with content similar to the following; it's not in the repository because it contains passwords.
|
||||
|
@ -59,11 +83,19 @@ Do get the database initialised, run
|
|||
|
||||
createdb youyesyet_dev
|
||||
|
||||
I'm no longer using Migratus as I'm using [Application Description Language]()
|
||||
I'm no longer using Migratus as I'm using [Application Description Language](https://github.com/simon-brooke/adl/)
|
||||
to generate the majority of the application, and, as changes are made to the application
|
||||
description, new database schemas are generated. The database initialisation script will
|
||||
be found at `resources/sql/youyesyet.postgres.sql`. Reference data initialisation scripts
|
||||
will in due course be stored in the same directory.
|
||||
be found at `resources/sql/youyesyet.postgres.sql`. Manually maintained overrides are found in
|
||||
`resources/sql/youyesyet.postgres.overrides.sql`. So to initialise the database, invoke
|
||||
|
||||
psql youyesyet_dev < resources/sql/youyesyet.postgres.sql
|
||||
|
||||
followed by
|
||||
|
||||
psql youyesyet_dev < resources/sql/youyesyet.postgres.overrides.sql
|
||||
|
||||
Reference data initialisation scripts will in due course be stored in the same directory.
|
||||
|
||||
Once we have a more or less finished application it may be worth going back to
|
||||
[Migratus](https://github.com/yogthos/migratus); I might have a go at generating migrations from
|
||||
|
@ -75,23 +107,33 @@ To run in a dev environment, checkout the *develop* branch
|
|||
|
||||
To download and install Javascript delendencies, run
|
||||
|
||||
cd youyesyet
|
||||
lein npm install
|
||||
|
||||
To start a development web server for the application, run:
|
||||
|
||||
lein run
|
||||
Then
|
||||
|
||||
If you're wanting to work on cljs development, you need two terminal sessions. In one run
|
||||
lein repl
|
||||
|
||||
lein run
|
||||
Wait for the clojure `user=>` prompt to appear, and enter
|
||||
|
||||
as above; in the other, run
|
||||
(mount/start)
|
||||
|
||||
This will get the application running for development; ideally, open a new terminal and invoke
|
||||
|
||||
lein figwheel
|
||||
|
||||
which will aid in work on the ClojureScript components.
|
||||
|
||||
## Running in a production environment
|
||||
|
||||
Doesn't really work yet; if you want to try it, see [Bug #36](https://github.com/simon-brooke/youyesyet/issues/36) and check out the associated feature branch.
|
||||
Either
|
||||
|
||||
1. run `lein uberjar` and execute the resulting jar file directly; or
|
||||
2. run `lein uberwar` and serve the resulting war file from a servlet container.
|
||||
|
||||
The [beta production server](https://www.projecthope.scot/) currently runs an uberwar build in Tomcat behind Nginx.
|
||||
|
||||
## Working on this project
|
||||
|
||||
|
@ -122,7 +164,7 @@ Note that all tools recommended in this document are free for non-commercial use
|
|||
|
||||
### Editors/IDEs
|
||||
|
||||
I (Simon) use, like and recommend [LightTable](http://lighttable.com/) as my editor; I used to use Emacs, and there is excellent Clojure tooling for Emacs, but these days Emacs ways of working seem just too far from everything else to be comfortable to me. [NightCode](https://sekao.net/nightcode/) is a lighter-weight Clojure IDE which you may like. There's also [Cursive](https://cursive-ide.com/) but it isn't free and I haven't tried it.
|
||||
I (Simon) use, like and recommend [LightTable](http://lighttable.com/) as my editor; I used to use Emacs, and there is excellent Clojure tooling for Emacs, but these days Emacs ways of working seem just too far from everything else to be comfortable to me. [NightCode](https://sekao.net/nightcode/) is a lighter-weight Clojure IDE which you may like. There's also [Cursive](https://cursive-ide.com/) but it isn't free and I have so far found it more annoying than helpful; or [Counterclockwise](https://github.com/ccw-ide/ccw) which I don't have recent experience of.
|
||||
|
||||
### Git
|
||||
|
||||
|
|
|
@ -75,18 +75,26 @@ Note that:
|
|||
|
||||
The map view shows a map of the streets immediately around their current location, overlaid, on dwellings where canvas has already been done, with icons indicating the voting preference expressed, and with the dwellings where canvassing is still required marked with an icon indicating this:
|
||||
|
||||

|
||||

|
||||
|
||||
Selecting a building on the map leads to
|
||||
|
||||
1. On buildings with multiple flats, a schematic view of the flats in the building (I haven't yet really got a good idea how to do this; it may be just a list). Selecting a flat from this view leads to the *Electors View*;
|
||||
1. On buildings with multiple flats, the *Building View*;
|
||||
2. On buildings with only one dwelling, the *Electors View*.
|
||||
|
||||
## Building View
|
||||
|
||||
A list of dwellings in a building.
|
||||
|
||||

|
||||
|
||||
Selecting a flat from this view leads to the *Electors View*.
|
||||
|
||||
## Electors View
|
||||
|
||||
The *Electors View* shows a schematic of the registered electors in a dwelling:
|
||||
|
||||

|
||||

|
||||
|
||||
One figure is shown for each elector, labelled with their name. In the dummy pages I've shown gendered stick figures, because I believe that in many casesthis will help the canvasser identify the person who has answered the door; but this may be seen as excluding electors with non-binary gender, and, in any case, I believe we don't actually get gender data (other than salutation) in the electoral roll data. So this may have to be reconsidered.
|
||||
|
||||
|
@ -112,9 +120,18 @@ The *Issues View* is a simple list of issues:
|
|||
| Other |
|
||||
+------------------------------------------------+
|
||||
|
||||

|
||||
|
||||
|
||||
This list will not be hard-coded but will be dynamic; thus, if we find an issue we didn't predict is regularly coming up on the doorstep an *Administrator* can add it to the list.
|
||||
|
||||
Selecting the back button from the *Issues View* returns to the *Electors View*. Selecting any option from the Issues view leads to a single page giving top level points the canvasser can make to the elector on the doorstep, and a link to a *Followup Request* form. There is also a 'back' button allowing the user to return to the *Issues View*
|
||||
Selecting the back button from the *Issues View* returns to the *Electors View*. Selecting any option from the Issues view leads to the *Issue View*.
|
||||
|
||||
## Issue View
|
||||
|
||||
A single page giving top level points the canvasser can make to the elector on the doorstep, regarding the selected issue; and a link to a *Followup Request* form. There is also a 'back' button allowing the user to return to the *Issues View*.
|
||||
|
||||

|
||||
|
||||
## Followup Request form
|
||||
|
||||
|
@ -132,6 +149,8 @@ The *Followup Request* form is a simple form which allows the canvasser to recor
|
|||
| |
|
||||
+------------------------------------------------+
|
||||
|
||||

|
||||
|
||||
## How Street Canvassers will use the system
|
||||
|
||||
Street Canvassers will typically use the system by
|
||||
|
|
19
docs/authorisation.html
Normal file
19
docs/authorisation.html
Normal file
File diff suppressed because one or more lines are too long
14
docs/competitors.html
Normal file
14
docs/competitors.html
Normal file
File diff suppressed because one or more lines are too long
551
docs/css/default.css
Normal file
551
docs/css/default.css
Normal file
|
@ -0,0 +1,551 @@
|
|||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
|
||||
font-size: 9pt;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: normal;
|
||||
font-size: 29px;
|
||||
margin: 10px 0 2px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
h5.license {
|
||||
margin: 9px 0 22px 0;
|
||||
color: #555;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.document h1, .namespace-index h1 {
|
||||
font-size: 32px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
#header, #content, .sidebar {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#header {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 22px;
|
||||
color: #f5f5f5;
|
||||
padding: 5px 7px;
|
||||
}
|
||||
|
||||
#content {
|
||||
top: 32px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
padding: 0 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 32px;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sidebar.primary {
|
||||
background: #e2e2e2;
|
||||
border-right: solid 1px #cccccc;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.sidebar.secondary {
|
||||
background: #f2f2f2;
|
||||
border-right: solid 1px #d7d7d7;
|
||||
left: 251px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#content.namespace-index, #content.document {
|
||||
left: 251px;
|
||||
}
|
||||
|
||||
#content.namespace-docs {
|
||||
left: 452px;
|
||||
}
|
||||
|
||||
#content.document {
|
||||
padding-bottom: 10%;
|
||||
}
|
||||
|
||||
#header {
|
||||
background: #3f3f3f;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 18px;
|
||||
font-weight: lighter;
|
||||
text-shadow: -1px -1px 0px #333;
|
||||
}
|
||||
|
||||
#header h1 .project-version {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.project-version {
|
||||
padding-left: 0.15em;
|
||||
}
|
||||
|
||||
#header a, .sidebar a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header a {
|
||||
color: #f5f5f5;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
float: right;
|
||||
font-size: 9pt;
|
||||
font-weight: normal;
|
||||
margin: 4px 3px;
|
||||
padding: 0;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
#header h2 a {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.sidebar h3 {
|
||||
margin: 0;
|
||||
padding: 10px 13px 0 13px;
|
||||
font-size: 19px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.sidebar h3 a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.sidebar h3.no-link {
|
||||
color: #636363;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
padding: 7px 0 6px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar ul.index-link {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.sidebar li {
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.sidebar li a, .sidebar li .no-link {
|
||||
border-left: 3px solid transparent;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sidebar li .no-link {
|
||||
display: block;
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sidebar li .inner {
|
||||
display: inline-block;
|
||||
padding-top: 7px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.sidebar li a, .sidebar li .tree {
|
||||
height: 31px;
|
||||
}
|
||||
|
||||
.depth-1 .inner { padding-left: 2px; }
|
||||
.depth-2 .inner { padding-left: 6px; }
|
||||
.depth-3 .inner { padding-left: 20px; }
|
||||
.depth-4 .inner { padding-left: 34px; }
|
||||
.depth-5 .inner { padding-left: 48px; }
|
||||
.depth-6 .inner { padding-left: 62px; }
|
||||
|
||||
.sidebar li .tree {
|
||||
display: block;
|
||||
float: left;
|
||||
position: relative;
|
||||
top: -10px;
|
||||
margin: 0 4px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar li.depth-1 .tree {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar li .tree .top, .sidebar li .tree .bottom {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.sidebar li .tree .top {
|
||||
border-left: 1px solid #aaa;
|
||||
border-bottom: 1px solid #aaa;
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
.sidebar li .tree .bottom {
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.sidebar li.branch .tree .bottom {
|
||||
border-left: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.sidebar.primary li.current a {
|
||||
border-left: 3px solid #a33;
|
||||
color: #a33;
|
||||
}
|
||||
|
||||
.sidebar.secondary li.current a {
|
||||
border-left: 3px solid #33a;
|
||||
color: #33a;
|
||||
}
|
||||
|
||||
.namespace-index h2 {
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.namespace-index h3 {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.namespace-index .topics {
|
||||
padding-left: 30px;
|
||||
margin: 11px 0 0 0;
|
||||
}
|
||||
|
||||
.namespace-index .topics li {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.namespace-docs h3 {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.public h3 {
|
||||
margin: 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.usage {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.public {
|
||||
margin: 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
padding-top: 14px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.public:last-child {
|
||||
margin-bottom: 20%;
|
||||
}
|
||||
|
||||
.members .public:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.members {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.members h4 {
|
||||
color: #555;
|
||||
font-weight: normal;
|
||||
font-variant: small-caps;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.members .inner {
|
||||
padding-top: 5px;
|
||||
padding-left: 12px;
|
||||
margin-top: 2px;
|
||||
margin-left: 7px;
|
||||
border-left: 1px solid #bbb;
|
||||
}
|
||||
|
||||
#content .members .inner h3 {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.members .public {
|
||||
border-top: none;
|
||||
margin-top: 0;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.members .public:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
h4.type,
|
||||
h4.dynamic,
|
||||
h4.added,
|
||||
h4.deprecated {
|
||||
float: left;
|
||||
margin: 3px 10px 15px 0;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.public h4.type,
|
||||
.public h4.dynamic,
|
||||
.public h4.added,
|
||||
.public h4.deprecated {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 3px 0 0 10px;
|
||||
}
|
||||
|
||||
.members h4.type,
|
||||
.members h4.added,
|
||||
.members h4.deprecated {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
h4.type {
|
||||
color: #717171;
|
||||
}
|
||||
|
||||
h4.dynamic {
|
||||
color: #9933aa;
|
||||
}
|
||||
|
||||
h4.added {
|
||||
color: #508820;
|
||||
}
|
||||
|
||||
h4.deprecated {
|
||||
color: #880000;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.namespace:last-child {
|
||||
margin-bottom: 10%;
|
||||
}
|
||||
|
||||
.index {
|
||||
padding: 0;
|
||||
font-size: 80%;
|
||||
margin: 15px 0;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.index * {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.index p {
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.index li {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.index ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.type-sig {
|
||||
clear: both;
|
||||
color: #088;
|
||||
}
|
||||
|
||||
.type-sig pre {
|
||||
padding-top: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.usage code {
|
||||
display: block;
|
||||
color: #008;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.usage code:first-child {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.public p:first-child, .public pre.plaintext {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.doc {
|
||||
margin: 0 0 26px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.public .doc {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.namespace-index .doc {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.namespace-index .namespace .doc {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-weight: normal;
|
||||
font-size: 20px;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 15px;
|
||||
margin: 22px 0 -4px 0;
|
||||
}
|
||||
|
||||
.doc, .public, .namespace .index {
|
||||
max-width: 680px;
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
.markdown pre > code {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.markdown pre > code, .src-link a {
|
||||
border: 1px solid #e4e4e4;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.markdown code:not(.hljs), .src-link a {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
pre.deps {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
border: 1px solid #e4e4e4;
|
||||
border-radius: 2px;
|
||||
padding: 10px;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
border-style: solid;
|
||||
border-top: none;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.doc ul, .doc ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.doc table {
|
||||
border-collapse: collapse;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.doc table td, .doc table th {
|
||||
border: 1px solid #dddddd;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.doc table th {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
|
||||
.doc dl {
|
||||
margin: 0 10px 20px 10px;
|
||||
}
|
||||
|
||||
.doc dl dt {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 3px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.doc dl dd {
|
||||
padding: 5px 0;
|
||||
margin: 0 0 5px 10px;
|
||||
}
|
||||
|
||||
.doc abbr {
|
||||
border-bottom: 1px dotted #333;
|
||||
font-variant: none;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.src-link {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.src-link a {
|
||||
font-size: 70%;
|
||||
padding: 1px 4px;
|
||||
text-decoration: none;
|
||||
color: #5555bb;
|
||||
}
|
97
docs/css/highlight.css
Normal file
97
docs/css/highlight.css
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attribute {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #009926;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
173
docs/database.html
Normal file
173
docs/database.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/index.html
Normal file
3
docs/index.html
Normal file
File diff suppressed because one or more lines are too long
2
docs/js/highlight.min.js
vendored
Normal file
2
docs/js/highlight.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
docs/js/jquery.min.js
vendored
Normal file
4
docs/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
112
docs/js/page_effects.js
Normal file
112
docs/js/page_effects.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
function visibleInParent(element) {
|
||||
var position = $(element).position().top
|
||||
return position > -50 && position < ($(element).offsetParent().height() - 50)
|
||||
}
|
||||
|
||||
function hasFragment(link, fragment) {
|
||||
return $(link).attr("href").indexOf("#" + fragment) != -1
|
||||
}
|
||||
|
||||
function findLinkByFragment(elements, fragment) {
|
||||
return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first()
|
||||
}
|
||||
|
||||
function scrollToCurrentVarLink(elements) {
|
||||
var elements = $(elements);
|
||||
var parent = elements.offsetParent();
|
||||
|
||||
if (elements.length == 0) return;
|
||||
|
||||
var top = elements.first().position().top;
|
||||
var bottom = elements.last().position().top + elements.last().height();
|
||||
|
||||
if (top >= 0 && bottom <= parent.height()) return;
|
||||
|
||||
if (top < 0) {
|
||||
parent.scrollTop(parent.scrollTop() + top);
|
||||
}
|
||||
else if (bottom > parent.height()) {
|
||||
parent.scrollTop(parent.scrollTop() + bottom - parent.height());
|
||||
}
|
||||
}
|
||||
|
||||
function setCurrentVarLink() {
|
||||
$('.secondary a').parent().removeClass('current')
|
||||
$('.anchor').
|
||||
filter(function(index) { return visibleInParent(this) }).
|
||||
each(function(index, element) {
|
||||
findLinkByFragment(".secondary a", element.id).
|
||||
parent().
|
||||
addClass('current')
|
||||
});
|
||||
scrollToCurrentVarLink('.secondary .current');
|
||||
}
|
||||
|
||||
var hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }())
|
||||
|
||||
function scrollPositionId(element) {
|
||||
var directory = window.location.href.replace(/[^\/]+\.html$/, '')
|
||||
return 'scroll::' + $(element).attr('id') + '::' + directory
|
||||
}
|
||||
|
||||
function storeScrollPosition(element) {
|
||||
if (!hasStorage) return;
|
||||
localStorage.setItem(scrollPositionId(element) + "::x", $(element).scrollLeft())
|
||||
localStorage.setItem(scrollPositionId(element) + "::y", $(element).scrollTop())
|
||||
}
|
||||
|
||||
function recallScrollPosition(element) {
|
||||
if (!hasStorage) return;
|
||||
$(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + "::x"))
|
||||
$(element).scrollTop(localStorage.getItem(scrollPositionId(element) + "::y"))
|
||||
}
|
||||
|
||||
function persistScrollPosition(element) {
|
||||
recallScrollPosition(element)
|
||||
$(element).scroll(function() { storeScrollPosition(element) })
|
||||
}
|
||||
|
||||
function sidebarContentWidth(element) {
|
||||
var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() })
|
||||
return Math.max.apply(Math, widths)
|
||||
}
|
||||
|
||||
function calculateSize(width, snap, margin, minimum) {
|
||||
if (width == 0) {
|
||||
return 0
|
||||
}
|
||||
else {
|
||||
return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2))
|
||||
}
|
||||
}
|
||||
|
||||
function resizeSidebars() {
|
||||
var primaryWidth = sidebarContentWidth('.primary')
|
||||
var secondaryWidth = 0
|
||||
|
||||
if ($('.secondary').length != 0) {
|
||||
secondaryWidth = sidebarContentWidth('.secondary')
|
||||
}
|
||||
|
||||
// snap to grid
|
||||
primaryWidth = calculateSize(primaryWidth, 32, 13, 160)
|
||||
secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160)
|
||||
|
||||
$('.primary').css('width', primaryWidth)
|
||||
$('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1)
|
||||
|
||||
if (secondaryWidth > 0) {
|
||||
$('#content').css('left', primaryWidth + secondaryWidth + 2)
|
||||
}
|
||||
else {
|
||||
$('#content').css('left', primaryWidth + 1)
|
||||
}
|
||||
}
|
||||
|
||||
$(window).ready(resizeSidebars)
|
||||
$(window).ready(setCurrentVarLink)
|
||||
$(window).ready(function() { persistScrollPosition('.primary')})
|
||||
$(window).ready(function() {
|
||||
$('#content').scroll(setCurrentVarLink)
|
||||
$(window).resize(setCurrentVarLink)
|
||||
})
|
108
docs/scaling.html
Normal file
108
docs/scaling.html
Normal file
File diff suppressed because one or more lines are too long
151
docs/userspec.html
Normal file
151
docs/userspec.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.cache.html
Normal file
3
docs/youyesyet.cache.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.ajax.html
Normal file
3
docs/youyesyet.canvasser-app.ajax.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.core.html
Normal file
3
docs/youyesyet.canvasser-app.core.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.gis.html
Normal file
3
docs/youyesyet.canvasser-app.gis.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.handlers.html
Normal file
3
docs/youyesyet.canvasser-app.handlers.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.state.html
Normal file
3
docs/youyesyet.canvasser-app.state.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.subscriptions.html
Normal file
3
docs/youyesyet.canvasser-app.subscriptions.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.ui-utils.html
Normal file
3
docs/youyesyet.canvasser-app.ui-utils.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.about.html
Normal file
3
docs/youyesyet.canvasser-app.views.about.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.building.html
Normal file
3
docs/youyesyet.canvasser-app.views.building.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.dwelling.html
Normal file
3
docs/youyesyet.canvasser-app.views.dwelling.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.elector.html
Normal file
3
docs/youyesyet.canvasser-app.views.elector.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.followup.html
Normal file
3
docs/youyesyet.canvasser-app.views.followup.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.gdpr.html
Normal file
3
docs/youyesyet.canvasser-app.views.gdpr.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.issue.html
Normal file
3
docs/youyesyet.canvasser-app.views.issue.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.issues.html
Normal file
3
docs/youyesyet.canvasser-app.views.issues.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.canvasser-app.views.map.html
Normal file
3
docs/youyesyet.canvasser-app.views.map.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.config.html
Normal file
3
docs/youyesyet.config.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.db.core.html
Normal file
3
docs/youyesyet.db.core.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.handler.html
Normal file
3
docs/youyesyet.handler.html
Normal file
File diff suppressed because one or more lines are too long
4
docs/youyesyet.layout.html
Normal file
4
docs/youyesyet.layout.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.locality.html
Normal file
3
docs/youyesyet.locality.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.middleware.html
Normal file
3
docs/youyesyet.middleware.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.oauth.html
Normal file
3
docs/youyesyet.oauth.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.outqueue.html
Normal file
3
docs/youyesyet.outqueue.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.auto-json.html
Normal file
3
docs/youyesyet.routes.auto-json.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.auto.html
Normal file
3
docs/youyesyet.routes.auto.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.home.html
Normal file
3
docs/youyesyet.routes.home.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.issue-experts.html
Normal file
3
docs/youyesyet.routes.issue-experts.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.manual.html
Normal file
3
docs/youyesyet.routes.manual.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.oauth.html
Normal file
3
docs/youyesyet.routes.oauth.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.rest.html
Normal file
3
docs/youyesyet.routes.rest.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.roles.html
Normal file
3
docs/youyesyet.routes.roles.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.routes.services.html
Normal file
3
docs/youyesyet.routes.services.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.utils.html
Normal file
3
docs/youyesyet.utils.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/youyesyet.validation.html
Normal file
3
docs/youyesyet.validation.html
Normal file
File diff suppressed because one or more lines are too long
19
documentation/authorisation.html
Normal file
19
documentation/authorisation.html
Normal file
File diff suppressed because one or more lines are too long
14
documentation/competitors.html
Normal file
14
documentation/competitors.html
Normal file
File diff suppressed because one or more lines are too long
551
documentation/css/default.css
Normal file
551
documentation/css/default.css
Normal file
|
@ -0,0 +1,551 @@
|
|||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
|
||||
font-size: 9pt;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: normal;
|
||||
font-size: 29px;
|
||||
margin: 10px 0 2px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
h5.license {
|
||||
margin: 9px 0 22px 0;
|
||||
color: #555;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.document h1, .namespace-index h1 {
|
||||
font-size: 32px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
#header, #content, .sidebar {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#header {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 22px;
|
||||
color: #f5f5f5;
|
||||
padding: 5px 7px;
|
||||
}
|
||||
|
||||
#content {
|
||||
top: 32px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
padding: 0 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 32px;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sidebar.primary {
|
||||
background: #e2e2e2;
|
||||
border-right: solid 1px #cccccc;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.sidebar.secondary {
|
||||
background: #f2f2f2;
|
||||
border-right: solid 1px #d7d7d7;
|
||||
left: 251px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#content.namespace-index, #content.document {
|
||||
left: 251px;
|
||||
}
|
||||
|
||||
#content.namespace-docs {
|
||||
left: 452px;
|
||||
}
|
||||
|
||||
#content.document {
|
||||
padding-bottom: 10%;
|
||||
}
|
||||
|
||||
#header {
|
||||
background: #3f3f3f;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 18px;
|
||||
font-weight: lighter;
|
||||
text-shadow: -1px -1px 0px #333;
|
||||
}
|
||||
|
||||
#header h1 .project-version {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.project-version {
|
||||
padding-left: 0.15em;
|
||||
}
|
||||
|
||||
#header a, .sidebar a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header a {
|
||||
color: #f5f5f5;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
float: right;
|
||||
font-size: 9pt;
|
||||
font-weight: normal;
|
||||
margin: 4px 3px;
|
||||
padding: 0;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
#header h2 a {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.sidebar h3 {
|
||||
margin: 0;
|
||||
padding: 10px 13px 0 13px;
|
||||
font-size: 19px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.sidebar h3 a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.sidebar h3.no-link {
|
||||
color: #636363;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
padding: 7px 0 6px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar ul.index-link {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.sidebar li {
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.sidebar li a, .sidebar li .no-link {
|
||||
border-left: 3px solid transparent;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sidebar li .no-link {
|
||||
display: block;
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sidebar li .inner {
|
||||
display: inline-block;
|
||||
padding-top: 7px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.sidebar li a, .sidebar li .tree {
|
||||
height: 31px;
|
||||
}
|
||||
|
||||
.depth-1 .inner { padding-left: 2px; }
|
||||
.depth-2 .inner { padding-left: 6px; }
|
||||
.depth-3 .inner { padding-left: 20px; }
|
||||
.depth-4 .inner { padding-left: 34px; }
|
||||
.depth-5 .inner { padding-left: 48px; }
|
||||
.depth-6 .inner { padding-left: 62px; }
|
||||
|
||||
.sidebar li .tree {
|
||||
display: block;
|
||||
float: left;
|
||||
position: relative;
|
||||
top: -10px;
|
||||
margin: 0 4px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar li.depth-1 .tree {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar li .tree .top, .sidebar li .tree .bottom {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.sidebar li .tree .top {
|
||||
border-left: 1px solid #aaa;
|
||||
border-bottom: 1px solid #aaa;
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
.sidebar li .tree .bottom {
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.sidebar li.branch .tree .bottom {
|
||||
border-left: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.sidebar.primary li.current a {
|
||||
border-left: 3px solid #a33;
|
||||
color: #a33;
|
||||
}
|
||||
|
||||
.sidebar.secondary li.current a {
|
||||
border-left: 3px solid #33a;
|
||||
color: #33a;
|
||||
}
|
||||
|
||||
.namespace-index h2 {
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.namespace-index h3 {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.namespace-index .topics {
|
||||
padding-left: 30px;
|
||||
margin: 11px 0 0 0;
|
||||
}
|
||||
|
||||
.namespace-index .topics li {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.namespace-docs h3 {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.public h3 {
|
||||
margin: 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.usage {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.public {
|
||||
margin: 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
padding-top: 14px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.public:last-child {
|
||||
margin-bottom: 20%;
|
||||
}
|
||||
|
||||
.members .public:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.members {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.members h4 {
|
||||
color: #555;
|
||||
font-weight: normal;
|
||||
font-variant: small-caps;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.members .inner {
|
||||
padding-top: 5px;
|
||||
padding-left: 12px;
|
||||
margin-top: 2px;
|
||||
margin-left: 7px;
|
||||
border-left: 1px solid #bbb;
|
||||
}
|
||||
|
||||
#content .members .inner h3 {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.members .public {
|
||||
border-top: none;
|
||||
margin-top: 0;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.members .public:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
h4.type,
|
||||
h4.dynamic,
|
||||
h4.added,
|
||||
h4.deprecated {
|
||||
float: left;
|
||||
margin: 3px 10px 15px 0;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.public h4.type,
|
||||
.public h4.dynamic,
|
||||
.public h4.added,
|
||||
.public h4.deprecated {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 3px 0 0 10px;
|
||||
}
|
||||
|
||||
.members h4.type,
|
||||
.members h4.added,
|
||||
.members h4.deprecated {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
h4.type {
|
||||
color: #717171;
|
||||
}
|
||||
|
||||
h4.dynamic {
|
||||
color: #9933aa;
|
||||
}
|
||||
|
||||
h4.added {
|
||||
color: #508820;
|
||||
}
|
||||
|
||||
h4.deprecated {
|
||||
color: #880000;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.namespace:last-child {
|
||||
margin-bottom: 10%;
|
||||
}
|
||||
|
||||
.index {
|
||||
padding: 0;
|
||||
font-size: 80%;
|
||||
margin: 15px 0;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.index * {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.index p {
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.index li {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.index ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.type-sig {
|
||||
clear: both;
|
||||
color: #088;
|
||||
}
|
||||
|
||||
.type-sig pre {
|
||||
padding-top: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.usage code {
|
||||
display: block;
|
||||
color: #008;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.usage code:first-child {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.public p:first-child, .public pre.plaintext {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.doc {
|
||||
margin: 0 0 26px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.public .doc {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.namespace-index .doc {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.namespace-index .namespace .doc {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-weight: normal;
|
||||
font-size: 20px;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 15px;
|
||||
margin: 22px 0 -4px 0;
|
||||
}
|
||||
|
||||
.doc, .public, .namespace .index {
|
||||
max-width: 680px;
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
.markdown pre > code {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.markdown pre > code, .src-link a {
|
||||
border: 1px solid #e4e4e4;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.markdown code:not(.hljs), .src-link a {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
pre.deps {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
border: 1px solid #e4e4e4;
|
||||
border-radius: 2px;
|
||||
padding: 10px;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
border-style: solid;
|
||||
border-top: none;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.doc ul, .doc ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.doc table {
|
||||
border-collapse: collapse;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.doc table td, .doc table th {
|
||||
border: 1px solid #dddddd;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.doc table th {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
|
||||
.doc dl {
|
||||
margin: 0 10px 20px 10px;
|
||||
}
|
||||
|
||||
.doc dl dt {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 3px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.doc dl dd {
|
||||
padding: 5px 0;
|
||||
margin: 0 0 5px 10px;
|
||||
}
|
||||
|
||||
.doc abbr {
|
||||
border-bottom: 1px dotted #333;
|
||||
font-variant: none;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.src-link {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.src-link a {
|
||||
font-size: 70%;
|
||||
padding: 1px 4px;
|
||||
text-decoration: none;
|
||||
color: #5555bb;
|
||||
}
|
97
documentation/css/highlight.css
Normal file
97
documentation/css/highlight.css
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attribute {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #009926;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
173
documentation/database.html
Normal file
173
documentation/database.html
Normal file
File diff suppressed because one or more lines are too long
3
documentation/index.html
Normal file
3
documentation/index.html
Normal file
File diff suppressed because one or more lines are too long
2
documentation/js/highlight.min.js
vendored
Normal file
2
documentation/js/highlight.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
documentation/js/jquery.min.js
vendored
Normal file
4
documentation/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
112
documentation/js/page_effects.js
Normal file
112
documentation/js/page_effects.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
function visibleInParent(element) {
|
||||
var position = $(element).position().top
|
||||
return position > -50 && position < ($(element).offsetParent().height() - 50)
|
||||
}
|
||||
|
||||
function hasFragment(link, fragment) {
|
||||
return $(link).attr("href").indexOf("#" + fragment) != -1
|
||||
}
|
||||
|
||||
function findLinkByFragment(elements, fragment) {
|
||||
return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first()
|
||||
}
|
||||
|
||||
function scrollToCurrentVarLink(elements) {
|
||||
var elements = $(elements);
|
||||
var parent = elements.offsetParent();
|
||||
|
||||
if (elements.length == 0) return;
|
||||
|
||||
var top = elements.first().position().top;
|
||||
var bottom = elements.last().position().top + elements.last().height();
|
||||
|
||||
if (top >= 0 && bottom <= parent.height()) return;
|
||||
|
||||
if (top < 0) {
|
||||
parent.scrollTop(parent.scrollTop() + top);
|
||||
}
|
||||
else if (bottom > parent.height()) {
|
||||
parent.scrollTop(parent.scrollTop() + bottom - parent.height());
|
||||
}
|
||||
}
|
||||
|
||||
function setCurrentVarLink() {
|
||||
$('.secondary a').parent().removeClass('current')
|
||||
$('.anchor').
|
||||
filter(function(index) { return visibleInParent(this) }).
|
||||
each(function(index, element) {
|
||||
findLinkByFragment(".secondary a", element.id).
|
||||
parent().
|
||||
addClass('current')
|
||||
});
|
||||
scrollToCurrentVarLink('.secondary .current');
|
||||
}
|
||||
|
||||
var hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }())
|
||||
|
||||
function scrollPositionId(element) {
|
||||
var directory = window.location.href.replace(/[^\/]+\.html$/, '')
|
||||
return 'scroll::' + $(element).attr('id') + '::' + directory
|
||||
}
|
||||
|
||||
function storeScrollPosition(element) {
|
||||
if (!hasStorage) return;
|
||||
localStorage.setItem(scrollPositionId(element) + "::x", $(element).scrollLeft())
|
||||
localStorage.setItem(scrollPositionId(element) + "::y", $(element).scrollTop())
|
||||
}
|
||||
|
||||
function recallScrollPosition(element) {
|
||||
if (!hasStorage) return;
|
||||
$(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + "::x"))
|
||||
$(element).scrollTop(localStorage.getItem(scrollPositionId(element) + "::y"))
|
||||
}
|
||||
|
||||
function persistScrollPosition(element) {
|
||||
recallScrollPosition(element)
|
||||
$(element).scroll(function() { storeScrollPosition(element) })
|
||||
}
|
||||
|
||||
function sidebarContentWidth(element) {
|
||||
var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() })
|
||||
return Math.max.apply(Math, widths)
|
||||
}
|
||||
|
||||
function calculateSize(width, snap, margin, minimum) {
|
||||
if (width == 0) {
|
||||
return 0
|
||||
}
|
||||
else {
|
||||
return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2))
|
||||
}
|
||||
}
|
||||
|
||||
function resizeSidebars() {
|
||||
var primaryWidth = sidebarContentWidth('.primary')
|
||||
var secondaryWidth = 0
|
||||
|
||||
if ($('.secondary').length != 0) {
|
||||
secondaryWidth = sidebarContentWidth('.secondary')
|
||||
}
|
||||
|
||||
// snap to grid
|
||||
primaryWidth = calculateSize(primaryWidth, 32, 13, 160)
|
||||
secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160)
|
||||
|
||||
$('.primary').css('width', primaryWidth)
|
||||
$('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1)
|
||||
|
||||
if (secondaryWidth > 0) {
|
||||
$('#content').css('left', primaryWidth + secondaryWidth + 2)
|
||||
}
|
||||
else {
|
||||
$('#content').css('left', primaryWidth + 1)
|
||||
}
|
||||
}
|
||||
|
||||
$(window).ready(resizeSidebars)
|
||||
$(window).ready(setCurrentVarLink)
|
||||
$(window).ready(function() { persistScrollPosition('.primary')})
|
||||
$(window).ready(function() {
|
||||
$('#content').scroll(setCurrentVarLink)
|
||||
$(window).resize(setCurrentVarLink)
|
||||
})
|
108
documentation/scaling.html
Normal file
108
documentation/scaling.html
Normal file
File diff suppressed because one or more lines are too long
151
documentation/userspec.html
Normal file
151
documentation/userspec.html
Normal file
File diff suppressed because one or more lines are too long
4
documentation/youyesyet.authorisation.html
Normal file
4
documentation/youyesyet.authorisation.html
Normal file
File diff suppressed because one or more lines are too long
4
documentation/youyesyet.config.html
Normal file
4
documentation/youyesyet.config.html
Normal file
File diff suppressed because one or more lines are too long
270
documentation/youyesyet.db.core.html
Normal file
270
documentation/youyesyet.db.core.html
Normal file
File diff suppressed because one or more lines are too long
8
documentation/youyesyet.handler.html
Normal file
8
documentation/youyesyet.handler.html
Normal file
File diff suppressed because one or more lines are too long
12
documentation/youyesyet.layout.html
Normal file
12
documentation/youyesyet.layout.html
Normal file
File diff suppressed because one or more lines are too long
6
documentation/youyesyet.locality.html
Normal file
6
documentation/youyesyet.locality.html
Normal file
File diff suppressed because one or more lines are too long
5
documentation/youyesyet.middleware.html
Normal file
5
documentation/youyesyet.middleware.html
Normal file
File diff suppressed because one or more lines are too long
8
documentation/youyesyet.oauth.html
Normal file
8
documentation/youyesyet.oauth.html
Normal file
File diff suppressed because one or more lines are too long
12
documentation/youyesyet.outqueue.html
Normal file
12
documentation/youyesyet.outqueue.html
Normal file
File diff suppressed because one or more lines are too long
61
documentation/youyesyet.routes.auto-json.html
Normal file
61
documentation/youyesyet.routes.auto-json.html
Normal file
File diff suppressed because one or more lines are too long
5
documentation/youyesyet.routes.auto.html
Normal file
5
documentation/youyesyet.routes.auto.html
Normal file
File diff suppressed because one or more lines are too long
5
documentation/youyesyet.routes.home.html
Normal file
5
documentation/youyesyet.routes.home.html
Normal file
File diff suppressed because one or more lines are too long
8
documentation/youyesyet.routes.issue-experts.html
Normal file
8
documentation/youyesyet.routes.issue-experts.html
Normal file
File diff suppressed because one or more lines are too long
4
documentation/youyesyet.routes.manual.html
Normal file
4
documentation/youyesyet.routes.manual.html
Normal file
File diff suppressed because one or more lines are too long
6
documentation/youyesyet.routes.oauth.html
Normal file
6
documentation/youyesyet.routes.oauth.html
Normal file
File diff suppressed because one or more lines are too long
18
documentation/youyesyet.routes.rest.html
Normal file
18
documentation/youyesyet.routes.rest.html
Normal file
File diff suppressed because one or more lines are too long
6
documentation/youyesyet.routes.roles.html
Normal file
6
documentation/youyesyet.routes.roles.html
Normal file
File diff suppressed because one or more lines are too long
4
documentation/youyesyet.routes.services.html
Normal file
4
documentation/youyesyet.routes.services.html
Normal file
File diff suppressed because one or more lines are too long
3
documentation/youyesyet.utils.html
Normal file
3
documentation/youyesyet.utils.html
Normal file
File diff suppressed because one or more lines are too long
3
documentation/youyesyet.validation.html
Normal file
3
documentation/youyesyet.validation.html
Normal file
File diff suppressed because one or more lines are too long
BIN
dummies/building.png
Normal file
BIN
dummies/building.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
dummies/building.xcf
Normal file
BIN
dummies/building.xcf
Normal file
Binary file not shown.
BIN
dummies/followup.png
Normal file
BIN
dummies/followup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
dummies/followup.xcf
Normal file
BIN
dummies/followup.xcf
Normal file
Binary file not shown.
BIN
dummies/issue.png
Normal file
BIN
dummies/issue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
BIN
dummies/issue.xcf
Normal file
BIN
dummies/issue.xcf
Normal file
Binary file not shown.
BIN
dummies/issues.png
Normal file
BIN
dummies/issues.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
dummies/issues.xcf
Normal file
BIN
dummies/issues.xcf
Normal file
Binary file not shown.
97
project.clj
97
project.clj
|
@ -1,50 +1,58 @@
|
|||
(defproject youyesyet "0.2.0-SNAPSHOT"
|
||||
(defproject youyesyet "0.2.2"
|
||||
|
||||
:description "Canvassing tool for referenda"
|
||||
:license {:name "GNU General Public License,version 2.0 or (at your option) any later version"
|
||||
:url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"}
|
||||
:url "https://github.com/simon-brooke/youyesyet"
|
||||
|
||||
:dependencies [[adl-support "0.1.4-SNAPSHOT"]
|
||||
:dependencies [[adl-support "0.1.6"]
|
||||
[bouncer "1.0.1"]
|
||||
[ch.qos.logback/logback-classic "1.2.3"]
|
||||
[clj-oauth "1.5.5"]
|
||||
[cljsjs/react-leaflet "1.6.5-0"]
|
||||
[cljs-ajax "0.7.4"]
|
||||
;; [cljsjs/react-leaflet "2.0.1-0"] is available but doesn't seem to work fully
|
||||
[cljs-ajax "0.8.0"]
|
||||
[com.andrewmcveigh/cljs-time "0.5.2"]
|
||||
[clojure.java-time "0.3.2"]
|
||||
[com.cemerick/url "0.1.1"]
|
||||
[compojure "1.6.1"]
|
||||
[conman "0.8.2"]
|
||||
[cprop "0.1.11"]
|
||||
[conman "0.8.3"]
|
||||
[cprop "0.1.13"]
|
||||
[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.2"]
|
||||
[luminus-nrepl "0.1.4"]
|
||||
[luminus-migrations "0.5.2"]
|
||||
[luminus-immutant "0.2.4"]
|
||||
[markdown-clj "1.0.2"]
|
||||
[luminus-nrepl "0.1.6"]
|
||||
[luminus-migrations "0.6.5"]
|
||||
[luminus-immutant "0.2.5"]
|
||||
[markdown-clj "1.0.8"]
|
||||
[metosin/compojure-api "1.1.12"]
|
||||
[metosin/ring-http-response "0.9.0"]
|
||||
[migratus "1.0.8"]
|
||||
[mount "0.1.12"]
|
||||
[metosin/ring-http-response "0.9.1"]
|
||||
[migratus "1.2.3"]
|
||||
[mount "0.1.16"]
|
||||
[org.clojure/clojure "1.9.0"]
|
||||
[org.clojure/clojurescript "1.10.339" :scope "provided"]
|
||||
[org.clojure/clojurescript "1.10.520" :scope "provided"]
|
||||
[org.clojure/core.memoize "0.7.1"]
|
||||
;;[org.clojure/spec.alpha "0.2.168"]
|
||||
[org.clojure/tools.cli "0.3.7"]
|
||||
[org.clojure/tools.cli "0.4.2"]
|
||||
[org.clojure/tools.logging "0.4.1"]
|
||||
[org.postgresql/postgresql "42.2.4"]
|
||||
[org.webjars/bootstrap "4.1.2"]
|
||||
[org.webjars/font-awesome "5.1.0"]
|
||||
[org.postgresql/postgresql "42.2.5"]
|
||||
[org.webjars/bootstrap "4.3.1"]
|
||||
[org.webjars/font-awesome "5.8.1"]
|
||||
[org.webjars.bower/tether "1.4.4"]
|
||||
[re-frame "0.10.5"]
|
||||
[postgre-types "0.0.4"]
|
||||
[re-frame "0.10.6"]
|
||||
[reagent "0.8.1"]
|
||||
[reagent-utils "0.3.1"]
|
||||
[ring-middleware-format "0.7.2"]
|
||||
[reagent-utils "0.3.2"]
|
||||
[ring-middleware-format "0.7.4"]
|
||||
[ring/ring-defaults "0.3.2"]
|
||||
[ring/ring-servlet "1.6.3"]
|
||||
[ring/ring-servlet "1.7.1"]
|
||||
[ring-webjars "0.2.0"]
|
||||
[secretary "1.2.3"]
|
||||
[selmer "1.11.8"]]
|
||||
[selmer "1.12.12"]]
|
||||
|
||||
:deploy-repositories [["releases" :clojars]
|
||||
["snapshots" :clojars]]
|
||||
|
||||
:min-lein-version "2.0.0"
|
||||
|
||||
|
@ -56,23 +64,27 @@
|
|||
:main ^:skip-aot youyesyet.core
|
||||
:migratus {:store :database :db ~(get (System/getenv) "DATABASE_URL")}
|
||||
|
||||
:plugins [;;[lein-adl ["0.1.2"]]
|
||||
:plugins [[lein-adl "0.1.7"]
|
||||
[lein-cljsbuild "1.1.7"]
|
||||
[lein-codox "0.10.4"]
|
||||
[lein-codox "0.10.7-multilang"]
|
||||
[lein-cprop "1.0.3"]
|
||||
[lein-kibit "0.1.6"]
|
||||
[lein-less "1.7.5"]
|
||||
[lein-npm "0.6.2"]
|
||||
[lein-release "1.1.3"]
|
||||
[lein-release "1.0.5"]
|
||||
[lein-uberwar "0.2.0"]
|
||||
[migratus-lein "0.5.9"]
|
||||
[org.clojars.punkisdead/lein-cucumber "1.0.7"]]
|
||||
|
||||
:cucumber-feature-paths ["test/clj/features"]
|
||||
|
||||
:codox {:metadata {:doc "FIXME: write docs"}
|
||||
:codox {:metadata {:doc "**TODO**: write docs"
|
||||
:doc/format :markdown}
|
||||
:languages [:clojure :clojurescript]
|
||||
:source-paths ["src/clj" "src/cljc" "src/cljs"]}
|
||||
:source-paths ["src/clj" "src/cljc" "src/cljs"]
|
||||
:source-uri "https://github.com/simon-brooke/youyesyet/blob/master/{filepath}#L{line}"
|
||||
:output-path "docs"}
|
||||
|
||||
|
||||
:npm {:dependencies [[datatables.net "1.10.19"]
|
||||
[datatables.net-dt "1.10.19"]
|
||||
|
@ -83,15 +95,15 @@
|
|||
[simplemde "1.11.2"]]
|
||||
:root "resources/public/js/lib"}
|
||||
|
||||
;; `lein release` doesn't play nice with `git flow release`. Run `lein release` in the
|
||||
;; `develop` branch, then reset the `master` branch to the release tag.
|
||||
|
||||
:release-tasks [["vcs" "assert-committed"]
|
||||
["change" "version" "leiningen.release/bump-version" "release"]
|
||||
["adl"]
|
||||
["vcs" "commit"]
|
||||
;; ["vcs" "tag"] -- not working, problems with secret key
|
||||
["clean"]
|
||||
["npm" "install"]
|
||||
["uberjar"]
|
||||
[uberwar]
|
||||
["uberwar"]
|
||||
["docker" "build"]
|
||||
["docker" "push"]
|
||||
["change" "version" "leiningen.release/bump-version"]
|
||||
|
@ -112,9 +124,10 @@
|
|||
|
||||
|
||||
:profiles {:uberjar {:omit-source true
|
||||
:prep-tasks [;;"adl"
|
||||
"compile"
|
||||
["cljsbuild" "once" "min"]]
|
||||
:prep-tasks ["adl"
|
||||
"compile"
|
||||
["npm" "install"]
|
||||
["cljsbuild" "once" "min"]]
|
||||
:cljsbuild
|
||||
{:builds
|
||||
{:min
|
||||
|
@ -135,21 +148,21 @@
|
|||
|
||||
:test [:project/dev :project/test :profiles/test]
|
||||
|
||||
:project/dev {:dependencies [[prone "1.1.4"]
|
||||
[ring/ring-mock "0.3.2"]
|
||||
[ring/ring-devel "1.6.3"]
|
||||
:project/dev {:dependencies [[prone "1.6.3"]
|
||||
[ring/ring-mock "0.4.0"]
|
||||
[ring/ring-devel "1.7.1"]
|
||||
[org.webjars/webjars-locator-jboss-vfs "0.1.0"]
|
||||
[luminus-immutant "0.2.4"]
|
||||
[pjstadig/humane-test-output "0.8.3"]
|
||||
[luminus-immutant "0.2.5"]
|
||||
[pjstadig/humane-test-output "0.9.0"]
|
||||
[binaryage/devtools "0.9.10"]
|
||||
[com.cemerick/piggieback "0.2.2"]
|
||||
[directory-naming/naming-java "0.8"]
|
||||
[doo "0.1.10"]
|
||||
[figwheel-sidecar "0.5.16"]]
|
||||
[doo "0.1.11"]
|
||||
[figwheel-sidecar "0.5.18"]]
|
||||
:plugins [[com.jakemccrary/lein-test-refresh "0.23.0"]
|
||||
[lein-doo "0.1.10"]
|
||||
[lein-figwheel "0.5.16"]
|
||||
[org.clojure/clojurescript "1.9.495"]]
|
||||
[org.clojure/clojurescript "1.10.520"]]
|
||||
:cljsbuild {:builds
|
||||
{:app
|
||||
{:source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
|
||||
|
|
|
@ -45,7 +45,6 @@ h1 {
|
|||
width: 100%;
|
||||
_position: absolute;
|
||||
_top: expression(document.documentElement.scrollTop);
|
||||
z-index: 149;
|
||||
background:rgba(7,27,51,0.8);
|
||||
}
|
||||
|
||||
|
@ -57,6 +56,7 @@ h1 {
|
|||
#nav-menu {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
z-index: 02110-1301;
|
||||
}
|
||||
|
||||
#nav menu li {
|
||||
|
@ -103,6 +103,7 @@ h1 {
|
|||
#nav:hover #nav-menu {
|
||||
display: block;
|
||||
list-style-type: none;
|
||||
z-index: 148;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
@ -141,7 +142,7 @@ h1 {
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
position: fixed;
|
||||
z-index: 149;
|
||||
z-index: 600;
|
||||
color: silver;
|
||||
background:rgba(40,40,40,0.9);
|
||||
}
|
||||
|
@ -149,6 +150,7 @@ h1 {
|
|||
#nav:hover #nav-menu {
|
||||
display: block;
|
||||
list-style-type: none;
|
||||
z-index: 500;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ th {
|
|||
width: 30%;
|
||||
float: right;
|
||||
position: fixed;
|
||||
bottom: 3.5em;
|
||||
bottom: 2em;
|
||||
right: 0;
|
||||
z-index: 175;
|
||||
background: transparent;
|
||||
|
@ -362,7 +362,6 @@ th {
|
|||
|
||||
/* content of the current page in the Wiki - editable, provided by users. Within main-container */
|
||||
#content {
|
||||
border: thin solid silver;
|
||||
width: 80%;
|
||||
float: right;
|
||||
padding-bottom: 5em;
|
||||
|
@ -396,11 +395,14 @@ th {
|
|||
|
||||
/* content of the current in the Wiki - editable, provided by users. Within main-container */
|
||||
#content {
|
||||
border: thin solid silver;
|
||||
width: 100%;
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
|
||||
#issue-text {
|
||||
font-size: 200%;
|
||||
}
|
||||
|
||||
#main-container {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
|
60
resources/public/error/502.html
Normal file
60
resources/public/error/502.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- a page which can be served as static (by nginx) if Tomcat has crashed -->
|
||||
<!-- head: if you want entire custom head content, override this block. -->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<meta name="referrer" content="same-origin">
|
||||
<link href="../css/yyy-common.css" rel="stylesheet" type="text/css" />
|
||||
<link href="../css/yyy-site.css" rel="stylesheet" type="text/css" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Archivo+Black|Archivo+Narrow" rel="stylesheet"/>
|
||||
<title>Project Hope: 502 Bad Gateway</title>
|
||||
|
||||
|
||||
<!-- extra-head: put any additional markup to go into the head of your document into this block -->
|
||||
<!-- e.g. script tags, link tags -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- whole-page: if you want an entire custom page layout, override this block. -->
|
||||
|
||||
<header>
|
||||
<h1>Sorry, we have a problem</h1>
|
||||
</header>
|
||||
|
||||
<div id="main-container" class="container">
|
||||
<h2><span class="text-danger">Error: 502 Bad Gateway</span></h2>
|
||||
<p>
|
||||
We are suffering an intermittent problem causing an occasional crash of
|
||||
the Project Hope canvassing application. We apologise for this, and are
|
||||
working on a permanent fix.
|
||||
</p>
|
||||
<p>
|
||||
The application will restart automatically
|
||||
within five minutes, please take a short break.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<br clear="both"/>
|
||||
</div>
|
||||
|
||||
<!-- foot: override this block if you don't want the standard footer -->
|
||||
<footer>
|
||||
<div id="credits">
|
||||
<div>
|
||||
<img height="16" width="16" alt="Clojure" src="/img/credits/luminus-logo.png"/>Built with <a href="http://www.luminusweb.net/">LuminusWeb</a> ||
|
||||
<img height="16" width="16" alt="Clojure" src="/img/credits/clojure-icon.gif"/> Powered by <a href="http://clojure.org">Clojure</a> ||
|
||||
<img height="16" width="16" alt="GitHub" src="/img/credits/github-logo-transparent.png"/>Find me/fork me on <a href="https://github.com/simon-brooke/youyesyet">Github</a> ||
|
||||
<img height="16" width="16" alt="Free Software Foundation" src="/img/credits/gnu.small.png"/>Licensed under the <a href="http://www.gnu.org/licenses/gpl-2.0.html">GNU General Public License version 2.0</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ SELECT DISTINCT request.*,
|
|||
addresses.address ||', '|| addresses.postcode ||', '|| visits.date AS visit_id_expanded,
|
||||
request.issue_id as issue_id_expanded,
|
||||
request.method_id AS method_id_expanded,
|
||||
visits.date
|
||||
visits.date AS raised
|
||||
FROM followuprequests as request,
|
||||
ln_experts_issues_canvassers as expertise,
|
||||
canvassers as experts,
|
||||
|
@ -53,12 +53,13 @@ FROM followuprequests as request,
|
|||
where not exists (select * from followupactions as action
|
||||
where action.request_id = request.id
|
||||
and action.closed = true)
|
||||
and request.locked_by is null
|
||||
and request.elector_id = electors.id
|
||||
and request.visit_id = visits.id
|
||||
and visits.address_id = addresses.id
|
||||
and request.issue_id = expertise.issue_id
|
||||
and expertise.canvasser_id = :expert
|
||||
ORDER BY visits.date desc
|
||||
ORDER BY raised
|
||||
|
||||
--:name get-last-visit-by-canvasser :? :1
|
||||
--:doc returns the most recent visit record of the canvasser with the specified `:id`
|
||||
|
@ -67,13 +68,20 @@ WHERE canvasser_id = :id
|
|||
ORDER BY date desc
|
||||
LIMIT 1
|
||||
|
||||
-- I don't know why this next one isn't autogenerating, but it isn't and it's critical.
|
||||
--:name get-locality-for-visit :? :1
|
||||
--:doc returns the locality of the address of this visit
|
||||
SELECT addresses.locality
|
||||
FROM addresses, visits
|
||||
WHERE visits.address_id = addresses.id
|
||||
AND visits.id = :id
|
||||
|
||||
-- :name list-roles-by-canvasser :? :*
|
||||
-- :doc links all existing canvasser records related to a given role
|
||||
SELECT roles.*
|
||||
FROM roles, ln_canvassers_roles
|
||||
WHERE roles.id = ln_canvassers_roles.role_id
|
||||
AND ln_canvassers_roles.canvasser_id = :id
|
||||
ORDER BY roles.name,
|
||||
roles.id
|
||||
|
||||
-- :name list-elector-intentions :? :*
|
||||
-- :doc short form of `list-intentions-by-elector`, returning far less data, for use in `youyesyet.routes.rest/get-local-data`, q.v.
|
||||
-- TODO: should be limited to visits in the past 24 hours, to prevent the app being
|
||||
-- used to harrass NO voters. See https://github.com/simon-brooke/youyesyet/issues/58
|
||||
SELECT intentions.id, intentions.option_id, visits.date
|
||||
FROM intentions, visits
|
||||
WHERE intentions.visit_id = visits.id
|
||||
AND intentions.elector_id = :id
|
||||
ORDER BY visits.date DESC
|
||||
|
|
53
resources/sql/youyesyet.postgres.overrides.sql
Normal file
53
resources/sql/youyesyet.postgres.overrides.sql
Normal file
|
@ -0,0 +1,53 @@
|
|||
------------------------------------------------------------------------
|
||||
-- User `youyesyet` (the app, and less secure parts of the site)
|
||||
-- must have the permissions of `canvassers`.
|
||||
------------------------------------------------------------------------
|
||||
DO
|
||||
$do$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT -- SELECT list can stay empty for this
|
||||
FROM pg_catalog.pg_roles
|
||||
WHERE rolname = 'youyesyet') THEN
|
||||
|
||||
CREATE ROLE youyesyet LOGIN PASSWORD 'thisisnotsecure';
|
||||
END IF;
|
||||
END
|
||||
$do$;
|
||||
|
||||
grant canvassers to youyesyet;
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- convenience view lv_followupactions of entity followupactions for
|
||||
-- lists, et cetera
|
||||
-- ADL is not yet correctly chaining tables when generating convenience
|
||||
-- views, so the auto-generated convenience view is a horrible
|
||||
-- cross-product join
|
||||
------------------------------------------------------------------------
|
||||
DROP VIEW lv_followupactions;
|
||||
CREATE VIEW lv_followupactions AS
|
||||
SELECT electors.name ||', '|| addresses.address ||', '|| addresses.postcode ||', '|| visits.date ||', '|| issues.id AS request_id_expanded,
|
||||
followupactions.request_id,
|
||||
canvassers.username ||', '|| canvassers.fullname ||', '|| addresses.address ||', '|| addresses.postcode ||', '|| canvassers.phone ||', '|| canvassers.email AS actor_expanded,
|
||||
followupactions.actor,
|
||||
canvassers.fullname AS actor_name,
|
||||
followupactions.date,
|
||||
followupactions.notes,
|
||||
followupactions.closed,
|
||||
followupactions.id
|
||||
FROM followuprequests, visits, canvassers, addresses, followupactions, issues, electors
|
||||
WHERE followupactions.request_id = followuprequests.id
|
||||
AND followuprequests.elector_id = electors.id
|
||||
AND followuprequests.visit_id = visits.id
|
||||
AND followuprequests.issue_id = issues.id
|
||||
AND visits.address_id = addresses.id
|
||||
AND followupactions.actor = canvassers.id
|
||||
;
|
||||
GRANT SELECT ON lv_followupactions TO canvassers, issueexperts;
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- request locking
|
||||
------------------------------------------------------------------------
|
||||
ALTER TABLE followuprequests ADD COLUMN locked_by INTEGER REFERENCES canvassers(id) ON DELETE SET NULL;
|
||||
ALTER TABLE followuprequests ADD COLUMN locked TIMESTAMP;
|
|
@ -5,6 +5,7 @@
|
|||
<!-- head: if you want entire custom head content, override this block. -->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<meta name="referrer" content="same-origin">
|
||||
{% style "/css/yyy-common.css" %}
|
||||
{% style "/css/yyy-site.css" %}
|
||||
{% style "/css/spinner.css" %}
|
||||
|
@ -26,10 +27,14 @@
|
|||
<img id="nav-icon" src="{{servlet-context}}/img/threelines.png" alt="Menu"/>
|
||||
<menu id="nav-menu" class="nav">
|
||||
<li class=""><a href="{{servlet-context}}/home">Home</a></li>
|
||||
<li class=""><a href="{{servlet-context}}/library">Library</a></li>
|
||||
<li class=""><a href="https://library.projecthope.scot/">Library</a></li>
|
||||
{% if user %}
|
||||
<li class=""><a href="{{servlet-context}}/roles">Roles</a></li>
|
||||
<li class=""><a href="{{servlet-context}}/logout">Logout</a></li>
|
||||
{% else %}
|
||||
<li class=""><a href="{{servlet-context}}/register">Register</a></li>
|
||||
<li class="">{% if user %}<a href="{{servlet-context}}/logout">Logout</a>
|
||||
{% else %}<a href="{{servlet-context}}/login">Login</a>{% endif %}</li>
|
||||
<li class=""><a href="{{servlet-context}}/login">Login</a></li>
|
||||
{% endif %}
|
||||
<li class=""><a href="{{servlet-context}}/about">About</a></li>
|
||||
{% if user %}
|
||||
<li id="user"><a href="{{servlet-context}}/profile">Logged in as {{user.username}}</a></li>
|
||||
|
@ -63,18 +68,31 @@
|
|||
<!-- content: put your main page content into this block -->
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div id="cookies">
|
||||
<div id="more-about-cookies">
|
||||
This website stores session information as a 'cookie' on your browser.
|
||||
This helps us show you the content you want to see. This cookie does
|
||||
not identify you, and cannot be read by other websites. It is deleted
|
||||
by your browser as soon as you leave this site. This website does not
|
||||
use any third party cookies, so your visit here cannot be tracked by
|
||||
other websites.
|
||||
</div>
|
||||
<div id="about-cookies">
|
||||
About cookies
|
||||
</div>
|
||||
</div>
|
||||
<br clear="both"/>
|
||||
</div>
|
||||
{% block foot %}
|
||||
<!-- foot: override this block if you don't want the standard footer -->
|
||||
<footer>
|
||||
<div id="credits">
|
||||
<div>
|
||||
<!-- div>
|
||||
<img src="{{servlet-context}}/img/credits/ric-logo.png" width="24" height="24"/>
|
||||
A project of the
|
||||
<a href="https://radical.scot/">Radical Independence Campaign</a> ||
|
||||
Version {{version}}
|
||||
</div>
|
||||
</div -->
|
||||
<div>
|
||||
<img height="16" width="16" alt="Clojure" src="{{servlet-context}}/img/credits/luminus-logo.png"/>Built with <a href="http://www.luminusweb.net/">LuminusWeb</a> ||
|
||||
<img height="16" width="16" alt="Clojure" src="{{servlet-context}}/img/credits/clojure-icon.gif"/> Powered by <a href="http://clojure.org">Clojure</a> ||
|
||||
|
|
|
@ -2,23 +2,12 @@
|
|||
{% block big-links %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="col-lg-12">
|
||||
<div class="centering text-center">
|
||||
<div class="text-center">
|
||||
<h1><span class="text-danger">Error: {{status}}</span></h1>
|
||||
<hr>
|
||||
{% if title %}
|
||||
<h2 class="without-margin">{{title}}</h2>
|
||||
{% endif %}
|
||||
{% if message %}
|
||||
<h4 class="text-danger">{{message}}</h4>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if status %}
|
||||
<h2>Error: {{status}}</h2>
|
||||
{% endif %}
|
||||
<hr>
|
||||
{% if error %}
|
||||
<p>{{error}}</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block extra-head %}
|
||||
<meta http-equiv="refresh" content="60">
|
||||
{% endblock %}
|
||||
|
||||
{% block back-links %}
|
||||
<div>
|
||||
<div class='back-link-container'>
|
||||
|
@ -36,19 +40,16 @@ Add a new Followuprequest
|
|||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Id
|
||||
Elector
|
||||
</th>
|
||||
<th>
|
||||
Elector_id
|
||||
Raised
|
||||
</th>
|
||||
<th>
|
||||
Visit_id
|
||||
Issue
|
||||
</th>
|
||||
<th>
|
||||
Issue_id
|
||||
</th>
|
||||
<th>
|
||||
Method_id
|
||||
Method
|
||||
</th>
|
||||
<th>
|
||||
|
||||
|
@ -56,13 +57,10 @@ Method_id
|
|||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<input id='id' type='text' name='id' value='{{ params.id }}'/>
|
||||
</th>
|
||||
<th>
|
||||
<input id='elector_id' type='text' name='elector_id' value='{{ params.elector_id }}'/>
|
||||
</th>
|
||||
<th>
|
||||
<input id='visit_id' type='text' name='visit_id' value='{{ params.visit_id }}'/>
|
||||
<input id='raised' type='text' name='raised' value='{{ params.raised }}'/>
|
||||
</th>
|
||||
<th>
|
||||
<input id='issue_id' type='text' name='issue_id' value='{{ params.issue_id }}'/>
|
||||
|
@ -79,22 +77,21 @@ Method_id
|
|||
{% for record in records %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ record.id }}
|
||||
</td>
|
||||
<td>
|
||||
<a href='{{servlet-context}}/form-electors-Elector?id={{ record.elector_id }}'>
|
||||
{{ record.elector_id_expanded }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href='{{servlet-context}}/form-visits-Visit?id={{ record.visit_id }}'>
|
||||
{{ record.visit_id_expanded }}
|
||||
</a>
|
||||
{{ record.raised }}
|
||||
</td>
|
||||
<td>
|
||||
<a href='{{servlet-context}}/form-issues-Issue?id={{ record.issue_id }}'>
|
||||
{{ record.issue_id_expanded }}
|
||||
</a>
|
||||
{% ifequal record.issue_id "Other" %}
|
||||
{{ record.issue_detail }}
|
||||
{% else %}
|
||||
<a href='{{servlet-context}}/form-issues-Issue?id={{ record.issue_id }}'>
|
||||
{{ record.issue_id }}
|
||||
</a>
|
||||
{% endifequal %}
|
||||
</td>
|
||||
<td>
|
||||
<a href='{{servlet-context}}/form-followupmethods-Followupmethod?id={{ record.method_id }}'>
|
||||
|
|
|
@ -13,16 +13,19 @@
|
|||
<form action='{{servlet-context}}/issue-expert/followup-action' method='POST'>
|
||||
{% csrf-field %}
|
||||
<input id='id' name='id' type='hidden' value='{{record.id}}'/>
|
||||
<input id='request_id' name='request_id' type='hidden' value='{{record.id}}'/>
|
||||
<input id='elector_id' name='elector_id' type='hidden' value='{{record.elector_id}}'/>
|
||||
<input id='visit_id' name='visit_id' type='hidden' value='{{record.visit_id}}'/>
|
||||
<p class='widget'>
|
||||
<label for='elector_id'>
|
||||
Elector
|
||||
</label>
|
||||
{% ifmemberof canvassers teamorganisers issueexperts analysts issueeditors admin %}
|
||||
<span id='elector_id' name='elector_id' class='pseudo-widget disabled'>
|
||||
<span id='elector' name='elector' class='pseudo-widget disabled'>
|
||||
{{elector.name}} ({{elector.gender}})
|
||||
</span>
|
||||
{% else %}
|
||||
<span id='elector_id' name='elector_id' class='pseudo-widget not-authorised'>
|
||||
<span id='elector' name='elector' class='pseudo-widget not-authorised'>
|
||||
You are not permitted to view elector of followuprequests
|
||||
</span>
|
||||
{% endifmemberof %}
|
||||
|
@ -33,7 +36,7 @@
|
|||
</label>
|
||||
{% ifmemberof issueexperts analysts issueeditors admin %}
|
||||
<span id='visit' name='visit' class='pseudo-widget disabled'>
|
||||
by {{visit.canvasser_id_expanded}} at {{visit.date}}
|
||||
by {{visit.canvasser_id_expanded}} on {{visit.date}}
|
||||
</span>
|
||||
{% else %}
|
||||
<span id='visit_id' name='visit_id' class='pseudo-widget not-authorised'>
|
||||
|
@ -43,8 +46,17 @@
|
|||
</p>
|
||||
<p class='widget'>
|
||||
<label for='issue_id'>
|
||||
{{issue.id}}
|
||||
Issue
|
||||
</label>
|
||||
{% ifmemberof issueexperts analysts issueeditors admin %}
|
||||
<span id='issue_id' name='issue_id' class='pseudo-widget disabled'>
|
||||
{{issue.id}} <em>{{record.issue_detail}}</em>
|
||||
</span>
|
||||
{% else %}
|
||||
<span id='issue_id' name='issue_id' class='pseudo-widget not-authorised'>
|
||||
You are not permitted to view issue of followuprequests
|
||||
</span>
|
||||
{% endifmemberof %}
|
||||
{% ifmemberof issueexperts admin %}
|
||||
<div id="issue-brief">
|
||||
{{issue.brief|safe}}
|
||||
|
@ -92,7 +104,7 @@
|
|||
<tbody>
|
||||
{% for action in actions %}
|
||||
<tr>
|
||||
<td>{{action.actor}}</td>
|
||||
<td><a href="{{servlet-context}}/form-canvassers-Canvasser?id={{action.actor}}">{{action.actor_name}}</a></td>
|
||||
<td>{{action.date}}</td>
|
||||
<td>{{action.closed}}</td>
|
||||
</tr>
|
||||
|
@ -104,13 +116,13 @@
|
|||
</table>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if not closed %}
|
||||
<p class='widget'>
|
||||
<label for='notes'>
|
||||
Your notes
|
||||
</label>
|
||||
{% ifmemberof admin issueexperts %}
|
||||
<textarea rows='8' cols='60' id='notes' name='notes'>
|
||||
</textarea>
|
||||
<textarea rows='8' cols='60' id='notes' name='notes'></textarea>
|
||||
{% endifmemberof %}
|
||||
</p>
|
||||
<p class='widget'>
|
||||
|
@ -121,7 +133,21 @@
|
|||
<input id='closed' name='closed' type='checkbox' maxlength='' size='16'/>
|
||||
{% endifmemberof %}
|
||||
</p>
|
||||
|
||||
<p class='widget'>
|
||||
<label for='intention'>
|
||||
What is the elector's voting intention now?
|
||||
</label>
|
||||
{% ifmemberof admin issueexperts %}
|
||||
<select id='option_id' name='option_id'>
|
||||
<option value="">Not stated</option>
|
||||
{% for option in options %}
|
||||
<img src="{{servlet-context}}/img/option/{{option.id}}-{% ifequal record.option_id option.id %}selected{% else %}unselected{% endifequal %}.png" alt="{{option.id}}"/>
|
||||
<option value='{{option.id}}' {% ifequal record.option_id option.id%}selected='selected'{% endifequal %} style="background-image: url('{{servlet-context}}/img/option/{{option.id}}-{% ifequal record.option_id option.id %}selected{% else %}unselected{% endifequal %}.png')">
|
||||
{{option.id}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endifmemberof %}
|
||||
</p>
|
||||
{% ifmemberof admin issueexperts %}
|
||||
<p class='widget action-safe'>
|
||||
<label for='save-button' class='action-safe'>
|
||||
|
@ -130,6 +156,7 @@
|
|||
<input id='save-button' name='save-button' class='action-safe' type='submit' value='Save!'/>
|
||||
</p>
|
||||
{% endifmemberof %}
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue