Release 0.6.0
- improved web interface - removed .htaccess from PHP version - better documentation -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEKHuXKkUYdvdO9493DXkdyNc3wdkFAl1FRqMACgkQDXkdyNc3 wdk67AgA5G+Uv776xleDsV+VdWb7wGYoM6NSICzVgca3HBUxSBqeRfGq7pSrWLnv QMOuG/p4X1rt0pjJe7e2I2aSeU6SDOoyiY3dZm193MknwgGLihHDj5SwHBdGlUCZ MARtnyNNt91YJbaP7UOfCOSjzWBjInBbwbN+zgxiRo1UBnprqrLzjKo77WOpcPJF KgOw+nrTJs/ON9/RRDMOXpzwuPSrQXNwdTVToEf3BWoD/GqbLGlkZ5GOzGha5BkY zuG8YkR7Sk/0ixitNm+lPB5gwagEx2TBtOZbpzDxZpV+IcdI5Tp7c/1QncbyTpt2 X9SBdsi3XnXfdixxHwdTvThTX5tblw== =tF0N -----END PGP SIGNATURE----- Merge tag '0.6.0' into debian Release 0.6.0 - improved web interface - removed .htaccess from PHP version - better documentation * tag '0.6.0': Refine HTML layout Add icon images Improve documentation Remove .htaccess from PHP age
This commit is contained in:
commit
f688e42178
17 changed files with 392 additions and 375 deletions
33
.htaccess
33
.htaccess
|
@ -1,33 +0,0 @@
|
|||
<IfModule mod_php5.c>
|
||||
php_flag display_errors Off
|
||||
php_flag log_errors On
|
||||
php_value error_log syslog
|
||||
|
||||
php_flag safe_mode On
|
||||
php_flag safe_mode_gid On
|
||||
php_value open_basedir /var/www/board
|
||||
php_value safe_mode_exec_dir /var/empty
|
||||
</IfModule>
|
||||
|
||||
<FilesMatch "^(database.*|remind.php|closevotes.php.*)$">
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</FilesMatch>
|
||||
|
||||
|
||||
|
||||
|
||||
<FilesMatch "^(motions?|vote|proxy)\.php$">
|
||||
# these files require authentication
|
||||
<IfModule mod_ssl.c>
|
||||
SSLOptions +OptRenegotiate +StdEnvVars +ExportCertData
|
||||
SSLUserName SSL_CLIENT_S_DN_Email
|
||||
SSLVerifyClient require
|
||||
# <IfModule mod_rewrite.c>
|
||||
# RewriteEngine on
|
||||
# RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS
|
||||
# RewriteRule .? - [F]
|
||||
# ErrorDocument 403 "You need a client side certificate issued by CAcert to access this url"
|
||||
# </IfModule>
|
||||
</IfModule>
|
||||
</FilesMatch>
|
|
@ -71,7 +71,7 @@ use `openssl` to create a self signed server certificate and retrieve the CAcert
|
|||
|
||||
```shell script
|
||||
openssl req -new -newkey rsa:2048 -keyout server.key -x509 -out server.crt -subj '/CN=localhost'
|
||||
curl -O cacert_class3.pem http://www.cacert.org/certs/class3_X0E.crt
|
||||
curl -o cacert_class3.pem http://www.cacert.org/certs/class3_X0E.crt
|
||||
```
|
||||
|
||||
It is advisable to have a local mail setup that intercepts outgoing email or to use email addresses that you control.
|
||||
|
@ -91,8 +91,7 @@ Parameter | Description | How to get a valid value
|
|||
`csrf_key` | A base64 encoded random byte value of at least 32 bytes used to encrypt [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention) tokens | see [Generating random byte values](#generating-random-byte-values) below
|
||||
`base_url` | The base URL of your application instance (production value is https://motions.cacert.org) | use https://localhost:8443
|
||||
`mail_server`.`host` | Mail server host (production value is `localhost`) | `localhost`
|
||||
`mail_server`.`port` | Mail server TCP port (production value is `25` | see [how to setup a debugging SMTP server](#debugging-smtp-server) below and choose the port of that
|
||||
|
||||
`mail_server`.`port` | Mail server TCP port (production value is `25` | see [how to setup a debugging SMTP server](#debugging-smtp-server) below and choose the port of that (default `8025`)
|
||||
### Generating random byte values
|
||||
|
||||
```shell script
|
||||
|
|
|
@ -219,7 +219,9 @@ func motionListHandler(w http.ResponseWriter, r *http.Request) {
|
|||
templateContext.PrevPage = params.Page - 1
|
||||
}
|
||||
|
||||
renderTemplate(w, r, []string{"motions.html", "motion_fragments.html", "header.html", "footer.html"}, templateContext)
|
||||
renderTemplate(w, r, []string{
|
||||
"motions.html", "motion_fragments.html", "page_fragments.html", "header.html", "footer.html",
|
||||
}, templateContext)
|
||||
}
|
||||
|
||||
func motionHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -252,7 +254,7 @@ func motionHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
templateContext.Decision = decision
|
||||
templateContext.PageTitle = fmt.Sprintf("Motion %s: %s", decision.Tag, decision.Title)
|
||||
renderTemplate(w, r, []string{"motion.html", "motion_fragments.html", "header.html", "footer.html"}, templateContext)
|
||||
renderTemplate(w, r, []string{"motion.html", "motion_fragments.html", "page_fragments.html", "header.html", "footer.html"}, templateContext)
|
||||
}
|
||||
|
||||
func singleDecisionHandler(w http.ResponseWriter, r *http.Request, tag string, handler func(http.ResponseWriter, *http.Request)) {
|
||||
|
@ -326,7 +328,7 @@ func (a *withDrawMotionAction) Handle(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed)
|
||||
return
|
||||
}
|
||||
templates := []string{"withdraw_motion_form.html", "header.html", "footer.html", "motion_fragments.html"}
|
||||
templates := []string{"withdraw_motion_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"}
|
||||
var templateContext struct {
|
||||
PageTitle string
|
||||
Decision *DecisionForDisplay
|
||||
|
@ -366,7 +368,7 @@ func (h *newMotionHandler) Handle(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed)
|
||||
}
|
||||
|
||||
templates := []string{"create_motion_form.html", "header.html", "footer.html"}
|
||||
templates := []string{"create_motion_form.html", "page_fragments.html", "header.html", "footer.html"}
|
||||
var templateContext struct {
|
||||
Form NewDecisionForm
|
||||
PageTitle string
|
||||
|
@ -428,7 +430,7 @@ func (a editMotionAction) Handle(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed)
|
||||
return
|
||||
}
|
||||
templates := []string{"edit_motion_form.html", "header.html", "footer.html"}
|
||||
templates := []string{"edit_motion_form.html", "page_fragments.html", "header.html", "footer.html"}
|
||||
var templateContext struct {
|
||||
Form EditDecisionForm
|
||||
PageTitle string
|
||||
|
@ -560,7 +562,7 @@ func (h *directVoteHandler) Handle(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
http.Redirect(w, r, "/motions/", http.StatusMovedPermanently)
|
||||
default:
|
||||
templates := []string{"direct_vote_form.html", "header.html", "footer.html", "motion_fragments.html"}
|
||||
templates := []string{"direct_vote_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"}
|
||||
var templateContext struct {
|
||||
Decision *DecisionForDisplay
|
||||
VoteChoice VoteChoice
|
||||
|
@ -601,7 +603,7 @@ func (h *proxyVoteHandler) Handle(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
templates := []string{"proxy_vote_form.html", "header.html", "footer.html", "motion_fragments.html"}
|
||||
templates := []string{"proxy_vote_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"}
|
||||
var templateContext struct {
|
||||
Form ProxyVoteForm
|
||||
Decision *DecisionForDisplay
|
||||
|
|
46
boardvoting/static/images/CAcert-logo-colour.svg
Normal file
46
boardvoting/static/images/CAcert-logo-colour.svg
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
width="510"
|
||||
height="116.25"
|
||||
id="svg3020"
|
||||
xml:space="preserve"><metadata
|
||||
id="metadata3026"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs3024" /><g
|
||||
transform="matrix(1.25,0,0,-1.25,0,116.25)"
|
||||
id="g3028"><g
|
||||
transform="scale(0.1,0.1)"
|
||||
id="g3030"><path
|
||||
d="m 2031.75,34.9688 c -56.31,0 -107.84,6.4062 -154.59,19.2812 -46.35,12.8438 -86.77,32.6562 -121.25,59.469 -34.1,26.781 -60.53,60.531 -79.3,101.312 -18.77,40.75 -28.16,88.469 -28.16,143.125 0,57.656 9.96,107.375 29.88,149.219 20.29,41.844 48.47,76.531 84.48,104.063 34.86,26.062 75.08,45.156 120.67,57.25 45.6,12.124 92.91,18.187 141.94,18.187 44.06,0 84.67,-4.594 121.85,-13.781 37.15,-9.156 71.82,-21.094 104,-35.782 l 0,-169.031 -29.3,0 c -8.05,6.594 -17.83,14.281 -29.31,23.094 -11.11,8.844 -24.91,17.469 -41.38,25.937 -15.7,8.032 -32.95,14.688 -51.72,19.782 -18.78,5.531 -40.61,8.25 -65.51,8.25 -55.17,0 -97.69,-16.875 -127.58,-50.625 -29.49,-33.438 -44.25,-78.907 -44.25,-136.563 0,-59.468 15.12,-104.625 45.4,-135.406 30.66,-30.875 73.94,-46.281 129.88,-46.281 26.05,0 49.42,2.781 70.11,8.25 21.06,5.875 38.5,12.687 52.3,20.375 13.01,7.344 24.51,15.062 34.47,23.125 9.96,8.093 19.15,15.969 27.59,23.687 l 29.3,0 0,-169.031 C 2218.72,68.1875 2184.61,56.6562 2148.98,48.1875 2113.73,39.375 2074.66,34.9688 2031.75,34.9688"
|
||||
id="path3032"
|
||||
style="fill:#11568c;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 2980.95,330.895 -458.79,0 c 2.97,-50.008 21.54,-88.27 55.68,-114.79 34.52,-26.519 85.19,-39.777 152,-39.777 42.32,0 83.33,7.766 123.05,23.297 39.72,15.535 71.08,32.203 94.09,50.008 l 22.27,0 0,-164.2268 c -45.28,-18.5624 -87.96,-32.0117 -128.05,-40.3476 -40.09,-8.332 -84.45,-12.5 -133.07,-12.5 -125.46,0 -221.6,28.7891 -288.41,86.3754 -66.81,57.582 -100.22,139.601 -100.22,246.058 0,105.317 31.55,188.664 94.65,250.035 63.47,61.75 150.33,92.625 260.57,92.629 101.71,-0.004 178.17,-26.332 229.39,-78.992 51.22,-52.277 76.84,-127.668 76.84,-226.168 l 0,-71.601 m -199.33,119.906 c -1.11,42.808 -11.51,75.008 -31.18,96.601 -19.67,21.594 -50.3,32.391 -91.87,32.395 -38.6,-0.004 -70.34,-10.231 -95.2,-30.688 -24.87,-20.457 -38.79,-53.23 -41.76,-98.308 l 260.01,0"
|
||||
id="path3034"
|
||||
style="fill:#11568c;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 3514.54,477.766 -18.23,0 c -8.74,2.953 -22.79,5.172 -42.17,6.656 -19.38,1.484 -35.53,2.234 -48.44,2.234 -29.26,0 -55.09,-1.859 -77.5,-5.562 -22.42,-3.703 -46.55,-10 -72.39,-18.891 l 0,-417.5155 -205.16,0 0,623.5005 205.16,0 0,-91.594 c 45.21,37.75 84.54,62.734 117.98,74.937 33.42,12.594 64.2,18.875 92.31,18.875 7.22,0 15.39,-0.172 24.51,-0.547 9.12,-0.375 17.1,-0.921 23.93,-1.671 l 0,-190.422"
|
||||
id="path3036"
|
||||
style="fill:#11568c;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 3874.46,836.262 -207.5,-80.5 0,-94.75 -85.75,0 0,-133.5 85.75,0 0,-287 c 0,-75.071 19.63,-128.028 59,-159.0003 39.74,-30.9805 99.97,-46.5 181,-46.5 36.27,0 67.16,1.7188 92.25,5 25.08,2.9141 48.61,7.0313 71,12.5 l 0,135.0003 -17.25,0 c -6.95,-3.645 -19.25,-7.633 -37,-12 -17.37,-4.375 -31.45,-6.504 -42.25,-6.5 -26.24,-0.008 -46.36,3.461 -60.25,10.75 -13.51,7.652 -23.1,17.988 -28.5,30.75 -5.79,12.754 -8.87,27.211 -9.25,43.25 -0.39,16.035 -0.5,34.746 -0.5,56.25 l 0,217.5 195,0 0,133.5 -195,0 0,175.25 -0.75,0"
|
||||
id="path3038"
|
||||
style="fill:#11568c;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 439.125,20.2734 c -62.25,0 -119.813,9.1875 -172.687,27.5625 -52.5,18.375 -97.688,45.75 -135.563,82.1251 C 93,166.336 63.5625,211.711 42.5625,266.086 21.9375,320.461 11.625,383.273 11.625,454.523 c 0,66.375 9.9375,126.563 29.8125,180.563 19.875,53.996 48.75,100.309 86.6245,138.937 36.376,37.122 81.376,65.809 135,86.063 54,20.246 112.876,30.371 176.626,30.375 35.25,-0.004 66.933,-2.066 95.062,-6.188 28.496,-3.753 54.746,-8.816 78.75,-15.187 25.121,-7.129 47.809,-15.191 68.062,-24.188 20.622,-8.628 38.622,-16.691 54,-24.187 l 0,-203.063 -24.75,0 c -10.503,9 -23.816,19.684 -39.937,32.063 -15.754,12.371 -33.754,24.559 -54,36.562 -20.629,11.997 -42.941,22.122 -66.937,30.375 -24.004,8.247 -49.688,12.372 -77.063,12.375 -30.375,-0.003 -59.25,-4.878 -86.625,-14.625 -27.375,-9.378 -52.688,-25.128 -75.938,-47.25 -22.124,-21.378 -40.124,-49.687 -54,-84.937 -13.5,-35.25 -20.25,-78 -20.25,-128.25 0,-52.5 7.313,-96.375 21.938,-131.625 15,-35.25 33.75,-63 56.25,-83.25 22.875,-20.625 48.375,-35.438 76.5,-44.438 28.125,-8.625 55.875,-12.937 83.25,-12.937 26.25,0 52.121,3.937 77.625,11.812 25.871,7.875 49.684,18.563 71.437,32.063 18.372,10.875 35.434,22.5 51.188,34.875 15.746,12.375 28.684,23.062 38.812,32.062 l 22.5,0 0,-200.2496 c -21.003,-9.375 -41.066,-18.1875 -60.187,-26.4375 -19.129,-8.25 -39.191,-15.375 -60.187,-21.375 -27.379,-7.875 -53.067,-13.875 -77.063,-18 -24.004,-4.125 -57,-6.1875 -99,-6.1875"
|
||||
id="path3040"
|
||||
style="fill:#11568c;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 1672.23,45.082 -223.31,0 -57.94,169.313 -310.5,0 -57.94,-169.313 -217.685,0 309.375,837.563 248.63,0 309.37,-837.563 m -333.56,322.875 -102.94,300.375 -102.94,-300.375 205.88,0"
|
||||
id="path3042"
|
||||
style="fill:#11568c;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 529.656,684.461 c -36.738,-1.871 -77.344,-32.203 -81.344,-73.883 -4.417,-45.98 17.786,-71.976 51.626,-89.816 16.921,-8.922 36.476,-11.504 56.164,-8.313 19.683,3.192 38.996,12.778 52.886,32.239 5.774,8.136 3.856,19.41 -4.281,25.183 -8.137,5.774 -19.41,3.856 -25.184,-4.281 -8.914,-12.488 -18.597,-15.906 -29.214,-17.629 -10.618,-1.723 -22.473,-1.027 -33.497,4.785 -22.046,11.621 -34.374,29.988 -32.992,54.609 1.391,24.7 26.168,40.575 49.614,41.09 23.449,0.52 45.949,-10.675 53.894,-41.804 0.942,-6.871 5.746,-12.473 12.344,-14.606 6.594,-2.137 13.851,-0.488 18.637,4.531 4.781,5.02 6.226,12.403 3.777,18.887 -11.832,46.344 -52.047,69.836 -89.66,69.008 -0.879,-0.02 -1.887,0.043 -2.77,0 z M 25.9648,673.129 c -0.5546,-0.07 -1.0859,-0.332 -1.5117,-0.504 -0.125,-0.055 -0.3906,-0.191 -0.5039,-0.254 -0.0351,-0.023 -0.2187,-0.226 -0.25,-0.25 -0.0664,-0.051 -0.1953,-0.199 -0.2539,-0.254 -0.0547,-0.055 -0.1992,-0.191 -0.25,-0.25 -0.0234,-0.031 -0.2305,-0.219 -0.2539,-0.254 -0.0586,-0.101 -0.207,-0.39 -0.25,-0.504 -0.0156,-0.035 0.0117,-0.211 0,-0.25 -0.0352,-0.117 -0.2305,-0.375 -0.2539,-0.504 -0.0039,-0.043 0.0078,-0.207 0,-0.25 -0.4102,-4.816 14.4805,-20.425 20.4023,-26.445 6.1016,-6.211 56.5235,-46.558 84.8712,-65.73 28.527,-19.297 94.066,-54.223 110.812,-62.461 16.594,-8.16 68.145,-29.715 102.25,-40.043 58.672,-17.77 118.954,-28.031 177.297,-32.488 58.348,-4.454 114.86,-2.961 165.969,3.023 102.219,11.965 184,38.824 222.379,85.879 19.191,23.527 29.098,61.598 7.305,85.375 -23.711,25.871 -78.68,46.996 -82.102,47.097 -0.191,0 -0.582,0.012 -0.754,0 -0.113,-0.011 -0.402,0.016 -0.504,0 -0.051,-0.011 -0.203,0.012 -0.254,0 -0.047,-0.015 -0.207,-0.238 -0.25,-0.253 -0.043,-0.016 -0.211,0.019 -0.254,0 -0.117,-0.055 -0.398,-0.18 -0.503,-0.25 -0.032,-0.028 -0.219,-0.227 -0.25,-0.254 -0.028,-0.028 -0.227,-0.223 -0.254,-0.25 -0.067,-0.098 -0.196,-0.395 -0.25,-0.504 -0.043,-0.117 -0.223,-0.375 -0.254,-0.504 -0.016,-0.086 0.011,-0.41 0,-0.504 -0.004,-0.047 0.004,-0.203 0,-0.254 0,-0.047 0,-0.199 0,-0.25 0.316,-8.516 16.094,-27.164 27.785,-40.113 9.016,-9.981 16.566,-16.922 19.832,-21.176 12.211,-15.898 3.715,-27.934 -4.047,-39.703 -18.082,-27.414 -96.656,-58.742 -192.914,-70.012 -48.129,-5.633 -101.41,-6.867 -156.398,-2.519 -54.985,4.347 -111.622,14.078 -166.719,30.726 -37.449,11.317 -88.692,31.836 -107.539,39.793 -19.356,8.168 -77.43,36.235 -97.215,46.086 -19.625,9.774 -93.2384,55.328 -99.2267,59.688 -5.9882,4.359 -21.3007,9.871 -25.6875,9.32 z M 442.52,410.703 c -1.821,-0.109 -3.649,-0.5 -5.04,-1.008 -0.453,-0.175 -1.101,-0.535 -1.511,-0.754 -0.199,-0.113 -0.567,-0.382 -0.754,-0.503 -0.184,-0.126 -0.582,-0.368 -0.754,-0.504 -0.227,-0.188 -0.555,-0.551 -0.758,-0.754 -0.199,-0.211 -0.578,-0.532 -0.754,-0.758 -0.129,-0.172 -0.387,-0.574 -0.504,-0.754 -0.3,-0.496 -0.539,-1.203 -0.757,-1.766 -0.254,-0.711 -0.629,-1.707 -0.754,-2.515 -1.094,-8.11 4.429,-21.043 16.371,-36.266 23.273,-29.68 22.093,-53.344 22.414,-80.844 0.316,-27.5 -17.395,-56.957 -41.051,-84.621 C 401.41,167.785 370.586,140.562 342.559,118.773 314.715,97.1289 260.012,63.6016 242.551,50.0586 225.332,36.707 212,28.3867 209.309,20.8477 c -0.153,-0.4532 -0.418,-1.086 -0.504,-1.5118 -0.063,-0.3554 0.019,-0.9257 0,-1.2617 -0.004,-0.1992 -0.012,-0.5625 0,-0.7539 0.015,-0.1914 -0.032,-0.5703 0,-0.7578 0.039,-0.1797 0.195,-0.5781 0.25,-0.7539 0.043,-0.1133 0.207,-0.3906 0.254,-0.5039 0.05,-0.1094 0.191,-0.3945 0.25,-0.5039 0.129,-0.211 0.347,-0.5586 0.503,-0.7539 0.043,-0.0508 0.211,-0.2071 0.254,-0.2539 0.043,-0.0469 0.204,-0.2032 0.25,-0.25 0.051,-0.0469 0.204,-0.2071 0.254,-0.2539 0.625,-0.5196 1.614,-1.1211 2.52,-1.5118 6.336,-2.56246 19.394,-1.97652 39.539,3.5274 15.758,4.3086 34.66,10.8086 47.348,15.6133 13.023,4.9375 74.964,38.4648 109,63.1523 33.785,24.5077 71.421,62.1407 87.437,83.1717 15.879,20.848 41.262,53.235 43.32,118.367 1.371,43.528 -8.191,72.75 -54.902,99.731 -19.402,11.207 -33.578,15.898 -42.562,15.363"
|
||||
id="path3044"
|
||||
style="fill:#00be00;fill-opacity:1;fill-rule:evenodd;stroke:none" /><path
|
||||
d="m 1298.29,33.0547 c -64.72,19.7617 -128.5,42.1328 -168.77,74.4333 -42.17,33.824 -51.52,48.008 -75.3,80.746 -29.81,41.043 -59.63,125.993 -62.228,205.957 -1.933,59.375 6.25,107.641 25.268,151.563 16.31,37.664 50.72,85.133 66.86,83.586 16.79,-1.613 12.79,-22.199 1.8,-68.606 -12.97,-54.804 -14.7,-69.25 -14.78,-123.539 -0.1,-65.406 6,-96.316 28.15,-162.394 9.16,-27.34 20.57,-61.301 52.72,-97.508 25.63,-28.879 61.73,-56.82 127.17,-93.0274 52.63,-29.1172 66.92,-42.0234 67.68,-50.7422 0.35,-3.9531 -3.72,-6.789 -10.93,-6.9336 -9.68,-0.2031 -23.7,2.211 -37.64,6.4649 z m 219.34,469.2573 c -42.18,10.309 -58.18,20.684 -88.8,33.672 -96.79,41.055 -164.89,71.496 -185.55,78.805 -27.01,9.551 -112.64,39.285 -163.57,51.039 -57.65,13.309 -142.409,29.652 -175.3,31.434 -29.926,1.621 -72.531,-2.672 -90.598,-12.86 -21.546,-12.152 -18.187,-34.172 9.403,-79.953 4.918,-8.16 9.805,-13.461 7.773,-16.984 -1.883,-3.27 -12.652,-0.403 -21.808,3.894 -12.336,5.786 -29.75,23.145 -39.18,37.668 -22.016,33.914 -9.391,79.172 30.613,101.153 28.953,15.906 60.739,19.273 126.742,13.832 73.885,-6.094 143.355,-26.278 176.195,-36.188 180.42,-54.453 245.08,-80.371 317.15,-119.347 33.6,-18.176 63.75,-39.961 71.71,-44.762 6.56,-3.953 29.91,-18.887 40.27,-29.125 4.14,-4.094 5.63,-7.664 4.93,-9.129 -1.52,-3.176 -15.1,-4.34 -19.98,-3.149 z m -467.18,247.145 c -13.3,5.957 -22.54,18.926 -29.18,31.254 -4.52,8.375 -7.28,21.266 -6.57,35.387 0.71,14.113 1.87,25.601 10.46,43.691 11.5,24.199 28.57,41.508 51.45,52.16 14.78,6.883 17.58,7.863 36.23,7.906 18.8,0.04 24.33,-3.253 34.76,-9.316 13.03,-7.57 19.42,-18.258 23.87,-28.062 4.41,-9.68 6.72,-16.102 6.87,-33.622 0.14,-17.671 -4.96,-37.812 -21.27,-63.027 -8,-12.375 -21.5,-24.558 -41.88,-36.012 -14.21,-7.988 -43.3,-9.964 -64.74,-0.359 z m 60.84,33.828 c 18.94,16.098 25.2,29.086 26.87,54.242 1.75,26.485 -19.08,44.25 -28.66,45.25 -25.17,2.621 -47.61,-15.839 -52.81,-50.113 -1.11,-7.344 -0.44,-14.316 2.39,-25.043 3.08,-11.683 10.74,-23.902 23.13,-27.586 12.77,-3.793 22.57,-0.824 29.08,3.25"
|
||||
id="path3046"
|
||||
style="fill:#c7ff00;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></svg>
|
After Width: | Height: | Size: 12 KiB |
BIN
boardvoting/static/images/favicon.ico
Normal file
BIN
boardvoting/static/images/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
|
@ -1,74 +1,66 @@
|
|||
{{ template "header.html" . }}
|
||||
<div class="column">
|
||||
<div class="ui basic segment">
|
||||
<div class="ui floated right secondary menu">
|
||||
<a href="/motions/" class="item" title="Show all votes">Back to motions</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="ui raised segment">
|
||||
<form action="/newmotion/" method="post">
|
||||
{{ template "return_header" . }}
|
||||
<div class="ui raised segment">
|
||||
<form action="/newmotion/" method="post">
|
||||
{{ csrfField }}
|
||||
<div class="ui form{{ if .Form.Errors }} error{{ end }}">
|
||||
<div class="three fields">
|
||||
<div class="field">
|
||||
<label>ID:</label>
|
||||
(generated on submit)
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Proponent:</label>
|
||||
{{ .Voter.Name }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Proposed date/time:</label>
|
||||
(auto filled to current date/time)
|
||||
</div>
|
||||
<div class="ui form{{ if .Form.Errors }} error{{ end }}">
|
||||
<div class="three fields">
|
||||
<div class="field">
|
||||
<label>ID:</label>
|
||||
(generated on submit)
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Title }} error{{ end }}">
|
||||
<label for="Title">Title:</label>
|
||||
<input id="Title" name="Title" type="text" value="{{ .Form.Title }}">
|
||||
<div class="field">
|
||||
<label>Proponent:</label>
|
||||
{{ .Voter.Name }}
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Content }} error{{ end }}">
|
||||
<label for="Content">Text:</label>
|
||||
<textarea id="Content" name="Content">{{ .Form.Content }}</textarea>
|
||||
<div class="field">
|
||||
<label>Proposed date/time:</label>
|
||||
(auto filled to current date/time)
|
||||
</div>
|
||||
<div class="two fields">
|
||||
<div class="required field{{ if .Form.Errors.VoteType }} error{{ end }}">
|
||||
<label for="VoteType">Vote type:</label>
|
||||
<select id="VoteType" name="VoteType">
|
||||
<option value="0"
|
||||
{{ if eq "0" .Form.VoteType }}selected{{ end }}>
|
||||
Motion
|
||||
</option>
|
||||
<option value="1"
|
||||
{{ if eq "1" .Form.VoteType }}selected{{ end }}>
|
||||
Veto
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Due }} error{{ end }}">
|
||||
<label for="Due">Due: (autofilled from chosen
|
||||
option)</label>
|
||||
<select id="Due" name="Due">
|
||||
<option value="+3 days">In 3 Days</option>
|
||||
<option value="+7 days">In 1 Week</option>
|
||||
<option value="+14 days">In 2 Weeks</option>
|
||||
<option value="+28 days">In 4 Weeks</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Title }} error{{ end }}">
|
||||
<label for="Title">Title:</label>
|
||||
<input id="Title" name="Title" type="text" value="{{ .Form.Title }}">
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Content }} error{{ end }}">
|
||||
<label for="Content">Text:</label>
|
||||
<textarea id="Content" name="Content">{{ .Form.Content }}</textarea>
|
||||
</div>
|
||||
<div class="two fields">
|
||||
<div class="required field{{ if .Form.Errors.VoteType }} error{{ end }}">
|
||||
<label for="VoteType">Vote type:</label>
|
||||
<select id="VoteType" name="VoteType">
|
||||
<option value="0"
|
||||
{{ if eq "0" .Form.VoteType }}selected{{ end }}>
|
||||
Motion
|
||||
</option>
|
||||
<option value="1"
|
||||
{{ if eq "1" .Form.VoteType }}selected{{ end }}>
|
||||
Veto
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ with .Form.Errors }}
|
||||
<div class="required field{{ if .Form.Errors.Due }} error{{ end }}">
|
||||
<label for="Due">Due: (autofilled from chosen
|
||||
option)</label>
|
||||
<select id="Due" name="Due">
|
||||
<option value="+3 days">In 3 Days</option>
|
||||
<option value="+7 days">In 1 Week</option>
|
||||
<option value="+14 days">In 2 Weeks</option>
|
||||
<option value="+28 days">In 4 Weeks</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{{ with .Form.Errors }}
|
||||
<div class="ui error message">
|
||||
{{ with .Title }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Content }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .VoteType }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Due }}<p>{{ . }}</p>{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<button class="ui button" type="submit">Propose</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ end }}
|
||||
<button class="ui button" type="submit">Propose</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ template "footer.html" . }}
|
|
@ -1,17 +1,23 @@
|
|||
{{ template "header.html" . }}
|
||||
<div class="column">
|
||||
<div class="ui negative message">
|
||||
<div class="header.html">You are not authorized to act here!</div>
|
||||
<p>If you think this is in error, please contact the administrator.</p>
|
||||
<p>If you don't know who that is, it is definitely not an error ;)</p>
|
||||
{{ if .Emails }}
|
||||
<p>The following addresses were present in your certificate:<p>
|
||||
<ul>
|
||||
{{ range .Emails }}
|
||||
<li>{{ . }}</li>
|
||||
<div class="ui container">
|
||||
<div class="ui negative icon message">
|
||||
<i class="ban icon "></i>
|
||||
<div class="content">
|
||||
<div class="header">You are not authorized to act here!</div>
|
||||
<p>If you think this is in error, please contact the administrator.</p>
|
||||
<p>If you don't know who that is, it is definitely not an error ;)</p>
|
||||
{{ if .Emails }}
|
||||
<p>The following addresses were present in your certificate:<p>
|
||||
<div class="ui list">
|
||||
{{ range .Emails }}
|
||||
<div class="item">
|
||||
<i class="address card outline icon"></i>
|
||||
<div class="content">{{ . }}</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ template "footer.html" . }}
|
|
@ -1,31 +1,23 @@
|
|||
{{ template "header.html" . }}
|
||||
<div class="column">
|
||||
<div class="ui basic segment">
|
||||
<div class="ui floated right secondary menu">
|
||||
<a href="/motions/" class="item" title="Show all votes">Back to motions</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ template "return_header" . }}
|
||||
{{ with .Decision }}
|
||||
<div class="column">
|
||||
<div class="ui raised segment">
|
||||
{{ template "motion_fragment" . }}
|
||||
{{ template "motion_fragment" . }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<form action="/vote/{{ .Decision.Tag }}/{{ .VoteChoice }}" method="post">
|
||||
{{ csrfField }}
|
||||
{{ csrfField }}
|
||||
<div class="ui form">
|
||||
{{ if eq 1 .VoteChoice }}
|
||||
<button class="ui right labeled green icon button" type="submit"><i class="check circle icon"></i>
|
||||
Vote {{ .VoteChoice }}</button>
|
||||
{{ else if eq -1 .VoteChoice }}
|
||||
<button class="ui right labeled red icon button" type="submit"><i class="minus circle icon"></i>
|
||||
Vote {{ .VoteChoice }}</button>
|
||||
{{ else }}
|
||||
<button class="ui right labeled grey icon button" type="submit"><i class="circle icon"></i>
|
||||
Vote {{ .VoteChoice }}</button>
|
||||
{{ end }}
|
||||
{{ if eq 1 .VoteChoice }}
|
||||
<button class="ui right labeled green icon button" type="submit"><i class="check circle icon"></i>
|
||||
Vote {{ .VoteChoice }}</button>
|
||||
{{ else if eq -1 .VoteChoice }}
|
||||
<button class="ui right labeled red icon button" type="submit"><i class="minus circle icon"></i>
|
||||
Vote {{ .VoteChoice }}</button>
|
||||
{{ else }}
|
||||
<button class="ui right labeled grey icon button" type="submit"><i class="circle icon"></i>
|
||||
Vote {{ .VoteChoice }}</button>
|
||||
{{ end }}
|
||||
</div>
|
||||
</form>
|
||||
{{ template "footer.html" . }}
|
|
@ -1,72 +1,66 @@
|
|||
{{ template "header.html" . }}
|
||||
<div class="column">
|
||||
<div class="ui floated right secondary menu">
|
||||
<a href="/motions/" class="item" title="Show all votes">Back to
|
||||
motions</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="ui raised segment">
|
||||
<form action="/motions/{{ .Form.Decision.Tag }}/edit" method="post">
|
||||
<div class="ui form{{ if .Form.Errors }} error{{ end }}">
|
||||
<div class="three fields">
|
||||
<div class="field">
|
||||
<label>ID:</label>
|
||||
<a href="/motions/{{ .Form.Decision.Tag }}">{{ .Form.Decision.Tag }}</a>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Proponent:</label>
|
||||
{{ .Voter.Name }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Proposed date/time:</label>
|
||||
{{ .Form.Decision.Proposed|date "2006-01-02 15:04:05 UTC" }}
|
||||
</div>
|
||||
{{ template "return_header" . }}
|
||||
<div class="ui raised segment">
|
||||
<form action="/motions/{{ .Form.Decision.Tag }}/edit" method="post">
|
||||
{{ csrfField }}
|
||||
<div class="ui form{{ if .Form.Errors }} error{{ end }}">
|
||||
<div class="three fields">
|
||||
<div class="field">
|
||||
<label>ID:</label>
|
||||
<a href="/motions/{{ .Form.Decision.Tag }}">{{ .Form.Decision.Tag }}</a>
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Title }} error{{ end }}">
|
||||
<label for="Title">Title:</label>
|
||||
<input name="Title" type="text" value="{{ .Form.Title }}">
|
||||
<div class="field">
|
||||
<label>Proponent:</label>
|
||||
{{ .Voter.Name }}
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Content }} error{{ end }}">
|
||||
<label for="Content">Text:</label>
|
||||
<textarea name="Content">{{ .Form.Content }}</textarea>
|
||||
<div class="field">
|
||||
<label>Proposed date/time:</label>
|
||||
{{ .Form.Decision.Proposed|date "2006-01-02 15:04:05 UTC" }}
|
||||
</div>
|
||||
<div class="two fields">
|
||||
<div class="required field{{ if .Form.Errors.VoteType }} error{{ end }}">
|
||||
<label for="VoteType">Vote type:</label>
|
||||
<select name="VoteType">
|
||||
<option value="0"
|
||||
{{ if eq "0" .Form.VoteType }}selected{{ end }}>
|
||||
Motion
|
||||
</option>
|
||||
<option value="1"
|
||||
{{ if eq "1" .Form.VoteType }}selected{{ end }}>
|
||||
Veto
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Due }} error{{ end }}">
|
||||
<label for="Due">Due: (autofilled from chosen
|
||||
option)</label>
|
||||
<select name="Due">
|
||||
<option value="+3 days">In 3 Days</option>
|
||||
<option value="+7 days">In 1 Week</option>
|
||||
<option value="+14 days">In 2 Weeks</option>
|
||||
<option value="+28 days">In 4 Weeks</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Title }} error{{ end }}">
|
||||
<label for="Title">Title:</label>
|
||||
<input name="Title" type="text" value="{{ .Form.Title }}">
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Content }} error{{ end }}">
|
||||
<label for="Content">Text:</label>
|
||||
<textarea name="Content">{{ .Form.Content }}</textarea>
|
||||
</div>
|
||||
<div class="two fields">
|
||||
<div class="required field{{ if .Form.Errors.VoteType }} error{{ end }}">
|
||||
<label for="VoteType">Vote type:</label>
|
||||
<select name="VoteType">
|
||||
<option value="0"
|
||||
{{ if eq "0" .Form.VoteType }}selected{{ end }}>
|
||||
Motion
|
||||
</option>
|
||||
<option value="1"
|
||||
{{ if eq "1" .Form.VoteType }}selected{{ end }}>
|
||||
Veto
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ with .Form.Errors }}
|
||||
<div class="required field{{ if .Form.Errors.Due }} error{{ end }}">
|
||||
<label for="Due">Due: (autofilled from chosen
|
||||
option)</label>
|
||||
<select name="Due">
|
||||
<option value="+3 days">In 3 Days</option>
|
||||
<option value="+7 days">In 1 Week</option>
|
||||
<option value="+14 days">In 2 Weeks</option>
|
||||
<option value="+28 days">In 4 Weeks</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{{ with .Form.Errors }}
|
||||
<div class="ui error message">
|
||||
{{ with .Title }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Content }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .VoteType }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Due }}<p>{{ . }}</p>{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<button class="ui button" type="submit">Propose</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ end }}
|
||||
<button class="ui button" type="submit">Propose</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ template "footer.html" . }}
|
|
@ -1,12 +1,12 @@
|
|||
{{ define "footer.html" }}
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('.message .close').on('click', function() {
|
||||
$(this).closest('.message').transition('fade');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('.message .close').on('click', function () {
|
||||
$(this).closest('.message').transition('fade');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
|
@ -7,20 +7,35 @@
|
|||
<link rel="stylesheet" type="text/css" href="/static/semantic.min.css"/>
|
||||
<script type="text/javascript" src="/static/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/static/semantic.min.js"></script>
|
||||
<link rel="icon" href="/static/images/favicon.ico">
|
||||
</head>
|
||||
<body class="site">
|
||||
<body id="cacert-boardvoting">
|
||||
<div class="pusher">
|
||||
<div class="ui vertical masthead center aligned segment">
|
||||
<div class="ui left secondary container">
|
||||
<img src="/static/images/CAcert-logo-colour.svg" alt="CAcert" height="40rem"/>
|
||||
</div>
|
||||
<div class="ui text container">
|
||||
<h1 class="ui header">
|
||||
{{ template "pagetitle" . }}
|
||||
{{ if .Voter }}
|
||||
<div class="ui left pointing label">Authenticated as {{ .Voter.Name }} <{{ .Voter.Reminder }}>
|
||||
</div>{{ end }}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui container">
|
||||
<h1 class="ui header">{{ template "pagetitle" . }}{{ if .Voter }}<div class="ui left pointing label">Authenticated as {{ .Voter.Name }} <{{ .Voter.Reminder }}></div>{{ end }}</h1>
|
||||
{{ with .Flashes }}
|
||||
<div class="ui info message">
|
||||
<i class="close icon"></i>
|
||||
<div class="ui list">
|
||||
{{ range . }}
|
||||
<div class="ui item">{{ . }}</div>
|
||||
{{ end }}
|
||||
<div class="basic segment">
|
||||
<div class="ui info message">
|
||||
<i class="close icon"></i>
|
||||
<div class="ui list">
|
||||
{{ range . }}
|
||||
<div class="ui item">{{ . }}</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="ui one column grid container">
|
||||
{{ end }}
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
{{ template "header.html" . }}
|
||||
{{ $voter := .Voter }}
|
||||
<div class="column">
|
||||
<div class="ui basic segment">
|
||||
<div class="ui floated right secondary menu">
|
||||
<a href="/motions/" class="item" title="Show all votes">All votes</a>
|
||||
{{ if $voter }}<a href="/motions/?unvoted=1" class="item" title="Show my outstanding votes">My outstanding votes</a>{{ end }}
|
||||
</div>
|
||||
<div class="ui basic segment">
|
||||
<div class="ui secondary pointing menu">
|
||||
<a href="/motions/" class="item" title="Show all votes">All votes</a>
|
||||
{{ if $voter }}
|
||||
<a href="/motions/?unvoted=1" class="item" title="Show my outstanding votes">My outstanding votes</a>
|
||||
<div class="right item">
|
||||
<a class="ui primary button" href="/newmotion/">New motion</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ with .Decision }}
|
||||
<div class="column">
|
||||
<div class="ui raised segment">
|
||||
{{ template "motion_fragment" . }}
|
||||
{{ if $voter }}{{ template "motion_actions" . }}{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end}}
|
||||
{{ template "footer.html" . }}
|
|
@ -1,64 +1,68 @@
|
|||
{{ define "motion_fragment" }}
|
||||
<span class="ui {{ template "status_class" .Status }} ribbon label">{{ .Status|toString|title }}</span>
|
||||
<span class="header.html">{{ .Modified|date "2006-01-02 15:04:05 UTC" }}</span>
|
||||
<h3 class="header.html"><a href="/motions/{{ .Tag }}">{{ .Tag }}: {{ .Title }}</a></h3>
|
||||
<p>{{ wrap 76 .Content | nl2br }}</p>
|
||||
<table class="ui small definition table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Due</td>
|
||||
<td>{{.Due|date "2006-01-02 15:04:05 UTC"}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Proposed</td>
|
||||
<td>{{.Proposer}} ({{.Proposed|date "2006-01-02 15:04:05 UTC"}})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Vote type:</td>
|
||||
<td>{{ .VoteType|toString|title }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Votes:</td>
|
||||
<td>
|
||||
<div class="ui labels">
|
||||
<div class="ui basic label green"><i
|
||||
class="check circle icon"></i>Aye
|
||||
<div class="detail">{{.Ayes}}</div>
|
||||
<span class="ui {{ template "status_class" .Status }} ribbon label">{{ .Status|toString|title }}</span>
|
||||
<span class="header.html">{{ .Modified|date "2006-01-02 15:04:05 UTC" }}</span>
|
||||
<h3 class="header.html"><a href="/motions/{{ .Tag }}">{{ .Tag }}: {{ .Title }}</a></h3>
|
||||
<p>{{ wrap 76 .Content | nl2br }}</p>
|
||||
<table class="ui small definition table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Due</td>
|
||||
<td>{{.Due|date "2006-01-02 15:04:05 UTC"}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Proposed</td>
|
||||
<td>{{.Proposer}} ({{.Proposed|date "2006-01-02 15:04:05 UTC"}})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Vote type:</td>
|
||||
<td>{{ .VoteType|toString|title }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Votes:</td>
|
||||
<td>
|
||||
<div class="ui labels">
|
||||
<div class="ui basic label green"><i
|
||||
class="check circle icon"></i>Aye
|
||||
<div class="detail">{{.Ayes}}</div>
|
||||
</div>
|
||||
<div class="ui basic label red"><i
|
||||
class="minus circle icon"></i>Naye
|
||||
<div class="detail">{{.Nayes}}</div>
|
||||
</div>
|
||||
<div class="ui basic label grey"><i class="circle icon"></i>Abstain
|
||||
<div class="detail">{{.Abstains}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui basic label red"><i
|
||||
class="minus circle icon"></i>Naye
|
||||
<div class="detail">{{.Nayes}}</div>
|
||||
</div>
|
||||
<div class="ui basic label grey"><i class="circle icon"></i>Abstain
|
||||
<div class="detail">{{.Abstains}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ if .Votes }}
|
||||
<div class="list">
|
||||
{{ range .Votes }}
|
||||
<div class="item">{{ .Name }}: {{ .Vote.Vote }}</div>
|
||||
{{ if .Votes }}
|
||||
<div class="list">
|
||||
{{ range .Votes }}
|
||||
<div class="item">{{ .Name }}: {{ .Vote.Vote }}</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<a href="/motions/{{ .Tag }}">Hide Votes</a>
|
||||
{{ else if or ((ne 0 .Ayes) (ne 0 .Nayes) (ne 0 .Abstains)) }}
|
||||
<a href="/motions/{{ .Tag }}?showvotes=1">Show Votes</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
<a href="/motions/{{ .Tag }}">Hide Votes</a>
|
||||
{{ else if or ((ne 0 .Ayes) (ne 0 .Nayes) (ne 0 .Abstains)) }}
|
||||
<a href="/motions/{{ .Tag }}?showvotes=1">Show Votes</a>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
|
||||
{{ define "status_class" }}{{ if eq . 0 }}blue{{ else if eq . 1 }}green{{ else if eq . -1 }}red{{ else if eq . -2 }}grey
|
||||
{{ end }}{{ end }}
|
||||
{{ define "status_class" }}{{ if eq . 0 }}blue{{ else if eq . 1 }}green{{ else if eq . -1 }}red{{ else if eq . -2 }}grey{{ end }}{{ end }}
|
||||
|
||||
{{ define "motion_actions" }}
|
||||
{{ if eq .Status 0 }}
|
||||
<a class="ui compact right labeled green icon button" href="/vote/{{ .Tag }}/aye"><i class="check circle icon"></i> Aye</a>
|
||||
<a class="ui compact right labeled red icon button" href="/vote/{{ .Tag }}/naye"><i class="minus circle icon"></i> Naye</a>
|
||||
<a class="ui compact right labeled grey icon button" href="/vote/{{ .Tag }}/abstain"><i class="circle icon"></i> Abstain</a>
|
||||
<a class="ui compact left labeled icon button" href="/proxy/{{ .Tag }}"><i class="users icon"></i> Proxy Vote</a>
|
||||
<a class="ui compact left labeled icon button" href="/motions/{{ .Tag }}/edit"><i class="edit icon"></i> Modify</a>
|
||||
<a class="ui compact left labeled icon button" href="/motions/{{ .Tag }}/withdraw"><i class="trash icon"></i> Withdraw</a>
|
||||
{{ end }}
|
||||
{{ if eq .Status 0 }}
|
||||
<a class="ui compact right labeled green icon button" href="/vote/{{ .Tag }}/aye"><i
|
||||
class="check circle icon"></i> Aye</a>
|
||||
<a class="ui compact right labeled red icon button" href="/vote/{{ .Tag }}/naye"><i
|
||||
class="minus circle icon"></i> Naye</a>
|
||||
<a class="ui compact right labeled grey icon button" href="/vote/{{ .Tag }}/abstain"><i class="circle icon"></i>
|
||||
Abstain</a>
|
||||
<a class="ui compact left labeled icon button" href="/proxy/{{ .Tag }}"><i class="users icon"></i> Proxy
|
||||
Vote</a>
|
||||
<a class="ui compact left labeled icon button" href="/motions/{{ .Tag }}/edit"><i class="edit icon"></i> Modify</a>
|
||||
<a class="ui compact left labeled icon button" href="/motions/{{ .Tag }}/withdraw"><i class="trash icon"></i>
|
||||
Withdraw</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
|
|
@ -1,52 +1,45 @@
|
|||
{{ template "header.html" . }}
|
||||
{{ $voter := .Voter }}
|
||||
<div class="column">
|
||||
<div class="ui basic segment">
|
||||
<div class="ui floated right secondary menu">
|
||||
|
||||
<a href="/motions/" class="{{ if not .Params.Flags.Unvoted }}active {{ end }}item" title="Show all votes">All votes</a>
|
||||
{{ if $voter }}<a href="/motions/?unvoted=1" class="{{ if .Params.Flags.Unvoted }}active {{ end}}item" title="Show my outstanding votes">My outstanding votes</a>{{ end }}
|
||||
</div>
|
||||
{{ if $voter }}<a class="ui primary button" href="/newmotion/">New motion</a>{{ end }}
|
||||
{{ if .PrevPage -}}
|
||||
<a href="?page={{ .PrevPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}"
|
||||
class="ui left labeled icon button" title="newer motions"><i class="left arrow icon"></i> newer</a>
|
||||
{{- end }}
|
||||
{{ if .NextPage -}}
|
||||
<a href="?page={{ .NextPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}"
|
||||
class="ui right labeled icon button" title="older motions"><i class="right arrow icon"></i> older</a>
|
||||
{{- end }}
|
||||
{{ $page := . }}
|
||||
<div class="ui basic segment">
|
||||
<div class="ui secondary pointing menu">
|
||||
<a href="/motions/" class="{{ if not .Params.Flags.Unvoted }}active {{ end }}item" title="Show all votes">All
|
||||
votes</a>
|
||||
{{ if $voter }}
|
||||
<a href="/motions/?unvoted=1" class="{{ if .Params.Flags.Unvoted }}active {{ end}}item"
|
||||
title="Show my outstanding votes">My outstanding votes</a>
|
||||
<div class="right item">
|
||||
<a class="ui primary button" href="/newmotion/">New motion</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ if .Decisions }}
|
||||
<div class="ui labeled icon menu">
|
||||
{{ template "pagination_fragment" $page }}
|
||||
</div>
|
||||
{{ range .Decisions }}
|
||||
<div class="column">
|
||||
<div class="ui raised segment">
|
||||
{{ template "motion_fragment" . }}
|
||||
{{ if $voter }}{{ template "motion_actions" . }}{{ end }}
|
||||
{{ template "motion_fragment" . }}
|
||||
{{ if $voter }}{{ template "motion_actions" . }}{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="ui labeled icon menu">
|
||||
{{ template "pagination_fragment" $page }}
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="ui basic segment">
|
||||
<div class="ui icon message">
|
||||
<i class="inbox icon"></i>
|
||||
<div class="content">
|
||||
<div class="header">No motions available</div>
|
||||
{{ if .Params.Flags.Unvoted }}
|
||||
<p>There are no motions requiring a vote from you.</p>
|
||||
{{ else }}
|
||||
<p>There are no motions in the system yet.</p>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="column">
|
||||
<div class="ui basic segment">
|
||||
{{ if $voter }}<a class="ui primary button" href="/newmotion/">New motion</a>{{ end }}
|
||||
{{ if .PrevPage -}}
|
||||
<a href="?page={{ .PrevPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}"
|
||||
class="ui left labeled icon button" title="newer motions">
|
||||
<i class="left arrow icon"></i> newer</a>
|
||||
{{- end }}
|
||||
{{ if .NextPage -}}
|
||||
<a href="?page={{ .NextPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}"
|
||||
class="ui right labeled icon button" title="older motions">
|
||||
<i class="right arrow icon"></i> older</a>
|
||||
{{- end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
{{ if .Params.Flags.Unvoted }}
|
||||
<p>There are no motions requiring a vote from you.</p>
|
||||
{{ else }}
|
||||
<p>There are no motions in the system yet.</p>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ template "footer.html" . }}
|
20
boardvoting/templates/page_fragments.html
Normal file
20
boardvoting/templates/page_fragments.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
{{ define "pagination_fragment" }}
|
||||
{{ if .PrevPage -}}
|
||||
<a class="item" href="?page={{ .PrevPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}">
|
||||
<i class="left arrow icon"></i> newer
|
||||
</a>
|
||||
{{- end }}
|
||||
{{ if .NextPage -}}
|
||||
<a class="right item" href="?page={{ .NextPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}">
|
||||
<i class="right arrow icon"></i> older
|
||||
</a>
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "return_header" }}
|
||||
<div class="ui basic segment">
|
||||
<div class="ui secondary pointing menu">
|
||||
<a href="/motions/" class="item" title="Show all votes">Back to motions</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
|
@ -1,56 +1,47 @@
|
|||
{{ template "header.html" . }}
|
||||
{{ template "return_header" . }}
|
||||
{{ $form := .Form }}
|
||||
<div class="column">
|
||||
<div class="ui basic segment">
|
||||
<div class="ui floated right secondary menu">
|
||||
<a href="/motions/" class="item" title="Show all votes">Back to
|
||||
motions</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="ui raised segment">
|
||||
<div class="ui raised segment">
|
||||
{{ with .Decision }}
|
||||
{{ template "motion_fragment" . }}
|
||||
{{ end }}
|
||||
<form action="/proxy/{{ .Decision.Tag }}" method="post">
|
||||
{{ end }}
|
||||
<form action="/proxy/{{ .Decision.Tag }}" method="post">
|
||||
{{ csrfField }}
|
||||
<div class="ui form{{ if .Form.Errors }} error{{ end }}">
|
||||
<div class="two fields">
|
||||
<div class="required field{{ if .Form.Errors.Voter }} error{{ end }}">
|
||||
<label for="Voter">Voter</label>
|
||||
<select name="Voter">
|
||||
<div class="ui form{{ if .Form.Errors }} error{{ end }}">
|
||||
<div class="two fields">
|
||||
<div class="required field{{ if .Form.Errors.Voter }} error{{ end }}">
|
||||
<label for="Voter">Voter</label>
|
||||
<select name="Voter">
|
||||
{{ range .Voters }}
|
||||
<option value="{{ .Id }}"
|
||||
{{ if eq (.Id | print) $form.Voter }}
|
||||
selected{{ end }}>{{ .Name }}</option>
|
||||
{{ if eq (.Id | print) $form.Voter }}
|
||||
selected{{ end }}>{{ .Name }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Vote }} error{{ end }}">
|
||||
<label for="Vote">Vote</label>
|
||||
<select name="Vote">
|
||||
<option value="1"{{ if eq .Form.Vote "1" }} selected{{ end }}>Aye</option>
|
||||
<option value="0"{{ if eq .Form.Vote "0" }} selected{{ end }}>Abstain</option>
|
||||
<option value="-1"{{ if eq .Form.Vote "-1" }} selected{{ end }}>Naye</option>
|
||||
</select>
|
||||
</div>
|
||||
</select>
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Justification }} error{{ end }}">
|
||||
<label for="Justification">Justification</label>
|
||||
<textarea name="Justification" rows="2">{{ .Form.Justification }}</textarea>
|
||||
<div class="required field{{ if .Form.Errors.Vote }} error{{ end }}">
|
||||
<label for="Vote">Vote</label>
|
||||
<select name="Vote">
|
||||
<option value="1"{{ if eq .Form.Vote "1" }} selected{{ end }}>Aye</option>
|
||||
<option value="0"{{ if eq .Form.Vote "0" }} selected{{ end }}>Abstain</option>
|
||||
<option value="-1"{{ if eq .Form.Vote "-1" }} selected{{ end }}>Naye</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="required field{{ if .Form.Errors.Justification }} error{{ end }}">
|
||||
<label for="Justification">Justification</label>
|
||||
<textarea name="Justification" rows="2">{{ .Form.Justification }}</textarea>
|
||||
</div>
|
||||
{{ with .Form.Errors }}
|
||||
<div class="ui error message">
|
||||
{{ with .Voter }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Vote }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Justification }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Voter }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Vote }}<p>{{ . }}</p>{{ end }}
|
||||
{{ with .Justification }}<p>{{ . }}</p>{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<button class="ui primary left labeled icon button" type="submit"><i class="users icon"></i> Proxy Vote
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<button class="ui primary left labeled icon button" type="submit"><i class="users icon"></i> Proxy Vote
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ template "footer.html" . }}
|
|
@ -1,22 +1,17 @@
|
|||
{{ template "header.html" . }}
|
||||
<div class="column">
|
||||
<div class="ui basic segment">
|
||||
<div class="ui floated right secondary menu">
|
||||
<a href="/motions/" class="item" title="Show all votes">Back to motions</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ template "return_header" . }}
|
||||
{{ with .Decision }}
|
||||
<div class="column">
|
||||
<div class="ui raised segment">
|
||||
{{ template "motion_fragment" . }}
|
||||
{{ template "motion_fragment" . }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<form action="/motions/{{ .Decision.Tag }}/withdraw" method="post">
|
||||
{{ csrfField }}
|
||||
<div class="ui form">
|
||||
<button class="ui primary left labeled icon button" type="submit"><i class="trash icon"></i> Withdraw</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ template "footer.html" . }}
|
||||
<div class="ui basic segment">
|
||||
<form action="/motions/{{ .Decision.Tag }}/withdraw" method="post">
|
||||
{{ csrfField }}
|
||||
<div class="ui form">
|
||||
<button class="ui primary left labeled icon button" type="submit"><i class="trash icon"></i> Withdraw
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ template "footer.html" . }}
|
Loading…
Reference in a new issue