liquid_feedback_frontend

changeset 211:4993b71b383f

First checkin of lf2 (frontend second generation) prototype
author bsw
date Wed Mar 02 20:06:26 2011 +0100 (2011-03-02)
parents 2c422bcb79de
children 3e4ad069847a
files app/main/_filter_view/34_stylesheet.lua app/main/_layout/lf2.html app/main/lf2/_area.lua app/main/lf2/_areas.lua app/main/lf2/_avatars.lua app/main/lf2/_delegation_global.lua app/main/lf2/_draft.lua app/main/lf2/_filter_view/10_topnav.lua app/main/lf2/_initiative.lua app/main/lf2/_initiatives.lua app/main/lf2/_interested.lua app/main/lf2/_issue_initiatives.lua app/main/lf2/_issues.lua app/main/lf2/_issues_issue.lua app/main/lf2/_search.lua app/main/lf2/_sidebar.lua app/main/lf2/_sidebar_drafts.lua app/main/lf2/_sidebar_initiatives.lua app/main/lf2/_sidebar_issue.lua app/main/lf2/area.lua app/main/lf2/area_notification.lua app/main/lf2/index.lua app/main/lf2/initiative.lua app/main/lf2/issue.lua config/development.lua env/ui/avatar.lua env/ui/box.lua env/ui/box_col.lua env/ui/box_row.lua env/ui/boxhead.lua locale/translations.de.lua locale/translations.en.lua model/area.lua model/delegating_interest_snapshot.lua model/direct_interest_snapshot.lua model/issue.lua static/lf2/icon_award_gold.png static/lf2/icon_award_silver.png static/lf2/icon_cross.png static/lf2/icon_delegated_star.png static/lf2/icon_delegation.png static/lf2/icon_delegation_area.png static/lf2/icon_delegation_global.png static/lf2/icon_eye.png static/lf2/icon_search.png static/lf2/icon_search_crossed.png static/lf2/icon_star.png static/lf2/icon_star_crossed.png static/lf2/icon_star_grey.png static/lf2/icon_suggestion.png static/lf2/icon_supporter.png static/lf2/icon_text.png static/lf2/icon_vote.png
line diff
     1.1 --- a/app/main/_filter_view/34_stylesheet.lua	Sat Feb 05 20:01:09 2011 +0100
     1.2 +++ b/app/main/_filter_view/34_stylesheet.lua	Wed Mar 02 20:06:26 2011 +0100
     1.3 @@ -41,7 +41,7 @@
     1.4    slot.set_layout("blank")
     1.5  end
     1.6  
     1.7 -if request.get_module() ~= "api" and request.get_view() ~= "list_rss" and request.get_module() ~= "sitemap" then
     1.8 +if request.get_module() ~= "lf2" and request.get_module() ~= "api" and request.get_view() ~= "list_rss" and request.get_module() ~= "sitemap" then
     1.9    ui.container{
    1.10      attr = {
    1.11        class = web20 and "web20" or "web10"
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/app/main/_layout/lf2.html	Wed Mar 02 20:06:26 2011 +0100
     2.3 @@ -0,0 +1,577 @@
     2.4 +<!-- <html> -->
     2.5 +<head> 
     2.6 +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     2.7 +<style>
     2.8 +
     2.9 +/* CSS reset */
    2.10 +
    2.11 +html, body, div, span, applet, object, iframe,
    2.12 +h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    2.13 +a, abbr, acronym, address, big, cite, code,
    2.14 +del, dfn, em, font, img, ins, kbd, q, s, samp,
    2.15 +small, strike, strong, sub, sup, tt, var,
    2.16 +dl, dt, dd, ol, ul, li,
    2.17 +fieldset, form, label, legend,
    2.18 +table, caption, tbody, tfoot, thead, tr, th, td {
    2.19 +    margin: 0;
    2.20 +    padding: 0;
    2.21 +    border: 0;
    2.22 +    outline: 0;
    2.23 +    font-weight: inherit;
    2.24 +    font-style: inherit;
    2.25 +    font-size: 100%;
    2.26 +    font-family: inherit;
    2.27 +    vertical-align: baseline;
    2.28 +}
    2.29 +/* remember to define focus styles! */
    2.30 +:focus {
    2.31 +    outline: 0;
    2.32 +}
    2.33 +body {
    2.34 +    line-height: 1;
    2.35 +    color: black;
    2.36 +    background: white;
    2.37 +}
    2.38 +ol, ul {
    2.39 +    list-style: none;
    2.40 +}
    2.41 +/* tables still need 'cellspacing="0"' in the markup */
    2.42 +table {
    2.43 +    border-collapse: separate;
    2.44 +    border-spacing: 0;
    2.45 +}
    2.46 +caption, th, td {
    2.47 +    text-align: left;
    2.48 +    font-weight: normal;
    2.49 +}
    2.50 +blockquote:before, blockquote:after,
    2.51 +q:before, q:after {
    2.52 +    content: "";
    2.53 +}
    2.54 +blockquote, q {
    2.55 +    quotes: "" "";
    2.56 +}
    2.57 +
    2.58 +/* end CSS reset */
    2.59 +
    2.60 +
    2.61 +/*
    2.62 +    Global settings
    2.63 +*/
    2.64 +body {
    2.65 +  font-family: sans-serif;
    2.66 +  background-color: #7df;
    2.67 +  color: #000;
    2.68 +}
    2.69 +
    2.70 +a {
    2.71 +  background-color: #ffffff;
    2.72 +  color: #000;
    2.73 +}
    2.74 +
    2.75 +/*
    2.76 +    Main top navigation
    2.77 +*/
    2.78 +
    2.79 +.tab1 {
    2.80 +  background-color: #444;
    2.81 +  color: #000;
    2.82 +}
    2.83 +
    2.84 +.tab1 .right {
    2.85 +  float: right;
    2.86 +}
    2.87 +
    2.88 +.tab1 a {
    2.89 +  float: left;
    2.90 +  padding: 0.5ex 0.5em 0.5ex 0.5em;
    2.91 +  margin-left: 0.5em;
    2.92 +  background-color: #444;
    2.93 +  color: #fff;
    2.94 +  font-weight: bold;
    2.95 +}
    2.96 +
    2.97 +.tab1 .right a {
    2.98 +  margin-left: 0;
    2.99 +  margin-right: 0.5em;
   2.100 +}
   2.101 +
   2.102 +.tab1 a.active {
   2.103 +  background-color: #7df;
   2.104 +}
   2.105 +
   2.106 +/*
   2.107 +    Default slot
   2.108 +*/
   2.109 +
   2.110 +.slot_default {
   2.111 +  margin: 2ex 1% 2ex 32%;
   2.112 +  position: relative;
   2.113 +  width: 67%;
   2.114 +}
   2.115 +
   2.116 +/*
   2.117 +    Sidebar
   2.118 +*/
   2.119 +
   2.120 +.slot_sidebar {
   2.121 +  margin: 2ex 1% 2ex 1%;
   2.122 +  float: left;
   2.123 +  width: 30%;
   2.124 +}
   2.125 +
   2.126 +.slot_sidebar .box {
   2.127 +  width: 100%;
   2.128 +}
   2.129 +
   2.130 +
   2.131 +/*
   2.132 +    Boxes
   2.133 +*/
   2.134 +
   2.135 +.box a {
   2.136 +  text-decoration: none;
   2.137 +  color: #46a;
   2.138 +}
   2.139 +
   2.140 +.boxhead,
   2.141 +a.boxhead {
   2.142 +  /* position */
   2.143 +  display: block;
   2.144 +  margin-bottom: 0.5ex;
   2.145 +  margin-top: 1ex;
   2.146 +  margin-left: 0.5em;
   2.147 +
   2.148 +  /* color */
   2.149 +  background-color: #7df;
   2.150 +  color: #000;
   2.151 +
   2.152 +  /* text format */
   2.153 +  font-weight: bold;
   2.154 +  text-shadow: 2px 2px 2px #fff;
   2.155 +}
   2.156 +
   2.157 +.box {
   2.158 +  /* position */
   2.159 +  position: relative;
   2.160 +  width: 100%;
   2.161 +  margin-bottom: 2ex;
   2.162 +
   2.163 +  /* border and shadow*/
   2.164 +  border-radius: 1ex;
   2.165 +  -moz-border-radius: 1ex;
   2.166 +  -webkit-box-shadow: 2px 2px 3px 0px #444;
   2.167 +  -moz-box-shadow: 2px 2px 3px 0px #444;
   2.168 +
   2.169 +  /* color */
   2.170 +  background-color: #fff;
   2.171 +  color: #000;
   2.172 +
   2.173 +}
   2.174 +
   2.175 +.box .row {
   2.176 +  overflow: auto;
   2.177 +  /* position */
   2.178 +
   2.179 +  /* border */
   2.180 +  border-top: 1px solid #ccc;
   2.181 +}
   2.182 +
   2.183 +.box .row .col {
   2.184 +  /* position */
   2.185 +  padding: 0.5ex 0.2em 0.5ex 0.2em;
   2.186 +
   2.187 +  /* text format */
   2.188 +  line-height: 125%;
   2.189 +}
   2.190 +
   2.191 +.box .row .col.left {
   2.192 +  float: left;
   2.193 +}
   2.194 +
   2.195 +.box .row .col.right {
   2.196 +  float: right;
   2.197 +}
   2.198 +
   2.199 +.box .row .col.clearleft {
   2.200 +  clear: left;
   2.201 +}
   2.202 +
   2.203 +.box .row .col.clearright {
   2.204 +  clear: right;
   2.205 +}
   2.206 +
   2.207 +.box .row .col.toggle {
   2.208 +  float: left;
   2.209 +  /* position */
   2.210 +  padding-left: 0.4em;
   2.211 +}
   2.212 +
   2.213 +.box .row .col.toggle:hover {
   2.214 +  /* color */
   2.215 +  background-color: #7cf;
   2.216 +
   2.217 +  /* cursor */
   2.218 +  cursor: pointer;
   2.219 +}
   2.220 +
   2.221 +.box .row.first .col.toggle {
   2.222 +  /* border */
   2.223 +  border-radius: 1ex 0 0 0;
   2.224 +}
   2.225 +
   2.226 +.box .row.last .col.toggle {
   2.227 +  /* border */
   2.228 +  border-radius: 0 0 0 1ex;
   2.229 +}
   2.230 +
   2.231 +.box .row.toggled .col.first {
   2.232 +  /* position */
   2.233 +  margin-left: 1.5em;
   2.234 +}
   2.235 +
   2.236 +.box .row.first {
   2.237 +  /* border */
   2.238 +  border-top: none;
   2.239 +}
   2.240 +
   2.241 +.box .row .col.first {
   2.242 +  /* position */
   2.243 +  padding-left: 0.5em;
   2.244 +}
   2.245 +
   2.246 +.box .row.toggled .col.first {
   2.247 +  /* position */
   2.248 +  padding-left: 0.2em;
   2.249 +}
   2.250 +
   2.251 +.box .row .col {
   2.252 +xborder: 1px solid red !important;
   2.253 +}
   2.254 +
   2.255 +.box .row.head {
   2.256 +  background-color: #e4e7f0;
   2.257 +  color: #000;
   2.258 +  border-radius: 1ex 1ex 0 0;
   2.259 +}
   2.260 +
   2.261 +.box .row.head .col a {
   2.262 +  background-color: #e4e7f0;
   2.263 +  color: #3B6E7F;
   2.264 +}
   2.265 +
   2.266 +.box .row.head2 {
   2.267 +  background-color: #f2f3f7;
   2.268 +  color: #000;
   2.269 +}
   2.270 +
   2.271 +.box .row.head2 .col a {
   2.272 +  background-color: #f2f3f7;
   2.273 +  color: #3B6E7F;
   2.274 +}
   2.275 +
   2.276 +
   2.277 +.box .row .col a {
   2.278 +  color: #3B6E7F;
   2.279 +}
   2.280 +
   2.281 +/* Sidebar hover button */
   2.282 +
   2.283 +.hoverbutton_container {
   2.284 +  position: relative;
   2.285 +}
   2.286 +
   2.287 +
   2.288 +.hoverbutton {
   2.289 +  /* position */
   2.290 +  display: none;
   2.291 +  position: absolute;
   2.292 +  top: 0px;
   2.293 +  left: 0px;
   2.294 +  height: 100%;
   2.295 +  width: 100%;
   2.296 +
   2.297 +  /* color */
   2.298 +  background-color: #fff;
   2.299 +
   2.300 +  /* text format */
   2.301 +  font-weight: bold;
   2.302 +
   2.303 +  /* cursor */
   2.304 +  cursor: pointer;
   2.305 +}
   2.306 +
   2.307 +.hoverbutton_container:hover .hoverbutton {
   2.308 +  /* position */
   2.309 +  display: block;
   2.310 +}
   2.311 +
   2.312 +.hoverbutton_container:hover .hoverbutton img {
   2.313 +  /* text format */
   2.314 +  vertical-align: middle;
   2.315 +}
   2.316 +
   2.317 +.hoverbutton_container:hover .hoverbutton.noaction {
   2.318 +  /* color */
   2.319 +  background-color: #ccc;
   2.320 +
   2.321 +  /* cursor */
   2.322 +  cursor: default;
   2.323 +}
   2.324 +
   2.325 +.hoverbutton_container:hover .hoverbutton.green {
   2.326 +  background-color: #cfc;
   2.327 +}
   2.328 +
   2.329 +.hoverbutton_container:hover .hoverbutton.red {
   2.330 +  background-color: #fcc;
   2.331 +}
   2.332 +
   2.333 +.hoverbutton .content {
   2.334 +  /* position */
   2.335 +  padding: 0.5ex 0.2em 0.5ex 0.5em;
   2.336 +}
   2.337 +
   2.338 +/* Scrolled col */
   2.339 +
   2.340 +.box .row .col.scrolled {
   2.341 +  padding: 0;
   2.342 +  max-height: 300px;
   2.343 +  overflow: auto;
   2.344 +}
   2.345 +
   2.346 +.box .row .col.scrolled .head {
   2.347 +  font-weight: bold;
   2.348 +  padding: 0.5ex 0.2em 0.5ex 0.5em;
   2.349 +}
   2.350 +
   2.351 +/*
   2.352 +  Bars
   2.353 +*/
   2.354 +
   2.355 +.bar {
   2.356 +  float: right;
   2.357 +  margin-left: 0.3em;
   2.358 +}
   2.359 +
   2.360 +.bar div {
   2.361 +  margin-top: 2px;
   2.362 +  float: left;
   2.363 +  height: 11px;
   2.364 +}
   2.365 +.bar .green {
   2.366 +  background-color: #0a0;
   2.367 +}
   2.368 +
   2.369 +.bar .grey {
   2.370 +  background-color: #eee;
   2.371 +}
   2.372 +
   2.373 +/*
   2.374 +    Avatars
   2.375 +*/
   2.376 +
   2.377 +.avatars {
   2.378 +  overflow: auto;
   2.379 +}
   2.380 +
   2.381 +.avatars .avatar {
   2.382 +  float: left;
   2.383 +  margin-left: 2px;
   2.384 +  margin-right: 2px;
   2.385 +}
   2.386 +
   2.387 +.avatars.normal .avatar {
   2.388 +  width: 100px;
   2.389 +  -webkit-box-shadow: 1px 1px 1px #000;
   2.390 +  background-color: #eee;
   2.391 +  border-radius: 1ex;
   2.392 +  -moz-border-radius: 1ex;
   2.393 +}
   2.394 +
   2.395 +.avatars.small .avatar {
   2.396 +  border: 2px solid #fff;
   2.397 +  border-radius: 0.5ex;
   2.398 +  -moz-border-radius: 0.5ex;
   2.399 +}
   2.400 +
   2.401 +.avatars .arrow {
   2.402 +  float: left;
   2.403 +  margin-top: 0.3ex;
   2.404 +}
   2.405 +
   2.406 +.avatars .avatar.myweight {
   2.407 +  border-color: #f70;
   2.408 +  background-color: #f70;
   2.409 +}
   2.410 +
   2.411 +.avatars .avatar.autoreject {
   2.412 +  border-color: #f00;
   2.413 +  background-color: #f00;
   2.414 +}
   2.415 +
   2.416 +.avatars.small .avatar img {
   2.417 +  border-radius: 0.25ex;
   2.418 +  -moz-border-radius: 0.25ex;
   2.419 +}
   2.420 +
   2.421 +.avatars.normal .avatar img {
   2.422 +  margin-left: 0.3em;
   2.423 +  margin-top: 0.3ex;
   2.424 +  border-radius: 1ex;
   2.425 +  -moz-border-radius: 1ex;
   2.426 +}
   2.427 +
   2.428 +.avatars.small .avatar img {
   2.429 +  height: 24px;
   2.430 +  width: 24px;
   2.431 +}
   2.432 +
   2.433 +.avatars.normal .avatar img {
   2.434 +  height: 48px;
   2.435 +  width: 48px;
   2.436 +}
   2.437 +
   2.438 +.avatars.normal .avatar .name {
   2.439 +  margin-left: 0.3em;
   2.440 +  margin-top: 0.3ex;
   2.441 +  line-height: 100%;
   2.442 +  font-size: 70%;
   2.443 +  overflow: hidden;
   2.444 +  height: 4ex;
   2.445 +}
   2.446 +
   2.447 +.avatars .avatar .weight {
   2.448 +  text-align: center;
   2.449 +  font-size: 70%;
   2.450 +}
   2.451 +
   2.452 +.avatars.small .avatar.participation {
   2.453 +  border-color: #f70;
   2.454 +}
   2.455 +
   2.456 +.avatars.small .avatar.overridden,
   2.457 +.avatars.small .arrow.overridden {
   2.458 +  opacity: 0.3;
   2.459 +}
   2.460 +
   2.461 +/*
   2.462 +  Area
   2.463 +*/
   2.464 +
   2.465 +.area .name {
   2.466 +  color: #444;
   2.467 +  font-weight: bold;
   2.468 +}
   2.469 +
   2.470 +.area .name a {
   2.471 +  font-weight: normal;
   2.472 +}
   2.473 +
   2.474 +.area .name .avatars {
   2.475 +  float: right;
   2.476 +  margin-top: -3px;
   2.477 +}
   2.478 +
   2.479 +/* Issues */
   2.480 +
   2.481 +.issue .issue_id {
   2.482 +  font-weight: bold;
   2.483 +}
   2.484 +
   2.485 +.issue .state_name {
   2.486 +  font-style: italic;
   2.487 +}
   2.488 +
   2.489 +.issue .time_left {
   2.490 +  font-style: italic;
   2.491 +}
   2.492 +
   2.493 +/* Initiatives */
   2.494 +
   2.495 +.initiative .name,
   2.496 +.initiative a.name {
   2.497 +  font-weight: bold;
   2.498 +}
   2.499 +
   2.500 +.initiative .authors {
   2.501 +  /* color */
   2.502 +  color: #777;
   2.503 +
   2.504 +  /* text format */
   2.505 +  font-size: 80%;
   2.506 +  font-style: italic;
   2.507 +}
   2.508 +
   2.509 +.initiative .authors a {
   2.510 +  /* color */
   2.511 +}
   2.512 +
   2.513 +.drafts .draft .created {
   2.514 +  font-weight: bold;
   2.515 +}
   2.516 +
   2.517 +.drafts .draft .author_name {
   2.518 +  font-style: italic;
   2.519 +}
   2.520 +
   2.521 +/* Draft */
   2.522 +
   2.523 +.draft {
   2.524 +  line-height: 135%;
   2.525 +}
   2.526 +
   2.527 +.draft h2 {
   2.528 +  font-size: 135%;
   2.529 +  font-weight: bold;
   2.530 +  margin-bottom: 0.5ex;
   2.531 +}
   2.532 +
   2.533 +.draft h3 {
   2.534 +  font-size: 135%;
   2.535 +  margin-bottom: 0.5ex;
   2.536 +}
   2.537 +
   2.538 +.draft p {
   2.539 +  margin-bottom: 1ex;
   2.540 +}
   2.541 +
   2.542 +.draft ul {
   2.543 +  padding-left: 2em;
   2.544 +  list-style: disc;
   2.545 +}
   2.546 +
   2.547 +.draft ul li {
   2.548 +  margin-bottom: 1ex;
   2.549 +}
   2.550 +
   2.551 +xdiv { border: 1px dotted #c00 !important; }
   2.552 +
   2.553 +
   2.554 +</style>
   2.555 +</head>
   2.556 +</body>
   2.557 +<div class="tab1">
   2.558 +  <!-- WEBMCP SLOT topnav -->
   2.559 +<br style="clear: both;" />
   2.560 +</div>
   2.561 +
   2.562 +<!-- WEBMCP SLOT sidebar -->
   2.563 +<!-- WEBMCP SLOT default -->
   2.564 +
   2.565 +
   2.566 +    <div class="layout_trace" id="layout_trace" style="xdisplay: none">
   2.567 +      <div id="trace_show" onclick="document.getElementById('trace_content').style.display='block';this.style.display='none';">TRACE</div>
   2.568 +        <div id="trace_content" style="display: none;">
   2.569 +            <tt id="system_error"><!-- WEBMCP SLOT system_error --></tt>
   2.570 +            <div id="trace">&nbsp;</div><hr />
   2.571 +            <!-- WEBMCP SLOT trace -->
   2.572 +          <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';">
   2.573 +            close
   2.574 +          </div>
   2.575 +        </div>
   2.576 +      </div>
   2.577 +    </div>
   2.578 +
   2.579 +</body>
   2.580 +</html>
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/app/main/lf2/_area.lua	Wed Mar 02 20:06:26 2011 +0100
     3.3 @@ -0,0 +1,75 @@
     3.4 +local area = param.get("area", "table")
     3.5 +
     3.6 +local membership = Membership:by_pk(area.id, app.session.member_id)
     3.7 +
     3.8 +local trustees = Member:new_selector()
     3.9 +  :add_field("delegation_chain.*")
    3.10 +  :join("delegation_chain(" .. app.session.member_id .. ", " .. area.id .. ", NULL)", "delegation_chain", "member.id = delegation_chain.member_id")
    3.11 +  :add_order_by("index")
    3.12 +  :exec()
    3.13 +
    3.14 +ui.box{ class = "area", content = function()
    3.15 +
    3.16 +  ui.box_row{ class = "head", content = function()
    3.17 +    ui.box_col{ class = "left name", content = area.name } 
    3.18 +    ui.box_col{ class = "right", content = _("#{direct_count}+#{delegated_count} Mitglieder", {
    3.19 +      direct_count = area.direct_member_count,
    3.20 +      delegated_count = area.member_weight - area.direct_member_count 
    3.21 +    } ) }
    3.22 +  end }
    3.23 +
    3.24 +  if area.description and #area.description > 0 then
    3.25 +    ui.box_row{ class = "description", content = function() ui.box_col{ content = area.description } end }
    3.26 +  end
    3.27 +  
    3.28 +  ui.box_row{ class = "member_count", content = function()
    3.29 +  end }
    3.30 +
    3.31 +  ui.box_row{ content = function()
    3.32 +    ui.box_col{ class = "left", content = function()
    3.33 +      execute.view{ module = "lf2", view = "_avatars", params = { members = trustees, arrows = true, size = "small" } }
    3.34 +    end }
    3.35 +    ui.box_col{ class = "right", content = function()
    3.36 +      ui.tag{ content = _"[Change] or [revoke] area delegation [prefix]" }
    3.37 +      ui.link{ text = _"[Change] or [revoke] area delegation [change]" }
    3.38 +      ui.tag{ content = _"[Change] or [revoke] area delegation [midpart]" }
    3.39 +      ui.link{ text = _"[Change] or [revoke] area delegation [revoke]" }
    3.40 +      ui.tag{ content = _"[Change] or [revoke] area delegation [suffix]" }
    3.41 +    end }
    3.42 +  end }
    3.43 +
    3.44 +  ui.box_row{ content = function()
    3.45 +    ui.box_col{ class = "left", content = function()
    3.46 +      if membership then
    3.47 +        ui.image{ static = "lf2/icon_star.png" }
    3.48 +        slot.put(" ", _"You are member of this area")
    3.49 +      else
    3.50 +        ui.link{
    3.51 +          module  = "membership", action = "update", params = { area_id = area.id },
    3.52 +          routing = { default = {
    3.53 +            mode = "redirect", module = "lf2", view = "area", id = area.id
    3.54 +          } },
    3.55 +          text = _"Become a member of this area"
    3.56 +        }
    3.57 +      end
    3.58 +    end }
    3.59 +    ui.box_col{ class = "right", content = function()
    3.60 +      if membership then
    3.61 +        ui.link{
    3.62 +          module  = "membership", action  = "update", params = { area_id = area.id, delete = true },
    3.63 +          routing = { default = {
    3.64 +            mode = "redirect", module = "lf2", view = "area", id = area.id
    3.65 +          } },
    3.66 +          text = _"Give up membership"
    3.67 +        }
    3.68 +      end
    3.69 +      if not trustees then
    3.70 +        if membership then
    3.71 +          slot.put(" &middot; ")
    3.72 +        end
    3.73 +        ui.link{ text = _"Delegate area...", module = "lf2", view = "delegation" }
    3.74 +      end
    3.75 +    end }
    3.76 +  end }
    3.77 +
    3.78 +end }
    3.79 \ No newline at end of file
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/app/main/lf2/_areas.lua	Wed Mar 02 20:06:26 2011 +0100
     4.3 @@ -0,0 +1,29 @@
     4.4 +local areas = param.get("areas_selector", "table"):exec()
     4.5 +local head_content = param.get("head_content", "function")
     4.6 +
     4.7 +ui.box{ class = "areas", row_count = #areas, content = function()
     4.8 +  if head_content then
     4.9 +    ui.box_row{ class = "head", content = function() ui.box_col{ content = head_content } end }
    4.10 +  end
    4.11 +
    4.12 +  for i, area in ipairs(areas) do
    4.13 +    local delegation = Delegation:by_pk(app.session.member_id, area.id)
    4.14 +    
    4.15 +    ui.box_row{ 
    4.16 +      class = "area", 
    4.17 +      toggle_content = function() 
    4.18 +        ui.image{ static = "lf2/icon_search_crossed.png" } 
    4.19 +      end,
    4.20 +      content = function()
    4.21 +        ui.box_col{ class = "name", content = function()
    4.22 +          if delegation then
    4.23 +            execute.view{ module = "lf2", view = "_avatars", params = { members = { delegation.trustee }, size = "small" } }
    4.24 +          end
    4.25 +          ui.link{ module = "lf2", view = "area", id = area.id, text = area.name }
    4.26 +        end }
    4.27 +      end
    4.28 +    }
    4.29 +    
    4.30 +  end
    4.31 +
    4.32 +end }
    4.33 \ No newline at end of file
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/app/main/lf2/_avatars.lua	Wed Mar 02 20:06:26 2011 +0100
     5.3 @@ -0,0 +1,51 @@
     5.4 +local members = param.get("members", "table")
     5.5 +local hidefirst = param.get("hidefirst", atom.boolean)
     5.6 +local size = param.get("size") or "normal"
     5.7 +
     5.8 +local first_participation = true
     5.9 +
    5.10 +ui.container{ attr = { class = "avatars " .. size }, content = function()
    5.11 +  for i, member in ipairs(members) do
    5.12 +    local class = "arrow"
    5.13 +    if member.overridden then
    5.14 +      class = class .. " overridden"
    5.15 +    end
    5.16 +    local image
    5.17 +    local text
    5.18 +    if member.scope_in == "global" then
    5.19 +      image = "lf2/icon_delegation_global.png"
    5.20 +      text = _"Global delegation"
    5.21 +    elseif member.scope_in == "area" then
    5.22 +      image = "lf2/icon_delegation_area.png"
    5.23 +      text = _"Area delegation"
    5.24 +    elseif member.scope_in == "issue" then
    5.25 +      image = "lf2/icon_delegation.png"
    5.26 +      text = _"Issue delegation"
    5.27 +    end
    5.28 +    if param.get("arrows", atom.boolean) and (i > 1 or #members == 1) then
    5.29 +      ui.image{ attr = { title = text, alt = text, class = class }, static = image }
    5.30 +      slot.put(member.scope)
    5.31 +    end
    5.32 +    if not hidefirst or i > 1 then
    5.33 +      local class = "avatar"
    5.34 +      if first_participation and member.participation then
    5.35 +        class = class .. " participation"
    5.36 +        first_participation = false
    5.37 +      end
    5.38 +      if member.overridden then
    5.39 +        class = class .. " overridden"
    5.40 +      end
    5.41 +      ui.container{ attr = { class = class, title = member.name }, content = function()
    5.42 +        ui.avatar(member, size)
    5.43 +        --ui.image{ module = "member_image", view = "show", id = member.id, params = { image_type = "avatar" } }
    5.44 +        if size == "normal" then
    5.45 +          ui.container{ attr = { class = "name" }, content = member.name }
    5.46 +        end
    5.47 +        if size == "small" and member.weight ~= nil then
    5.48 +          ui.container{ attr = { class = "weight" }, content = member.weight }
    5.49 +        end
    5.50 +      end }
    5.51 +    end
    5.52 +  end
    5.53 +end }
    5.54 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/app/main/lf2/_delegation_global.lua	Wed Mar 02 20:06:26 2011 +0100
     6.3 @@ -0,0 +1,23 @@
     6.4 +local trustees = Member:new_selector()
     6.5 +  :add_field("delegation_chain.*")
     6.6 +  :join("delegation_chain(" .. tostring(app.session.member.id) .. ", NULL, NULL)", "delegation_chain", "member.id = delegation_chain.member_id")
     6.7 +  :add_order_by("index")
     6.8 +  :exec()
     6.9 +
    6.10 +ui.box{ content = function()
    6.11 +  ui.box_row{ class = "head", content = function()
    6.12 +    ui.box_col{ content = _"Global delegation active" }
    6.13 +  end }
    6.14 +  ui.box_row{ content = function() ui.box_col{ content = function()
    6.15 +      execute.view{ module = "lf2", view = "_avatars", params = { members = trustees, arrows = true, size = "small" } }
    6.16 +  end } end }
    6.17 +  ui.box_row{ content = function() ui.box_col{ content = function()
    6.18 +    ui.tag{ content = _"[Change] or [revoke] global delegation [prefix]" }
    6.19 +    ui.link{ text = _"[Change] or [revoke] global delegation [change]" }
    6.20 +    ui.tag{ content = _"[Change] or [revoke] global delegation [midpart]" }
    6.21 +    ui.link{ text = _"[Change] or [revoke] global delegation [revoke]" }
    6.22 +    ui.tag{ content = _"[Change] or [revoke] global delegation [suffix]" }
    6.23 +    
    6.24 +  end } end }
    6.25 +end }
    6.26 +    
    6.27 \ No newline at end of file
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/app/main/lf2/_draft.lua	Wed Mar 02 20:06:26 2011 +0100
     7.3 @@ -0,0 +1,5 @@
     7.4 +local draft = param.get("draft", "table")
     7.5 +
     7.6 +ui.container{ attr = { class = "draft" }, content = function() 
     7.7 +  slot.put(format.wiki_text(draft.content, draft.formatting_engine)) 
     7.8 +end }
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/app/main/lf2/_filter_view/10_topnav.lua	Wed Mar 02 20:06:26 2011 +0100
     8.3 @@ -0,0 +1,44 @@
     8.4 +local state = param.get("state")
     8.5 +local order = param.get("order")
     8.6 +
     8.7 +slot.select("topnav", function()
     8.8 +
     8.9 +  ui.link{
    8.10 +    attr = { class = state == "closed" and "active" or nil },
    8.11 +    text = _"Closed", module = "lf2", view = "index", params = { state = "closed", order = order } 
    8.12 +  }
    8.13 +  ui.link{ 
    8.14 +    attr = { class = state == "voting" and "active" or nil },
    8.15 +    text = _"Voting", module = "lf2", view = "index", params = { state = "voting", order = order } 
    8.16 +  }
    8.17 +  ui.link{ 
    8.18 +    attr = { class = state == "frozen" and "active" or nil },
    8.19 +    text = _"Frozen", module = "lf2", view = "index", params = { state = "frozen", order = order } 
    8.20 +  }
    8.21 +  ui.link{
    8.22 +    attr = { class = state == "discussion" and "active" or nil },
    8.23 +    text = _"Discussion", module = "lf2", view = "index", params = { state = "discussion", order = order }
    8.24 +  }
    8.25 +  ui.link{
    8.26 +    attr = { class = state == "new" and "active" or nil },
    8.27 +    text = _"New", module = "lf2", view = "index", params = { state = "new", order = order } 
    8.28 +  }
    8.29 +
    8.30 +  ui.container{ attr = { class = "right" }, content = function()
    8.31 +    ui.link{
    8.32 +      attr = { class = order == "last_change" and "active" or nil },
    8.33 +      text = _"Last change", module = "lf2", view = "index", params = { order = "last_change", state = state }
    8.34 +    }
    8.35 +    ui.link{ 
    8.36 +      attr = { class = order == "time_left" and "active" or nil },
    8.37 +      text = _"Time left", module = "lf2", view = "index", params = { order = "time_left", state = state }
    8.38 +    }
    8.39 +    ui.link{
    8.40 +      attr = { class = order == "interest" and "active" or nil },
    8.41 +      text = _"Interest", module = "lf2", view = "index", params = { order = "interest", state = state }
    8.42 +    }
    8.43 +  end }
    8.44 +
    8.45 +end)
    8.46 +
    8.47 +execute.inner()
    8.48 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/app/main/lf2/_initiative.lua	Wed Mar 02 20:06:26 2011 +0100
     9.3 @@ -0,0 +1,95 @@
     9.4 +local initiative = param.get("initiative", "table")
     9.5 +
     9.6 +ui.container{ attr = { class = "bar" }, content = function()
     9.7 +  if initiative.issue.fully_frozen and initiative.issue.closed then
     9.8 +    if initiative.issue.ranks_available then 
     9.9 +      if initiative.negative_votes and initiative.positive_votes then
    9.10 +        local max_value = initiative.issue.voter_count
    9.11 +        ui.bargraph{
    9.12 +          max_value = max_value,
    9.13 +          width = 100,
    9.14 +          bars = {
    9.15 +            { color = "#0a0", value = initiative.positive_votes },
    9.16 +            { color = "#aaa", value = max_value - initiative.negative_votes - initiative.positive_votes },
    9.17 +            { color = "#a00", value = initiative.negative_votes },
    9.18 +          }
    9.19 +        }
    9.20 +      else
    9.21 +        slot.put("&nbsp;")
    9.22 +      end
    9.23 +    else
    9.24 +      slot.put(_"Counting of votes")
    9.25 +    end
    9.26 +  elseif initiative.issue.population then
    9.27 +    local max_value = initiative.issue.population
    9.28 +    ui.bargraph{
    9.29 +      max_value = max_value,
    9.30 +      width = 100,
    9.31 +      quorum = max_value * (initiative.issue.policy.initiative_quorum_num / initiative.issue.policy.initiative_quorum_den),
    9.32 +      quorum_color = "#00F",
    9.33 +      bars = {
    9.34 +        { color = "#0a0", value = (initiative.satisfied_supporter_count or 0) },
    9.35 +        { color = "#bbb", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) },
    9.36 +        { color = "#eee", value = max_value - (initiative.supporter_count or 0) },
    9.37 +      }
    9.38 +    }
    9.39 +  else
    9.40 +    slot.put("&nbsp;")
    9.41 +  end
    9.42 +end }
    9.43 +
    9.44 +if initiative.issue.fully_frozen and not initiative.issue.closed then
    9.45 +  if not initiative.admitted then
    9.46 +    ui.image{ attr = { title = _"Initiative not admitted" }, static = "lf2/icon_cross.png" }
    9.47 +    slot.put(" ")
    9.48 +  end
    9.49 +end
    9.50 +
    9.51 +if initiative.issue.closed then
    9.52 +  if initiative.issue.accepted then
    9.53 +    if initiative.admitted then
    9.54 +      if initiative.agreed then
    9.55 +        if initiative.rank == 1 then
    9.56 +          ui.image{ static = "lf2/icon_award_gold.png" }
    9.57 +        else
    9.58 +          ui.image{ static = "lf2/icon_award_silver.png" }
    9.59 +        end
    9.60 +        slot.put(" ")
    9.61 +        ui.tag{ content = initiative.rank }
    9.62 +      else
    9.63 +      ui.image{ attr = { title = _"Initiative not agreed" }, static = "lf2/icon_cross.png" }
    9.64 +      end
    9.65 +    else
    9.66 +      ui.image{ attr = { title = _"Initiative not admitted" }, static = "lf2/icon_cross.png" }
    9.67 +    end
    9.68 +  else
    9.69 +   ui.image{ attr = { title = _"Issue not accepted" }, static = "lf2/icon_cross.png" }
    9.70 +  end
    9.71 +  slot.put(" ")
    9.72 +end
    9.73 +
    9.74 +ui.link{ 
    9.75 +  module = "lf2", view = "initiative", id = initiative.id,
    9.76 +  params = { tab = "draft" }, attr = { class = "name" }, 
    9.77 +  text = initiative.name
    9.78 +}
    9.79 +
    9.80 +ui.container{ attr = { class = "authors" }, content = function()
    9.81 +  local members = initiative.initiating_members
    9.82 +  slot.put(_"by", " ")
    9.83 +  for i, member in ipairs(members) do
    9.84 +    if i > 1 and i < #members then
    9.85 +      slot.put(", ")
    9.86 +    elseif i > 1 then
    9.87 +      slot.put(" ", _"and", " ")
    9.88 +    end
    9.89 +    ui.link{
    9.90 +      module = "lf2", view = "initiative", id = initiative.id,
    9.91 +      params = { member_id = member.id }, content = function()
    9.92 +        ui.tag{ content = member.name }
    9.93 +      end
    9.94 +    }
    9.95 +  end
    9.96 +end }
    9.97 +  
    9.98 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/app/main/lf2/_initiatives.lua	Wed Mar 02 20:06:26 2011 +0100
    10.3 @@ -0,0 +1,13 @@
    10.4 +local initiatives = param.get("initiatives", "table")
    10.5 +
    10.6 +initiatives:load("initiating_members", nil, "initiating_members")
    10.7 +
    10.8 +ui.box{ content = function()
    10.9 +  for i, initiative in ipairs(initiatives) do
   10.10 +
   10.11 +    ui.box_row{ class = "initiative", content = function() ui.box_col { content = function()
   10.12 +      execute.view{ module = "lf2", view = "_initiative", params = { initiative = initiative } }
   10.13 +    end } end }
   10.14 +
   10.15 +  end
   10.16 +end }
   10.17 \ No newline at end of file
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/app/main/lf2/_interested.lua	Wed Mar 02 20:06:26 2011 +0100
    11.3 @@ -0,0 +1,12 @@
    11.4 +local interested_members = param.get("interested_members", "table")
    11.5 +ui.box{ content = function()
    11.6 +  ui.box_row{ class = "head interested", content = function()
    11.7 +    ui.box_col{ class = "", content = _"Interested members" }
    11.8 +  end }
    11.9 +  ui.box_row{ class = "interested", content = function()
   11.10 +    ui.box_col{ content = _"The interested members are updated after some time." }
   11.11 +    ui.box_col{ class = "", content = function()
   11.12 +      execute.view{ module = "lf2", view = "_avatars", params = { members = interested_members } }
   11.13 +    end }
   11.14 +  end }
   11.15 +end }
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/app/main/lf2/_issue_initiatives.lua	Wed Mar 02 20:06:26 2011 +0100
    12.3 @@ -0,0 +1,72 @@
    12.4 +local initiatives = param.get("initiatives", "table")
    12.5 +
    12.6 +for i, initiative in ipairs(initiatives) do
    12.7 +
    12.8 +  local first = ""
    12.9 +  if i == 1 then first = " first" end
   12.10 +  
   12.11 +  ui.box_row{ class = "initiative" .. first, content = function() ui.box_col { content = function()
   12.12 +
   12.13 +    ui.link{ 
   12.14 +      module = "lf2", view = "initiative", id = initiative.id,
   12.15 +      params = { tab = "draft" }, attr = { class = "name" }, 
   12.16 +      text = initiative.name
   12.17 +    }
   12.18 +
   12.19 +    ui.container{ attr = { class = "bar" }, content = function()
   12.20 +      if initiative.issue.fully_frozen and initiative.issue.closed then
   12.21 +        if initiative.issue.ranks_available then 
   12.22 +          if initiative.negative_votes and initiative.positive_votes then
   12.23 +            local max_value = initiative.issue.voter_count
   12.24 +            ui.bargraph{
   12.25 +              max_value = max_value,
   12.26 +              width = 100,
   12.27 +              bars = {
   12.28 +                { color = "#0a0", value = initiative.positive_votes },
   12.29 +                { color = "#aaa", value = max_value - initiative.negative_votes - initiative.positive_votes },
   12.30 +                { color = "#a00", value = initiative.negative_votes },
   12.31 +              }
   12.32 +            }
   12.33 +          else
   12.34 +            slot.put("&nbsp;")
   12.35 +          end
   12.36 +        else
   12.37 +          slot.put(_"Counting of votes")
   12.38 +        end
   12.39 +      elseif initiative.issue.population then
   12.40 +        local max_value = initiative.issue.population
   12.41 +        ui.bargraph{
   12.42 +          max_value = max_value,
   12.43 +          width = 100,
   12.44 +          quorum = max_value * (initiative.issue.policy.initiative_quorum_num / initiative.issue.policy.initiative_quorum_den),
   12.45 +          quorum_color = "#00F",
   12.46 +          bars = {
   12.47 +            { color = "#0a0", value = (initiative.satisfied_supporter_count or 0) },
   12.48 +            { color = "#bbb", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) },
   12.49 +            { color = "#eee", value = max_value - (initiative.supporter_count or 0) },
   12.50 +          }
   12.51 +        }
   12.52 +      else
   12.53 +        slot.put("&nbsp;")
   12.54 +      end
   12.55 +    end }
   12.56 +
   12.57 +    ui.container{ attr = { class = "authors" }, content = function()
   12.58 +      local members = initiative.initiating_members
   12.59 +      slot.put(_"by", " ")
   12.60 +      for i, member in ipairs(members) do
   12.61 +        if i > 1 and i < #members then
   12.62 +          slot.put(", ")
   12.63 +        elseif i > 1 then
   12.64 +          slot.put(" ", _"and", " ")
   12.65 +        end
   12.66 +        ui.link{
   12.67 +          module = "lf2", view = "initiative", id = initiative.id,
   12.68 +          params = { member_id = member.id }, text = member.name
   12.69 +        }
   12.70 +      end
   12.71 +    end }
   12.72 +
   12.73 +  end } end }
   12.74 +
   12.75 +end
   12.76 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/app/main/lf2/_issues.lua	Wed Mar 02 20:06:26 2011 +0100
    13.3 @@ -0,0 +1,114 @@
    13.4 +local issues = param.get("issues", "table")
    13.5 +
    13.6 +for i, issue in ipairs(issues) do
    13.7 +  local initiatives = issue.initiatives
    13.8 +
    13.9 +  local interested_members = issue.interested_members
   13.10 +
   13.11 +  -- prepare interest of current user
   13.12 +  local interest = issue.interest
   13.13 +
   13.14 +  -- prepare trustees
   13.15 +  local trustees = Member:new_selector()
   13.16 +    :add_field("delegation_chain.*")
   13.17 +    :join("delegation_chain(" .. tostring(app.session.member.id) .. ", NULL, " .. tostring(issue.id or "NULL") .. ")", "delegation_chain", "member.id = delegation_chain.member_id")
   13.18 +    :add_order_by("index")
   13.19 +    :exec()
   13.20 +    
   13.21 +  local global_delegation
   13.22 +  local area_delegation
   13.23 +  local issue_delegation
   13.24 +
   13.25 +  for i, delegation in ipairs(issue.outgoing_delegations) do
   13.26 +    if delegation.scope == "global" then global_delegation = delegation
   13.27 +    elseif delegation.scope == "area" then area_delegation = delegation
   13.28 +    elseif delegation.scope == "issue" then issue_delegation = delegation
   13.29 +    end
   13.30 +  end
   13.31 +
   13.32 +  local delegation = issue_delegation or area_delegation or global_delegation
   13.33 +
   13.34 +  local delegating_interest = issue.delegating_interest
   13.35 +
   13.36 +  ui.box{ class = "issue", content = function()
   13.37 +
   13.38 +    ui.box_row{ class = "head", content = function()
   13.39 +
   13.40 +      ui.box_col{ class = "issue_id left", content = function()
   13.41 +        ui.link{
   13.42 +          module = "lf2", view = "issue", id = issue.id,
   13.43 +          content = _("Issue ##{id}", { id = issue.id })
   13.44 +        }
   13.45 +      end }
   13.46 +    
   13.47 +      ui.box_col{ class = "unit_name right", content = function()
   13.48 +        ui.link{ 
   13.49 +          module = "lf2", view = "unit", id = 1,
   13.50 +          content = "Dummy unit name" 
   13.51 +        }
   13.52 +      end }
   13.53 +      ui.box_col{ class = "area_name right clearright", content = function()
   13.54 +        ui.link{
   13.55 +          module = "lf2", view = "area_name", id = issue.area_id,
   13.56 +          content = issue.area.name
   13.57 +        }
   13.58 +      end }
   13.59 +      ui.box_col{ class = "policy_name left clearleft first", content = function()
   13.60 +        ui.link{
   13.61 +          module = "lf2", view = "policy", id = issue.policy_id,
   13.62 +          content = issue.policy.name
   13.63 +        }
   13.64 +      end }
   13.65 +
   13.66 +    end }
   13.67 +
   13.68 +    ui.box_row{ class = "head2", content = function()
   13.69 +
   13.70 +      ui.box_col{ class = "state_name left", content = function()
   13.71 +        ui.tag{ content = issue.state_name }
   13.72 +        slot.put(" &middot; ")
   13.73 +        ui.tag{ content = issue.closed and _("since #{date}", { date = format.date(issue.closed.date) }) or _("#{time_left} left", { time_left =  issue.state_time_left }) }
   13.74 +      end }
   13.75 +    end }
   13.76 +    
   13.77 +    if interest or delegation then
   13.78 +      ui.box_row{ class = "head2", content = function()
   13.79 +        ui.box_col{ class = "interest left", content = function()
   13.80 +          if interest then
   13.81 +            ui.image{ static = "lf2/icon_star.png" }
   13.82 +            if issue.closed then
   13.83 +              slot.put(" ", _"You were interested in this issue")
   13.84 +            else
   13.85 +              slot.put(" ", _"You are interested in this issue")
   13.86 +            end
   13.87 +          elseif delegating_interest then
   13.88 +            ui.image{ static = "lf2/icon_delegated_star.png" }
   13.89 +            if issue.closed then
   13.90 +              slot.put(" ", _"You were interested in this issue by delegation")
   13.91 +            else
   13.92 +              slot.put(" ", _"You are interested in this issue by delegation")
   13.93 +            end
   13.94 +          elseif trustees then
   13.95 +            slot.put(_"You have delegated this issue")
   13.96 +          else
   13.97 +            slot.put(_"You are not interested in this issue")
   13.98 +          end
   13.99 +        end } 
  13.100 +        -- TODO if delegation ist falsch
  13.101 +        if delegation then
  13.102 +          slot.put(tostring(delegation.id))
  13.103 +          ui.box_col{ class = "delegation right", content = function()
  13.104 +            execute.view{ module = "lf2", view = "_avatars", params = { members = trustees, arrows = true, size = "small" } }
  13.105 +          end }
  13.106 +        end
  13.107 +      end }
  13.108 +    end
  13.109 +    
  13.110 +    for i, initiative in ipairs(issue.initiatives) do
  13.111 +      ui.box_row{ class = "initiative", content = function() ui.box_col { content = function()
  13.112 +        execute.view{ module = "lf2", view = "_initiative", params = { initiative = initiative } }
  13.113 +      end } end }
  13.114 +    end
  13.115 +    
  13.116 +  end }
  13.117 +end
  13.118 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/app/main/lf2/_issues_issue.lua	Wed Mar 02 20:06:26 2011 +0100
    14.3 @@ -0,0 +1,77 @@
    14.4 +local issue = param.get("issue", "table")
    14.5 +local hide = param.get("hide", "table") or {}
    14.6 +
    14.7 +local interest = issue.interest
    14.8 +
    14.9 +local delegations = issue.delegations
   14.10 +
   14.11 +local global_delegation
   14.12 +local area_delegation
   14.13 +local issue_delegation
   14.14 +
   14.15 +for i, delegation in ipairs(issue.delegations) do
   14.16 +  if delegation.scope == "global" then global_delegation = delegation
   14.17 +  elseif delegation.scope == "area" then area_delegation = delegation
   14.18 +  elseif delegation.scope == "issue" then issue_delegation = delegation
   14.19 +  end
   14.20 +end
   14.21 +
   14.22 +local delegation = issue_delegation or area_delegation or global_delegation
   14.23 +
   14.24 +local delegating_interest = issue.delegating_interest
   14.25 +
   14.26 +ui.box{ class = "issue", content = function()
   14.27 +
   14.28 +  ui.box_row{ class = "issue_id", content = function() ui.box_col{ content = function()
   14.29 +    ui.link{
   14.30 +      module = "lf2", view = "issue", id = issue.id,
   14.31 +      content = _("Issue ##{id}", { id = issue.id })
   14.32 +    }
   14.33 +  end } end }
   14.34 +
   14.35 +  if not hide.unit then
   14.36 +    ui.box_row{ class = "unit_name", content = function() ui.box_col{ content = function()
   14.37 +      ui.link{ 
   14.38 +        module = "lf2", view = "unit", id = 1,
   14.39 +        content = "DE / Berlin / Friedrichshain-Kreuzberg" 
   14.40 +      }
   14.41 +    end } end }
   14.42 +  end
   14.43 +
   14.44 +  if not hide.area then
   14.45 +    ui.box_row{ class = "area_name", content = function() ui.box_col{ content = function()
   14.46 +      ui.link{
   14.47 +        module = "lf2", view = "area", id = issue.area_id,
   14.48 +        content = issue.area.name
   14.49 +      }
   14.50 +    end } end }
   14.51 +  end
   14.52 +  
   14.53 +
   14.54 +  ui.box_row{ class = "interest", content = function()
   14.55 +    if interest then
   14.56 +      ui.container{ attr = { title = _"You are interested in this issue" }, content = function() 
   14.57 +        ui.image{ static = "lf2/icon_star.png" }
   14.58 +      end  }
   14.59 +    elseif delegating_interest then
   14.60 +      ui.container{ attr = { class = "interest", title = _"You are interested in this issue by delegation" }, content = function() 
   14.61 +        ui.image{ static = "lf2/icon_delegated_star.png" }
   14.62 +        slot.put(delegating_interest.trustee_member_id)
   14.63 +      end  }
   14.64 +    else
   14.65 +    end
   14.66 +  end }
   14.67 +
   14.68 +  ui.box_row{ class = "delegation", content = function()
   14.69 +    if delegation then
   14.70 +      ui.box_col{ content = function() 
   14.71 +        execute.view{ module = "lf2", view = "_avatars", params = { members = { app.session.member, delegation.trustee }, arrows = true, hidefirst = true } }
   14.72 +      end }
   14.73 +    else
   14.74 +    end
   14.75 +  end }
   14.76 +
   14.77 +end }
   14.78 +  
   14.79 +ui.box_col{ class = "time_left", content = issue.closed and _("Closed since #{date}", { date = format.date(issue.closed.date) }) or _("#{time_left} left", { time_left =  issue.state_time_left }) }
   14.80 +
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/app/main/lf2/_search.lua	Wed Mar 02 20:06:26 2011 +0100
    15.3 @@ -0,0 +1,35 @@
    15.4 +ui.container{
    15.5 +  attr = { class = "boxhead" },
    15.6 +  content = _"Search in initiatives for text:"
    15.7 +}
    15.8 +
    15.9 +ui.container{
   15.10 +  attr = { class = "search box" },
   15.11 +  content = function()
   15.12 +    ui.container{
   15.13 +      attr = { class = "row first" },
   15.14 +      content = function()
   15.15 +        ui.container{
   15.16 +          attr = { class = "col first" },
   15.17 +          content = function()
   15.18 +
   15.19 +            ui.form{
   15.20 +              content = function()
   15.21 +
   15.22 +                
   15.23 +                slot.put(" ")
   15.24 +              
   15.25 +                ui.tag{ tag = "input", attr = { type = "text", name = "q" } }
   15.26 +                
   15.27 +                ui.submit{ text = _"Search" }
   15.28 +
   15.29 +              end
   15.30 +            }
   15.31 +
   15.32 +          end
   15.33 +        }
   15.34 +
   15.35 +      end
   15.36 +    }
   15.37 +  end
   15.38 +}
   15.39 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/app/main/lf2/_sidebar.lua	Wed Mar 02 20:06:26 2011 +0100
    16.3 @@ -0,0 +1,36 @@
    16.4 +local member_areas_selector = Area:build_selector{
    16.5 +  member_id = app.session.member_id,
    16.6 +  order = "name"
    16.7 +}
    16.8 +local other_areas_selector = Area:build_selector{
    16.9 +  not_member_id = app.session.member_id,
   16.10 +  order = "name"
   16.11 +}
   16.12 +
   16.13 +execute.view{ module = "lf2", view = "_delegation_global" }
   16.14 +    
   16.15 +ui.form{
   16.16 +  content = function()
   16.17 +    
   16.18 +    ui.container{ attr = { class = "boxhead" }, content = _"" }
   16.19 +    --execute.view{ module = "lf2", view = "_areas", params = { areas_selector = member_areas_selector } }
   16.20 +    
   16.21 +    execute.view{
   16.22 +      module = "lf2", view = "_areas", params = { 
   16.23 +        areas_selector = member_areas_selector,
   16.24 +        head_content = function() ui.tag{ content = _"Areas, you are member of" } end
   16.25 +      }
   16.26 +    }
   16.27 +
   16.28 +    execute.view{
   16.29 +      module = "lf2", view = "_areas", params = { 
   16.30 +        areas_selector = other_areas_selector,
   16.31 +        head_content = function() ui.tag{ content = _"Areas, you are not member of" } end
   16.32 +      }
   16.33 +    }
   16.34 +
   16.35 +  end
   16.36 +}
   16.37 +
   16.38 +execute.view{ module = "lf2", view = "_search", params = { area = area } }
   16.39 +    
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/app/main/lf2/_sidebar_drafts.lua	Wed Mar 02 20:06:26 2011 +0100
    17.3 @@ -0,0 +1,55 @@
    17.4 +local initiative = param.get("initiative", "table")
    17.5 +
    17.6 +local drafts = Draft:new_selector()
    17.7 +  :add_where{ "draft.initiative_id = ?", initiative.id }
    17.8 +  :add_order_by("id DESC")
    17.9 +  :exec()
   17.10 +
   17.11 +ui.container{ attr = { class = "boxhead" }, content = _"Draft revisions" }
   17.12 +
   17.13 +ui.box{ class = "drafts", content = function()
   17.14 +  if drafts then
   17.15 +    ui.form{
   17.16 +      method = "get",
   17.17 +      module = "draft",
   17.18 +      view = "diff",
   17.19 +      content = function()
   17.20 +        ui.box_row{ class = "", content = function()
   17.21 +          ui.box_col{ class = "scrolled", content = function()
   17.22 +
   17.23 +            for i, draft in ipairs(drafts) do
   17.24 +              ui.box_row{ class = "draft", content = function()
   17.25 +                ui.box_col{ class = "left", content = function()
   17.26 +                  ui.link{
   17.27 +                    attr = { class = "created" },
   17.28 +                    text = format.timestamp(draft.created),
   17.29 +                    module = "draft",
   17.30 +                    view = "show",
   17.31 +                    id = draft.id
   17.32 +                  }
   17.33 +                  slot.put("<br />")
   17.34 +                  ui.tag{ content = _"by" }
   17.35 +                  slot.put(" ")
   17.36 +                  ui.link{
   17.37 +                    attr = { class = "author_name" },
   17.38 +                    module = "lf2", view = "issue", id = initiative.issue_id,
   17.39 +                    params = { member_id = author_id },
   17.40 +                    text = draft.author.name
   17.41 +                  }
   17.42 +                end } 
   17.43 +                ui.box_col{ class = "right", content = function()
   17.44 +                  slot.put('<input type="radio" name="old_draft_id" value="' .. tostring(draft.id) .. '">')
   17.45 +                  slot.put('<input type="radio" name="new_draft_id" value="' .. tostring(draft.id) .. '">')
   17.46 +                end }
   17.47 +              end }
   17.48 +            end
   17.49 +          end } end }
   17.50 +
   17.51 +          ui.box_row{ content = function() ui.box_col{ class = "right", content = function()
   17.52 +          ui.submit{ text = _"Compare selected" }
   17.53 +        end } end }
   17.54 +      end
   17.55 +    }
   17.56 +  else
   17.57 +  end
   17.58 +end }
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/app/main/lf2/_sidebar_initiatives.lua	Wed Mar 02 20:06:26 2011 +0100
    18.3 @@ -0,0 +1,9 @@
    18.4 +local initiatives = param.get("initiatives", "table")
    18.5 +ui.box{ content = function()
    18.6 +  ui.box_row{ class = "initiatives", content = function()
    18.7 +    ui.box_col{ class = "scrolled", content = function()
    18.8 +      execute.view{ module = "lf2", view = "_issue_initiatives", params = { initiatives = initiatives } }
    18.9 +    end }
   18.10 +  end }
   18.11 +end }
   18.12 +
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/app/main/lf2/_sidebar_issue.lua	Wed Mar 02 20:06:26 2011 +0100
    19.3 @@ -0,0 +1,177 @@
    19.4 +local issue = param.get("issue", "table")
    19.5 +
    19.6 +local initiatives = issue.initiatives
    19.7 +
    19.8 +local interested_members_selector = Member:new_selector()
    19.9 +  :join("direct_interest_snapshot", "dis", { "dis.issue_id = ? AND dis.member_id = member.id and dis.event = (select latest_snapshot_event from issue where id = ?)", issue.id, issue.id })
   19.10 +  :add_field("dis.weight", "weight")
   19.11 +  :add_order_by("dis.weight DESC")
   19.12 +local interested_members = interested_members_selector:exec()
   19.13 +
   19.14 +local interest = issue.interest
   19.15 +
   19.16 +local delegations = issue.delegations
   19.17 +
   19.18 +local trustees = Member:new_selector()
   19.19 +  :add_field("delegation_chain.*")
   19.20 +  :join("delegation_chain(" .. tostring(app.session.member.id) .. ", NULL, " .. tostring(issue.id or "NULL") .. ")", "delegation_chain", "member.id = delegation_chain.member_id")
   19.21 +  :add_order_by("index")
   19.22 +  :exec()
   19.23 +
   19.24 +local global_delegation
   19.25 +local area_delegation
   19.26 +local issue_delegation
   19.27 +
   19.28 +for i, delegation in ipairs(issue.delegations) do
   19.29 +  if delegation.scope == "global" then global_delegation = delegation
   19.30 +  elseif delegation.scope == "area" then area_delegation = delegation
   19.31 +  elseif delegation.scope == "issue" then issue_delegation = delegation
   19.32 +  end
   19.33 +end
   19.34 +
   19.35 +local delegation = issue_delegation or area_delegation or global_delegation
   19.36 +
   19.37 +local delegating_interest = issue.delegating_interest
   19.38 +
   19.39 +ui.box{ class = "issue", content = function()
   19.40 +
   19.41 +  ui.box_row{ class = "issue_id head", content = function() ui.box_col{ content = function()
   19.42 +    ui.link{
   19.43 +      module = "lf2", view = "issue", id = issue.id,
   19.44 +      content = _("Issue ##{id}", { id = issue.id })
   19.45 +    }
   19.46 +  end } end }
   19.47 +
   19.48 +  ui.box_row{ class = "unit_name", content = function() ui.box_col{ content = function()
   19.49 +    ui.link{ 
   19.50 +      module = "lf2", view = "unit", id = 1,
   19.51 +      content = "DE / Berlin / Friedrichshain-Kreuzberg" 
   19.52 +    }
   19.53 +  end } end }
   19.54 +
   19.55 +  ui.box_row{ class = "area_name", content = function() ui.box_col{ content = function()
   19.56 +    ui.link{
   19.57 +      module = "lf2", view = "area", id = issue.area_id,
   19.58 +      content = issue.area.name
   19.59 +    }
   19.60 +  end } end }
   19.61 +  
   19.62 +  ui.box_row{ class = "policy_name", content = function() ui.box_col{ content = function()
   19.63 +    ui.link{
   19.64 +      module = "lf2", view = "policy", id = issue.policy_id,
   19.65 +      content = issue.policy.name
   19.66 +    }
   19.67 +  end } end }
   19.68 +
   19.69 +  ui.box_row{ class = "time_left", content = function()
   19.70 +    ui.box_col{ content = issue.closed and _("Closed since #{date}", { date = format.date(issue.closed.date) }) or _("#{time_left} left", { time_left =  issue.state_time_left }) }
   19.71 +  end }
   19.72 +  
   19.73 +  ui.box_row{ class = "interest hoverbutton_container", content = function() ui.box_col{ content = function()
   19.74 +    if interest then
   19.75 +      ui.image{ static = "lf2/icon_star.png" }
   19.76 +      if issue.closed then
   19.77 +        slot.put(" ", _"You were interested in this issue")
   19.78 +      else
   19.79 +        slot.put(" ", _"You are interested in this issue")
   19.80 +      end
   19.81 +    else
   19.82 +      ui.image{ static = "lf2/icon_star_grey.png" }
   19.83 +      slot.put(_"You are not interested in this issue")
   19.84 +    end
   19.85 +    
   19.86 +    if issue.closed then
   19.87 +      ui.container{ attr = { class = "hoverbutton noaction"}, content = function()
   19.88 +        ui.container{ attr = { class = "content"}, content = function()
   19.89 +          slot.put(" ", encode.html(_"This issue is closed"))
   19.90 +        end }
   19.91 +      end }
   19.92 +    elseif issue.fully_frozen then
   19.93 +      ui.container{ attr = { class = "hoverbutton noaction"}, content = function()
   19.94 +        ui.container{ attr = { class = "content"}, content = function()
   19.95 +          slot.put(" ", encode.html(_"This issue is in voting"))
   19.96 +        end }
   19.97 +      end }
   19.98 +    else
   19.99 +      if interest then
  19.100 +        ui.link{
  19.101 +          module = "interest", action = "update", params = { issue_id = issue.id, delete = true },
  19.102 +          routing = { default = {
  19.103 +            mode = "redirect", module = "lf2", view = "issue", id = issue.id
  19.104 +          } },
  19.105 +          attr = { class = "hoverbutton red"},
  19.106 +          content = function()
  19.107 +            ui.container{ attr = { class = "content"}, content = function()
  19.108 +              ui.image{ static = "lf2/icon_star_crossed.png" }
  19.109 +              slot.put(" ", encode.html(_"Remove my interest"))
  19.110 +            end }
  19.111 +          end 
  19.112 +        }
  19.113 +        
  19.114 +      else
  19.115 +        ui.link{
  19.116 +          module = "interest", action = "update", params = { issue_id = issue.id },
  19.117 +          routing = { default = {
  19.118 +            mode = "redirect", module = "lf2", view = "issue", id = issue.id
  19.119 +          } },
  19.120 +          attr = { class = "hoverbutton green"},
  19.121 +          content = function()
  19.122 +            ui.container{ attr = { class = "content"}, content = function()
  19.123 +              ui.image{ static = "lf2/icon_star.png" }
  19.124 +              slot.put(" ", encode.html(_"Add my interest"))
  19.125 +            end 
  19.126 +          }
  19.127 +        end }
  19.128 +        
  19.129 +      end
  19.130 +    end
  19.131 +  end } end }
  19.132 +
  19.133 +  ui.box_row{ class = "delegation hoverbutton_container", content = function() ui.box_col{ content = function()
  19.134 +    if delegation then
  19.135 +      if delegation.issue_id then
  19.136 +        slot.put(encode.html(_"You have delegated this issue"))
  19.137 +      elseif delegation.area_id then
  19.138 +        slot.put(encode.html(_"You have delegated this area"))
  19.139 +      elseif delegation then
  19.140 +        slot.put(encode.html(_"You have delegated globally"))
  19.141 +      end
  19.142 +    else
  19.143 +      slot.put(encode.html(_"No delegation active"))
  19.144 +    end
  19.145 +
  19.146 +    if issue.closed then
  19.147 +      ui.container{ attr = { class = "hoverbutton noaction"}, content = function()
  19.148 +        ui.container{ attr = { class = "content"}, content = function()
  19.149 +          slot.put(" ", encode.html(_"This issue is closed"))
  19.150 +        end }
  19.151 +      end }
  19.152 +    else
  19.153 +      if delegation then
  19.154 +        ui.link{ attr = { class = "hoverbutton red"}, content = function()
  19.155 +          ui.container{ attr = { class = "content"}, content = function()
  19.156 +            ui.image{ static = "lf2/icon_delegation.png" }
  19.157 +            slot.put(" ", encode.html(_"Change delegation..."))
  19.158 +          end }
  19.159 +        end }
  19.160 +        
  19.161 +      else
  19.162 +        ui.link{ attr = { class = "hoverbutton green"}, content = function()
  19.163 +          ui.container{ attr = { class = "content"}, content = function()
  19.164 +            ui.image{ static = "lf2/icon_delegation.png" }
  19.165 +            slot.put(" ", encode.html(_"Delegate issue"))
  19.166 +          end }
  19.167 +        end }
  19.168 +        
  19.169 +      end
  19.170 +    end
  19.171 +    
  19.172 +  end } end }
  19.173 +    
  19.174 +  if delegation then
  19.175 +    ui.box_row{ class = "delegation", content = function() ui.box_col{ content = function()
  19.176 +      execute.view{ module = "lf2", view = "_avatars", params = { members = trustees, arrows = true, size = "small" } }
  19.177 +    end } end }
  19.178 +  end
  19.179 +
  19.180 +end }
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/app/main/lf2/area.lua	Wed Mar 02 20:06:26 2011 +0100
    20.3 @@ -0,0 +1,24 @@
    20.4 +local area = Area:by_id(param.get_id())
    20.5 +
    20.6 +slot.set_layout("lf2")
    20.7 +
    20.8 +slot.select("sidebar", function()
    20.9 +  execute.view{ module = "lf2", view = "_sidebar" }
   20.10 +end)
   20.11 +
   20.12 +execute.view{ module = "lf2", view = "_area", params = { area = area } }
   20.13 +
   20.14 +
   20.15 +local issues_selector = Issue:build_selector{
   20.16 +  area_id = area.id,
   20.17 +  state = param.get("state"),
   20.18 +  order = param.get("order")
   20.19 +}:limit(25)
   20.20 +
   20.21 +local issues = issues_selector:exec()
   20.22 +
   20.23 +issues:load("delegating_interest_snapshot_for_member", { member_id = app.session.member_id }, "delegating_interest")
   20.24 +issues:load("interest_for_member", { member_id = app.session.member_id }, "interest")
   20.25 +issues:load("outgoing_delegations_for_member", { member_id = app.session.member_id }, "outgoing_delegations")
   20.26 +
   20.27 +execute.view{ module = "lf2", view = "_issues", params = { issues = issues } }
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/app/main/lf2/area_notification.lua	Wed Mar 02 20:06:26 2011 +0100
    21.3 @@ -0,0 +1,11 @@
    21.4 +local area = Area:by_id(param.get_id())
    21.5 +
    21.6 +slot.set_layout("lf2")
    21.7 +
    21.8 +ui.box{
    21.9 +  ui.box_row{ content = function() ui.box_col{ content = function()
   21.10 +
   21.11 +    
   21.12 +
   21.13 +  end } end }
   21.14 +}
   21.15 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/app/main/lf2/index.lua	Wed Mar 02 20:06:26 2011 +0100
    22.3 @@ -0,0 +1,18 @@
    22.4 +slot.set_layout("lf2")
    22.5 +
    22.6 +slot.select("sidebar", function()
    22.7 +  execute.view{ module = "lf2", view = "_sidebar" }
    22.8 +end)
    22.9 +
   22.10 +local issues_selector = Issue:build_selector{
   22.11 +  state = param.get("state"),
   22.12 +  order = param.get("order")
   22.13 +}:limit(25)
   22.14 +
   22.15 +local issues = issues_selector:exec()
   22.16 +
   22.17 +issues:load("delegating_interest_snapshot_for_member", { member_id = app.session.member_id }, "delegating_interest")
   22.18 +issues:load("interest_for_member", { member_id = app.session.member_id }, "interest")
   22.19 +issues:load("outgoing_delegations_for_member", { member_id = app.session.member_id }, "outgoing_delegations")
   22.20 +
   22.21 +execute.view{ module = "lf2", view = "_issues", params = { issues = issues } }
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/app/main/lf2/initiative.lua	Wed Mar 02 20:06:26 2011 +0100
    23.3 @@ -0,0 +1,92 @@
    23.4 +slot.set_layout("lf2")
    23.5 +
    23.6 +local initiative = Initiative:by_id(param.get_id())
    23.7 +
    23.8 +local issue = initiative.issue
    23.9 +
   23.10 +local supporting_members_selector = Member:new_selector()
   23.11 +  :join("direct_supporter_snapshot", "dss", { "dss.issue_id = ? AND dss.initiative_id = ? AND dss.member_id = member.id and dss.event = (select latest_snapshot_event from issue where id = ?)", issue.id, initiative.id, issue.id })
   23.12 +  :join("direct_interest_snapshot", "dis", { "dis.issue_id = ? AND dis.member_id = member.id and dis.event = (select latest_snapshot_event from issue where id = ?)", issue.id, issue.id })
   23.13 +  :add_field("dis.weight", "weight")
   23.14 +  :add_order_by("dis.weight DESC")
   23.15 +local supporting_members = supporting_members_selector:exec()
   23.16 +
   23.17 +local voting_members_selector = Member:new_selector()
   23.18 +  :join("direct_voter", nil, { "direct_voter.issue_id = ? AND direct_voter.member_id = member.id", issue.id })
   23.19 +  :add_field("direct_voter.weight", "weight")
   23.20 +  :add_order_by("direct_voter.weight DESC")
   23.21 +local voting_members = voting_members_selector:exec()
   23.22 +
   23.23 +local alternative_initiatives = initiative.issue.initiatives
   23.24 +alternative_initiatives:load("initiating_members", nil, "initiating_members")
   23.25 +
   23.26 +
   23.27 +slot.select("sidebar", function()
   23.28 +  
   23.29 +  execute.view{ module = "lf2", view = "_sidebar_issue", params = { issue = issue } }
   23.30 +  ui.container{ attr = { class = "boxhead" }, content = _"Alternative initiatives" }
   23.31 +  
   23.32 +  execute.view{ module = "lf2", view = "_sidebar_initiatives", params = {
   23.33 +    initiatives = alternative_initiatives
   23.34 +  } }
   23.35 +  
   23.36 +  execute.view{ module = "lf2", view = "_sidebar_drafts", params = {
   23.37 +    initiative = initiative
   23.38 +  } }
   23.39 +
   23.40 +end)
   23.41 +
   23.42 +local draft = initiative.current_draft
   23.43 +
   23.44 +ui.box{
   23.45 +  content = function()
   23.46 +
   23.47 +    ui.box_row{ class = "initiative head", content = function() ui.box_col { content = function()
   23.48 +      execute.view{ module = "lf2", view = "_initiative", params = { initiative = initiative } }
   23.49 +    end } end }
   23.50 +    
   23.51 +    ui.box_row{ class = "head2", content = function() ui.box_col{ content = function()
   23.52 +      if initiative.issue.fully_frozen and initiative.issue.closed then
   23.53 +        ui.link{ external = "#votes", text = _("#{vote_count} votes", { vote_count = #voting_members }) }
   23.54 +        slot.put(" &middot; ")
   23.55 +      end
   23.56 +      ui.link{ external = "#suggestions", text = _("#{suggestion_count} suggestions", { suggestion_count = 23 })  }
   23.57 +      slot.put(" &middot; ")
   23.58 +      ui.link{ external = "#supporters", text = _("#{supporter_count} supporters", { supporter_count = #supporting_members }) }
   23.59 +    end } end }
   23.60 +
   23.61 +    ui.box_row{ content = function() ui.box_col{ content = function()
   23.62 +      execute.view{ module = "lf2", view = "_draft", params = { draft = draft } }
   23.63 +    end } end }
   23.64 +  end
   23.65 +}
   23.66 +
   23.67 +if initiative.issue.fully_frozen and initiative.issue.closed then
   23.68 +  ui.boxhead{ name = "votes", content = _"Votes" }
   23.69 +  ui.box{
   23.70 +    content = function()
   23.71 +      ui.box_row{ content = function() ui.box_col{ content = function()
   23.72 +        execute.view{ module = "lf2", view = "_avatars", params = { members = voting_members } }
   23.73 +      end } end }
   23.74 +    end
   23.75 +  }
   23.76 +end
   23.77 +
   23.78 +ui.boxhead{ name = "suggestions", content = _"Suggestions" }
   23.79 +ui.box{
   23.80 +  content = function()
   23.81 +    ui.box_row{ content = function() ui.box_col{ content = function()
   23.82 +      slot.put("suggestions")
   23.83 +    end } end }
   23.84 +  end
   23.85 +}
   23.86 +    
   23.87 +ui.boxhead{ name = "supporters", content = _"Supporters" }
   23.88 +ui.box{
   23.89 +  content = function()
   23.90 +    ui.box_row{ content = function() ui.box_col{ content = function()
   23.91 +      execute.view{ module = "lf2", view = "_avatars", params = { members = supporting_members } }
   23.92 +    end } end }
   23.93 +  end
   23.94 +}
   23.95 +    
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/app/main/lf2/issue.lua	Wed Mar 02 20:06:26 2011 +0100
    24.3 @@ -0,0 +1,56 @@
    24.4 +slot.set_layout("lf2")
    24.5 +
    24.6 +
    24.7 +local issue = Issue:by_id(param.get_id())
    24.8 +local area = issue.area
    24.9 +
   24.10 +-- TODO broken
   24.11 +--issue:load("interested_members_snapshot", {}, "interested_members")
   24.12 +issue:load("delegating_interest_snapshot_for_member", { member_id = app.session.member_id }, "delegating_interest")
   24.13 +issue:load("interest_for_member", { member_id = app.session.member_id }, "interest")
   24.14 +issue:load("outgoing_delegations_for_member", { member_id = app.session.member_id }, "outgoing_delegations")
   24.15 +
   24.16 +local initiatives = issue.initiatives
   24.17 +
   24.18 +local interested_members = issue.interested_members
   24.19 +
   24.20 +local interest = issue.interest
   24.21 +
   24.22 +local delegations = issue.delegations
   24.23 +
   24.24 +local trustees = Member:new_selector()
   24.25 +  :add_field("delegation_chain.*")
   24.26 +  :join("delegation_chain(" .. tostring(app.session.member.id) .. ", " .. tostring(area_id or "NULL") .. ", " .. tostring(issue_id or "NULL") .. ")", "delegation_chain", "member.id = delegation_chain.member_id")
   24.27 +  :add_order_by("index")
   24.28 +  :exec()
   24.29 +        
   24.30 +local global_delegation
   24.31 +local area_delegation
   24.32 +local issue_delegation
   24.33 +
   24.34 +for i, delegation in ipairs(issue.delegations) do
   24.35 +  if delegation.scope == "global" then global_delegation = delegation
   24.36 +  elseif delegation.scope == "area" then area_delegation = delegation
   24.37 +  elseif delegation.scope == "issue" then issue_delegation = delegation
   24.38 +  end
   24.39 +end
   24.40 +
   24.41 +local delegation = issue_delegation or area_delegation or global_delegation
   24.42 +
   24.43 +local delegating_interest = issue.delegating_interest
   24.44 +
   24.45 +slot.select("sidebar", function()
   24.46 +  execute.view{ module = "lf2", view = "_sidebar" }
   24.47 +end)
   24.48 +
   24.49 +execute.view{ module = "lf2", view = "_area", params = { area = area } }
   24.50 +
   24.51 +execute.view{ module = "lf2", view = "_issues", params = { issues = { issue } } }
   24.52 +
   24.53 +-- TODO bugfix for not working reference loader
   24.54 +interested_members = issue:get_reference_selector("interested_members_snapshot"):exec()
   24.55 +
   24.56 +execute.view{ module = "lf2", view = "_interested", params = {
   24.57 +  interested_members = interested_members
   24.58 +} }
   24.59 +
    25.1 --- a/config/development.lua	Sat Feb 05 20:01:09 2011 +0100
    25.2 +++ b/config/development.lua	Wed Mar 02 20:06:26 2011 +0100
    25.3 @@ -3,7 +3,7 @@
    25.4  execute.config("default")
    25.5  
    25.6  config.formatting_engine_executeables = {
    25.7 -  rocketwiki= "/opt/rocketwiki/rocketwiki-lqfb",
    25.8 +  rocketwiki= "/opt/rocketwiki/rocketwiki-lqfb.sh",
    25.9    compat = "/opt/rocketwiki/rocketwiki-lqfb-compat"
   25.10  }
   25.11  
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/env/ui/avatar.lua	Wed Mar 02 20:06:26 2011 +0100
    26.3 @@ -0,0 +1,66 @@
    26.4 +local alphabet = {
    26.5 +  "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
    26.6 +  "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
    26.7 +  "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
    26.8 +  "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
    26.9 +  "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"
   26.10 +}
   26.11 +
   26.12 +local function encode_base64(str)
   26.13 +  local parts = {}
   26.14 +  local pos = 1
   26.15 +  local block_count = 0
   26.16 +  while pos <= #str do
   26.17 +    local s = string.sub(str, pos, pos + 2)
   26.18 +    local n = 0
   26.19 +    for i = 1, 3 do
   26.20 +      n = n * 256
   26.21 +      if i <= #s then
   26.22 +        n = n + string.byte(string.sub(s, i, i))
   26.23 +      end
   26.24 +    end
   26.25 +    parts[#parts+1] = alphabet[math.floor(n / 262144) + 1]
   26.26 +    parts[#parts+1] = alphabet[math.floor(n / 4096) % 64 + 1]
   26.27 +    if #s > 1 then
   26.28 +      parts[#parts+1] = alphabet[math.floor(n / 64) % 64 + 1]
   26.29 +    else
   26.30 +      parts[#parts+1] = "="
   26.31 +    end
   26.32 +    if #s > 2 then
   26.33 +      parts[#parts+1] = alphabet[n % 64 + 1]
   26.34 +    else
   26.35 +      parts[#parts+1] = "="
   26.36 +    end
   26.37 +    block_count = block_count + 1
   26.38 +    if block_count == 19 then
   26.39 +      --parts[#parts+1] = "\r\n"
   26.40 +      block_count = 0
   26.41 +    end
   26.42 +    pos = pos + #s
   26.43 +  end
   26.44 +  if block_count > 0 then
   26.45 +    --parts[#parts+1] = "\r\n"
   26.46 +  end
   26.47 +  return table.concat(parts)
   26.48 +end
   26.49 +
   26.50 +function ui.avatar(member, size)
   26.51 +  local base64_string
   26.52 +  
   26.53 +  if member.avatar_base64 then
   26.54 +    base64_string = member.avatar_base64
   26.55 +  else
   26.56 +    local member_image = MemberImage:by_pk(member.id, "avatar", true)
   26.57 +    if member_image then
   26.58 +      base64_string = encode_base64(member_image.data)
   26.59 +    else
   26.60 +      base64_string = "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAAwADABAREA/8QAGQABAAMBAQAAAAAAAAAAAAAAAAMGBwQC/8QAIxAAAgICAgEEAwAAAAAAAAAAAQIAAwQRBTEGEiEyYTVRcf/aAAgBAQAAPwDf4kN2TRjjd1ip/TFOTRkDdNiv/DJoiR3WCml7D0o3M55DOtzsp7HYkb9h+hHH51uDlJYjEDfuP2Jo1NgupSwdMNySJzcgC3H3gd+gzNCNMR9wBtgPuaXx4K8fQD36BOmJ5ZQ6FT0RozNeQrWrPuRegx1HH1rbn0o3RYbmlKoRAo6A0J6kGXlV4eM99vxXuVrK8uJBXHp19tKxZY1trWN8mOzFdjVWrYvyU7Es+L5cQAuRTv7WWXEyq8zGS+r4t1ODyP8AC3SgRES/+OfhaZ//2Q=="
   26.61 +    end
   26.62 +    member.avatar_base64 = base64_string
   26.63 +    member:save()
   26.64 +  end
   26.65 +
   26.66 +  ui.tag{ tag = "img", attr = { src = "data:image/jpeg;base64," .. base64_string } }
   26.67 +  
   26.68 +end
   26.69 +
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/env/ui/box.lua	Wed Mar 02 20:06:26 2011 +0100
    27.3 @@ -0,0 +1,7 @@
    27.4 +function ui.box(args)
    27.5 +  app.ui_box_row = 1
    27.6 +  app.ui_box_row_count = args.row_count
    27.7 +  local class = "box"
    27.8 +  if args.class then class = class .. " " .. args.class end
    27.9 +  ui.container{ attr = { class = class }, content = args.content }
   27.10 +end
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/env/ui/box_col.lua	Wed Mar 02 20:06:26 2011 +0100
    28.3 @@ -0,0 +1,7 @@
    28.4 +function ui.box_col(args)
    28.5 +  local class = "col"
    28.6 +  if args.class then class = class .. " " .. args.class end
    28.7 +  if app.ui_box_col == 1 then class = class .. " first" end
    28.8 +  ui.container{ attr = { class = class }, content = args.content }
    28.9 +  app.ui_box_col = app.ui_box_col + 1
   28.10 +end
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/env/ui/box_row.lua	Wed Mar 02 20:06:26 2011 +0100
    29.3 @@ -0,0 +1,25 @@
    29.4 +function ui.box_row(args)
    29.5 +  app.ui_box_col = 1
    29.6 +  local class = "row"
    29.7 +  if args.class then class = class .. " " .. args.class end
    29.8 +  if app.ui_box_row == 1 then class = class .. " first" end
    29.9 +  if app.ui_box_row == app.ui_box_row_count then class = class .. " last" end
   29.10 +  if args.toggle_content then class = class .. " toggled" end
   29.11 +  ui.container{ attr = { class = class }, content = function()
   29.12 +    if args.toggle_content then
   29.13 +      ui.container{ attr = { class = "col toggle"}, content = function()
   29.14 +        if type(args.toggle_content) == "function" then
   29.15 +          args.toggle_content()
   29.16 +        else
   29.17 +          slot.put(encode.html(args.toggle_content))
   29.18 +        end
   29.19 +      end }
   29.20 +    end
   29.21 +    if type(args.content) == "function" then
   29.22 +      args.content()
   29.23 +    else
   29.24 +      slot.put(encode.html(args.content))
   29.25 +    end
   29.26 +  end }
   29.27 +  app.ui_box_row = app.ui_box_row + 1
   29.28 +end
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/env/ui/boxhead.lua	Wed Mar 02 20:06:26 2011 +0100
    30.3 @@ -0,0 +1,5 @@
    30.4 +function ui.boxhead(args)
    30.5 +  local class = "boxhead"
    30.6 +  if args.class then class = class .. " " .. args.class end
    30.7 +  ui.tag{ tag = "a", attr = { class = class, name = args.name }, content = args.content }
    30.8 +end
    31.1 --- a/locale/translations.de.lua	Sat Feb 05 20:01:09 2011 +0100
    31.2 +++ b/locale/translations.de.lua	Wed Mar 02 20:06:26 2011 +0100
    31.3 @@ -3,14 +3,20 @@
    31.4  ["##{id}"] = "##{id}";
    31.5  ["##{issue_id}.#{id} #{name}"] = "##{issue_id}.#{id} #{name}";
    31.6  ["#{author} at #{date}"] = "#{author} am #{date}";
    31.7 +["#{direct_count}+#{delegated_count} Mitglieder"] = false;
    31.8  ["#{interested_issues_to_vote_count} issue(s) you are interested in"] = "#{interested_issues_to_vote_count} Themen, die Dich interessieren";
    31.9  ["#{issues_to_vote_count} issue(s)"] = "#{issues_to_vote_count} Themen";
   31.10  ["#{number} Image(s) has been deleted"] = "Es wurde(n) #{number} Bild(er) gelöscht";
   31.11  ["#{number} Image(s) has been updated"] = "Es wurde(n) #{number} Bild(er) aktualisiert";
   31.12 +["#{suggestion_count} suggestions"] = "#{suggestion_count} Anregungen";
   31.13 +["#{supporter_count} supporters"] = "#{supporter_count} Unterstützer";
   31.14 +["#{time_left} left"] = "noch #{time_left}";
   31.15 +["#{vote_count} votes"] = "#{vote_count} Stimmzettel";
   31.16  ["(#{more_count} duplicates removed)"] = "(#{more_count} Duplikate entfernt)";
   31.17  ["(change URL)"] = "(URL ändern)";
   31.18  ["(new window)"] = "(neues Fenster)";
   31.19  ["+ #{weight}"] = "+ #{weight}";
   31.20 +["+getElementById("] = false;
   31.21  ["A-Z"] = "A-Z";
   31.22  ["API key"] = "API-Schlüssel";
   31.23  ["API key has been deleted"] = "API-Schlüssel wurde gelöscht";
   31.24 @@ -62,6 +68,8 @@
   31.25  ["Area list"] = "Liste der Themenbereiche";
   31.26  ["Area successfully updated"] = "Themenbereich erfolgreich aktualisiert";
   31.27  ["Areas"] = "Themenbereiche";
   31.28 +["Areas, you are member of"] = false;
   31.29 +["Areas, you are not member of"] = "Nicht Mitglied in:";
   31.30  ["Author"] = "Autor";
   31.31  ["Auto support is now disabled"] = false;
   31.32  ["Auto support is now enabled"] = false;
   31.33 @@ -77,6 +85,7 @@
   31.34  ["Back to timeline"] = "Zurück zur Zeitachse";
   31.35  ["Ballot of '#{member_name}' for issue ##{issue_id}"] = "Stimmzettel von '#{member_name}' für Thema ##{issue_id}";
   31.36  ["Become a member"] = "Mitglied werden";
   31.37 +["Become a member of this area"] = "Dem Themenbereich beitreten";
   31.38  ["Birthday"] = "Geburtstag";
   31.39  ["Can't remove last initiator"] = "Der letzte Initiator kann nicht entfernt werden";
   31.40  ["Can't send confirmation email"] = "Bestätigungs-E-Mail kann nicht versendet werden.";
   31.41 @@ -87,6 +96,7 @@
   31.42  ["Cancelled"] = "Abgebrochen";
   31.43  ["Change API key"] = "API-Schlüssel ändern";
   31.44  ["Change area delegation"] = "Delegation für Themenbereich ändern";
   31.45 +["Change delegation..."] = "Delegation ändern...";
   31.46  ["Change display settings"] = "Anzeige-Einstellungen ändern";
   31.47  ["Change email"] = "E-Mail-Adresse ändern";
   31.48  ["Change email address"] = "E-Mail-Adresse ändern";
   31.49 @@ -106,9 +116,11 @@
   31.50  ["Choose member"] = "Mitglied auswählen";
   31.51  ["Click for details"] = "Klicke für Details";
   31.52  ["Closed"] = "geschlossen";
   31.53 +["Closed since #{date}"] = "Geschlossen seit #{date}";
   31.54  ["Collective opinion of supporters"] = "Meinungsbild der Unterstützer";
   31.55  ["Commit suggestion"] = "Anregung speichern";
   31.56  ["Compare"] = "Vergleichen";
   31.57 +["Compare selected"] = "Vergleiche ausgewählte";
   31.58  ["Confirm"] = "Bestätigen";
   31.59  ["Confirmation code"] = "Bestätigungscode";
   31.60  ["Confirmation code invalid!"] = "Bestätigungscode ist ungültig!";
   31.61 @@ -133,6 +145,8 @@
   31.62  ["Date format is not valid. Please use following format: YYYY-MM-DD"] = "Datumsformat nicht korrekt. Bitte verwende: JJJJ-MM-TT, also z.B. 1945-05-23";
   31.63  ["Default Policy"] = "Standard-Regelwerk";
   31.64  ["Degree"] = "Grad";
   31.65 +["Delegate area..."] = "Themengebiet delegieren...";
   31.66 +["Delegate issue"] = "Thema delegieren";
   31.67  ["Delegation abandoned"] = "Delegation ausgesetzt";
   31.68  ["Delegation problems"] = "Delegationsprobleme";
   31.69  ["Delegation turned off for area"] = "Delegation für Themengebiet ausgesetzt";
   31.70 @@ -166,6 +180,7 @@
   31.71  ["Download database export"] = "Datenbankexport herunterladen";
   31.72  ["Draft"] = "Entwurf";
   31.73  ["Draft history"] = "Entwurfshistorie";
   31.74 +["Draft revisions"] = "Entwurfsversionen";
   31.75  ["EXPERIMENTAL FEATURE"] = "EXPERIMENTELLE FUNKTION";
   31.76  ["Edit"] = "Bearbeiten";
   31.77  ["Edit draft"] = "Entwurf bearbeiten";
   31.78 @@ -193,6 +208,7 @@
   31.79  ["Fully frozen at"] = "Ganz eingefroren am/um";
   31.80  ["Generate / change API key"] = "API-Schlüssel erzeugen/ändern";
   31.81  ["Generate API key"] = "API-Schlüssel erzeugen";
   31.82 +["Give up membership"] = "Mitgliedschaft aufgeben";
   31.83  ["Global delegation"] = "Globale Delegation";
   31.84  ["Global delegation active"] = "Globale Delegation aktiv";
   31.85  ["Go up"] = "Nach oben";
   31.86 @@ -222,6 +238,8 @@
   31.87  ["Initiative ##{id}"] = "Initiative ##{id}";
   31.88  ["Initiative events"] = "Initiativen-Ereignisse";
   31.89  ["Initiative is revoked now"] = "Initiative ist jetzt zurückgezogen";
   31.90 +["Initiative not admitted"] = "Initiative nicht zugelassen";
   31.91 +["Initiative not agreed"] = "Initiative abgelehnt";
   31.92  ["Initiative quorum"] = "Quorum Inititive";
   31.93  ["Initiative quorum denumerator"] = "Initiativ-Quorum Zähler";
   31.94  ["Initiative quorum numerator"] = "Initiativ-Quorum Nenner";
   31.95 @@ -239,6 +257,7 @@
   31.96  ["Initiator"] = "Initiator";
   31.97  ["Initiator invites"] = "Einladungen";
   31.98  ["Initiators"] = "Initiatoren";
   31.99 +["Interest"] = "Interesse";
  31.100  ["Interest not existant"] = "Interesse existiert nicht";
  31.101  ["Interest removed"] = "Interesse entfernt";
  31.102  ["Interest updated"] = "Interesse aktualisiert";
  31.103 @@ -263,6 +282,7 @@
  31.104  ["Issue finished"] = "Thema abgeschlossen";
  31.105  ["Issue finished without voting"] = "Thema ohne Abstimmung abgeschlossen";
  31.106  ["Issue frozen"] = "Thema eingefroren";
  31.107 +["Issue not accepted"] = "Thema nicht zugelassen";
  31.108  ["Issue policy"] = "Regelwerk für Thema";
  31.109  ["Issue quorum"] = "Quorum Thema";
  31.110  ["Issue quorum denumerator"] = "Themen-Quorum Zähler";
  31.111 @@ -270,6 +290,8 @@
  31.112  ["Issues"] = "Themen";
  31.113  ["JavaScript is disabled or not available."] = "JavaScript ist abgeschaltet oder nicht verfügbar.";
  31.114  ["Last author"] = "Letzter Autor";
  31.115 +["Last change"] = "Letzte Änderung";
  31.116 +["Last login (updated daily)"] = "Letzte Anmeldung (täglich aktualisiert)";
  31.117  ["Last snapshot:"] = "Letzte Auszählung:";
  31.118  ["Legend:"] = "Legende:";
  31.119  ["License"] = "Lizenz";
  31.120 @@ -336,6 +358,7 @@
  31.121  ["No changes to your images were made"] = "An Deinen Bildern wurde nichts geändert";
  31.122  ["No default"] = "Kein Standard";
  31.123  ["No delegation"] = "Keine Delegation";
  31.124 +["No delegation active"] = "Keine Delegation aktiv";
  31.125  ["No events selected to list"] = "Keine Ereignisse ausgewählt";
  31.126  ["No membership at all"] = "Gar keine Mitgliedschaft";
  31.127  ["No support at all"] = "Gar keine Unterstützung";
  31.128 @@ -442,6 +465,7 @@
  31.129  ["Saved as contact"] = "Als Kontakt gespeichert";
  31.130  ["Saved contacts"] = "Gespeicherte Kontakte";
  31.131  ["Search"] = "Suchen";
  31.132 +["Search in initiatives for text:"] = "In Initiative nach Text suchen:";
  31.133  ["Search initiatives"] = "Suche Initiativen";
  31.134  ["Search issues"] = "Suche Themen";
  31.135  ["Search members"] = "Suche Mitglieder";
  31.136 @@ -507,6 +531,7 @@
  31.137  ["Supported"] = "Unterstützt";
  31.138  ["Supported initiatives"] = "Unterstützte Initiativen";
  31.139  ["Supporter"] = "Unterstützer";
  31.140 +["Supporters"] = "Unterstützer";
  31.141  ["Syntax help"] = "Syntax-Hilfe";
  31.142  ["Tabs"] = "Registerkarten";
  31.143  ["Terms of use"] = "Nutzungsbedingungen";
  31.144 @@ -515,6 +540,7 @@
  31.145  ["The draft of this initiative has been updated!"] = "Der Entwurfstext der Initiative wurde aktualisiert!";
  31.146  ["The drafts do not differ"] = "Die Entwürfe unterscheiden sich nicht";
  31.147  ["The initiators suggest to support the following initiative:"] = "Die Initiatoren empfehlen folgende Initiative zu unterstützen:";
  31.148 +["The interested members are updated after some time."] = false;
  31.149  ["There are no more alternative initiatives currently."] = "Es gibt zur Zeit keine weiteren alternative Initiative.";
  31.150  ["There were no more alternative initiatives."] = "Es gab keine weiteren alternativen Initiativen.";
  31.151  ["This email address is too short!"] = "Diese E-Mail-Adresse ist zu kurz!";
  31.152 @@ -530,6 +556,8 @@
  31.153  ["This issue has been finished without any winning initiative."] = "Das Thema wurde ohne Gewinner abgeschlossen.";
  31.154  ["This issue is already closed."] = "Das Thema ist schon geschlossen.";
  31.155  ["This issue is already frozen."] = "Das Thema ist schon eingefroren";
  31.156 +["This issue is closed"] = "Thema geschlossen";
  31.157 +["This issue is in voting"] = "Thema in Abstimmung";
  31.158  ["This login is already taken, please choose another one!"] = "Dieser Anmeldename ist bereits vergeben, bitte wähle einen anderen!";
  31.159  ["This login is too short!"] = "Dieser Anmeldename ist zu kurz!";
  31.160  ["This member account has been created at #{created}"] = "Dieser Mitgliedszugang wurde am/um #{created} angelegt.";
  31.161 @@ -570,6 +598,7 @@
  31.162  ["Voted no"] = "Mit Nein gestimmt";
  31.163  ["Voted proposal"] = "Abgestimmte Vorlage";
  31.164  ["Voted yes"] = "Mit Ja gestimmt";
  31.165 +["Votes"] = "Stimmzettel";
  31.166  ["Voting"] = "Abstimmung";
  31.167  ["Voting details"] = "Abstimmdetails";
  31.168  ["Voting for this issue has already begun."] = "Die Abstimmung für dieses Thema hat schon begonnen.";
  31.169 @@ -591,9 +620,12 @@
  31.170  ["You are currently not invited to any initiative."] = "Du bist zur Zeit von keiner Initiative eingeladen.";
  31.171  ["You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter."] = "Du bist zur Zeit kein direkter Unterstützer dieser Initiative. Wenn Du eine Anregung hinzufügst wirst Du automatisch potentieller Unterstützer!";
  31.172  ["You are iniator of this initiative"] = "Du bist Initiator dieser Initiative";
  31.173 -["You are interested in this issue"] = "Du bist an diesem Thema interessiert";
  31.174 +["You are interested in this issue"] = "Du bist am Thema interessiert";
  31.175 +["You are interested in this issue by delegation"] = "Du bist am Thema durch Delegation interessiert";
  31.176  ["You are invited to become initiator of this initiative."] = "Du bist eingeladen Initiator dieser Initiative zu werden.";
  31.177  ["You are member"] = "Du bist Mitglied";
  31.178 +["You are member of this area"] = "Du bist Mitglied des Themenbereichs";
  31.179 +["You are not interested in this issue"] = "Du bist nicht am Thema interessiert";
  31.180  ["You are now initiator of this initiative"] = "Du bist jetzt Initiator dieser Initiative";
  31.181  ["You are potential supporter of this initiative"] = "Du bist potentieller Unterstützer dieser Initiative";
  31.182  ["You are supporting this initiative"] = "Du unterstützt diese Initiative";
  31.183 @@ -603,11 +635,16 @@
  31.184  ["You didn't confirmed your email address '#{email}' within 7 days."] = "Du hast die E-Mail-Adresse '#{email}' nicht innerhalb von 7 Tagen bestätigt.";
  31.185  ["You didn't confirmed your email address '#{email}'. You have received an email with an activation link."] = "Du hast die E-Mail-Adresse '#{email}' nicht bestätigt. Du hast hierzu eine E-Mail mit einem Aktivierungslink erhalten.";
  31.186  ["You didn't saved any member as contact yet."] = "Du hast noch kein Mitglied als Kontakt gespeichert!";
  31.187 +["You have delegated globally"] = "Du hast global delegiert";
  31.188 +["You have delegated this area"] = "Du hast das Themengebiet delegiert";
  31.189 +["You have delegated this issue"] = "Du hast das Thema delegiert";
  31.190  ["You have saved this member as contact"] = "Du hast das Mitglied als Kontakt gespeichert";
  31.191  ["You have saved this member as contact."] = "Du hast das Mitglied als Kontakt gespeichert.";
  31.192  ["You have to mark 'Are you sure' to revoke!"] = "Zum Zurückziehen musst Du 'Sicher?' auswählen";
  31.193  ["You need to be logged in, to use all features of this system."] = "Du musst eingeloggt sein, um alle Funktionen dieses Systems nutzen zu können.";
  31.194  ["You want to vote later"] = "Du willst später abstimmen";
  31.195 +["You were interested in this issue"] = "Du warst am Thema interessiert";
  31.196 +["You were interested in this issue by delegation"] = "Du warst am Thema durch Delegation interessiert";
  31.197  ["You've successfully registered and you can login now with your login and password!"] = "Du hast Dich erfolgreich registriert und kannst Dich jetzt mit Deinen Benutzernamen und Kennwort anmelden!";
  31.198  ["Your API key:"] = "Dein API-Schlüssel:";
  31.199  ["Your are interested"] = "Du bist interessiert";
  31.200 @@ -636,13 +673,25 @@
  31.201  ["Your vote has been discarded. Delegation rules apply if set."] = "Deine Abstimmung wurde zurückgezogen. Delegationsregeln gelten sofern gesetzt.";
  31.202  ["Your web browser is not fully supported yet."] = "Dein Web-Browser wird noch nicht vollständig unterstützt.";
  31.203  ["Z-A"] = "Z-A";
  31.204 +["[Change] or [revoke] area delegation [change]"] = false;
  31.205 +["[Change] or [revoke] area delegation [midpart]"] = false;
  31.206 +["[Change] or [revoke] area delegation [prefix]"] = false;
  31.207 +["[Change] or [revoke] area delegation [revoke]"] = false;
  31.208 +["[Change] or [revoke] area delegation [suffix]"] = false;
  31.209 +["[Change] or [revoke] global delegation [change]"] = false;
  31.210 +["[Change] or [revoke] global delegation [midpart]"] = false;
  31.211 +["[Change] or [revoke] global delegation [prefix]"] = false;
  31.212 +["[Change] or [revoke] global delegation [revoke]"] = false;
  31.213 +["[Change] or [revoke] global delegation [suffix]"] = false;
  31.214  ["[Registered members only]"] = "[nur für Registrierte]";
  31.215  ["[not displayed public]"] = "[nicht öffentlich]";
  31.216  ["a bit unsatisfied"] = "etwas unzufrieden";
  31.217  ["abandoned"] = "ausgesetzt";
  31.218  ["activated"] = "aktiviert";
  31.219 +["and"] = "und";
  31.220  ["and #{count} more initiatives"] = "und #{count} weitere Initiativen";
  31.221  ["area"] = "Themengebiet";
  31.222 +["by"] = "von";
  31.223  ["deactivated"] = "deaktiviert";
  31.224  ["delete<br /><br />"] = "löschen<br /><br />";
  31.225  ["disabled"] = "ausgeschaltet";
  31.226 @@ -658,12 +707,13 @@
  31.227  ["must/should not"] = "muss/soll nicht";
  31.228  ["neutral"] = "neutral";
  31.229  ["not implemented"] = "nicht umgesetzt";
  31.230 +["not yet"] = false;
  31.231  ["requested"] = "angefragt";
  31.232  ["satisfied"] = "zufrieden";
  31.233  ["should"] = "soll";
  31.234  ["should not"] = "soll nicht";
  31.235 +["since #{date}"] = "seit #{date}";
  31.236  ["to reset your password please click on the following link:\n\n"] = "um Dein Kennwort zurückzusetzen klicke bitte den folgenden Link an:\n\n";
  31.237  ["until"] = "bis";
  31.238  ["xmpp"] = "Jabber (XMPP)";
  31.239 -["Last login (updated daily)"] = "Letzte Anmeldung (täglich aktualisiert)";
  31.240  }
    32.1 --- a/locale/translations.en.lua	Sat Feb 05 20:01:09 2011 +0100
    32.2 +++ b/locale/translations.en.lua	Wed Mar 02 20:06:26 2011 +0100
    32.3 @@ -3,14 +3,20 @@
    32.4  ["##{id}"] = false;
    32.5  ["##{issue_id}.#{id} #{name}"] = false;
    32.6  ["#{author} at #{date}"] = false;
    32.7 +["#{direct_count}+#{delegated_count} Mitglieder"] = false;
    32.8  ["#{interested_issues_to_vote_count} issue(s) you are interested in"] = false;
    32.9  ["#{issues_to_vote_count} issue(s)"] = false;
   32.10  ["#{number} Image(s) has been deleted"] = false;
   32.11  ["#{number} Image(s) has been updated"] = false;
   32.12 +["#{suggestion_count} suggestions"] = false;
   32.13 +["#{supporter_count} supporters"] = false;
   32.14 +["#{time_left} left"] = false;
   32.15 +["#{vote_count} votes"] = false;
   32.16  ["(#{more_count} duplicates removed)"] = false;
   32.17  ["(change URL)"] = false;
   32.18  ["(new window)"] = false;
   32.19  ["+ #{weight}"] = false;
   32.20 +["+getElementById("] = false;
   32.21  ["A-Z"] = false;
   32.22  ["API key"] = false;
   32.23  ["API key has been deleted"] = false;
   32.24 @@ -62,6 +68,8 @@
   32.25  ["Area list"] = false;
   32.26  ["Area successfully updated"] = false;
   32.27  ["Areas"] = false;
   32.28 +["Areas, you are member of"] = false;
   32.29 +["Areas, you are not member of"] = false;
   32.30  ["Author"] = false;
   32.31  ["Auto support is now disabled"] = false;
   32.32  ["Auto support is now enabled"] = false;
   32.33 @@ -77,6 +85,7 @@
   32.34  ["Back to timeline"] = false;
   32.35  ["Ballot of '#{member_name}' for issue ##{issue_id}"] = false;
   32.36  ["Become a member"] = false;
   32.37 +["Become a member of this area"] = false;
   32.38  ["Birthday"] = false;
   32.39  ["Can't remove last initiator"] = false;
   32.40  ["Can't send confirmation email"] = false;
   32.41 @@ -87,6 +96,7 @@
   32.42  ["Cancelled"] = false;
   32.43  ["Change API key"] = false;
   32.44  ["Change area delegation"] = false;
   32.45 +["Change delegation..."] = false;
   32.46  ["Change display settings"] = false;
   32.47  ["Change email"] = false;
   32.48  ["Change email address"] = false;
   32.49 @@ -106,9 +116,11 @@
   32.50  ["Choose member"] = false;
   32.51  ["Click for details"] = false;
   32.52  ["Closed"] = false;
   32.53 +["Closed since #{date}"] = false;
   32.54  ["Collective opinion of supporters"] = false;
   32.55  ["Commit suggestion"] = false;
   32.56  ["Compare"] = false;
   32.57 +["Compare selected"] = false;
   32.58  ["Confirm"] = false;
   32.59  ["Confirmation code"] = false;
   32.60  ["Confirmation code invalid!"] = false;
   32.61 @@ -116,9 +128,12 @@
   32.62  ["Contacts"] = false;
   32.63  ["Content"] = false;
   32.64  ["Counting of votes"] = false;
   32.65 +["Create / edit area"] = false;
   32.66 +["Create / edit policy"] = false;
   32.67  ["Create alternative initiative"] = false;
   32.68  ["Create new area"] = false;
   32.69  ["Create new issue"] = false;
   32.70 +["Create new policy"] = false;
   32.71  ["Created at"] = false;
   32.72  ["Current draft"] = false;
   32.73  ["Current name"] = false;
   32.74 @@ -130,6 +145,8 @@
   32.75  ["Date format is not valid. Please use following format: YYYY-MM-DD"] = false;
   32.76  ["Default Policy"] = false;
   32.77  ["Degree"] = false;
   32.78 +["Delegate area..."] = false;
   32.79 +["Delegate issue"] = false;
   32.80  ["Delegation abandoned"] = false;
   32.81  ["Delegation problems"] = false;
   32.82  ["Delegation turned off for area"] = false;
   32.83 @@ -163,6 +180,7 @@
   32.84  ["Download database export"] = false;
   32.85  ["Draft"] = false;
   32.86  ["Draft history"] = false;
   32.87 +["Draft revisions"] = false;
   32.88  ["EXPERIMENTAL FEATURE"] = false;
   32.89  ["Edit"] = false;
   32.90  ["Edit draft"] = false;
   32.91 @@ -190,6 +208,7 @@
   32.92  ["Fully frozen at"] = false;
   32.93  ["Generate / change API key"] = false;
   32.94  ["Generate API key"] = false;
   32.95 +["Give up membership"] = false;
   32.96  ["Global delegation"] = false;
   32.97  ["Global delegation active"] = false;
   32.98  ["Go up"] = false;
   32.99 @@ -200,6 +219,7 @@
  32.100  ["Hide"] = false;
  32.101  ["Hide filter details"] = false;
  32.102  ["Hide this help message"] = false;
  32.103 +["Hint"] = false;
  32.104  ["History"] = false;
  32.105  ["Home"] = false;
  32.106  ["I consider suggestion as"] = false;
  32.107 @@ -210,6 +230,7 @@
  32.108  ["Images"] = false;
  32.109  ["In discussion"] = false;
  32.110  ["Incoming delegations"] = false;
  32.111 +["Index"] = false;
  32.112  ["Information about the available policies"] = false;
  32.113  ["Inherit autoreject from area"] = false;
  32.114  ["Initiated"] = false;
  32.115 @@ -217,7 +238,11 @@
  32.116  ["Initiative ##{id}"] = false;
  32.117  ["Initiative events"] = false;
  32.118  ["Initiative is revoked now"] = false;
  32.119 +["Initiative not admitted"] = false;
  32.120 +["Initiative not agreed"] = false;
  32.121  ["Initiative quorum"] = false;
  32.122 +["Initiative quorum denumerator"] = false;
  32.123 +["Initiative quorum numerator"] = false;
  32.124  ["Initiative revoked"] = false;
  32.125  ["Initiative successfully created"] = false;
  32.126  ["Initiative successfully updated"] = false;
  32.127 @@ -232,12 +257,14 @@
  32.128  ["Initiator"] = false;
  32.129  ["Initiator invites"] = false;
  32.130  ["Initiators"] = false;
  32.131 +["Interest"] = false;
  32.132  ["Interest not existant"] = false;
  32.133  ["Interest removed"] = false;
  32.134  ["Interest updated"] = false;
  32.135  ["Interested"] = false;
  32.136  ["Interested members"] = false;
  32.137  ["Internal posts"] = false;
  32.138 +["Interval format:"] = false;
  32.139  ["Invalid query"] = false;
  32.140  ["Invalid username or password!"] = false;
  32.141  ["Invitation has been refused"] = false;
  32.142 @@ -255,11 +282,16 @@
  32.143  ["Issue finished"] = false;
  32.144  ["Issue finished without voting"] = false;
  32.145  ["Issue frozen"] = false;
  32.146 +["Issue not accepted"] = false;
  32.147  ["Issue policy"] = false;
  32.148  ["Issue quorum"] = false;
  32.149 +["Issue quorum denumerator"] = false;
  32.150 +["Issue quorum numerator"] = false;
  32.151  ["Issues"] = false;
  32.152  ["JavaScript is disabled or not available."] = false;
  32.153  ["Last author"] = false;
  32.154 +["Last change"] = false;
  32.155 +["Last login (updated daily)"] = false;
  32.156  ["Last snapshot:"] = false;
  32.157  ["Legend:"] = false;
  32.158  ["License"] = false;
  32.159 @@ -270,6 +302,8 @@
  32.160  ["Logout"] = false;
  32.161  ["Logout successful"] = false;
  32.162  ["Majority"] = false;
  32.163 +["Majority denumerator"] = false;
  32.164 +["Majority numerator"] = false;
  32.165  ["Manage filter"] = false;
  32.166  ["Manage timeline filters"] = false;
  32.167  ["Max potential support"] = false;
  32.168 @@ -324,6 +358,7 @@
  32.169  ["No changes to your images were made"] = false;
  32.170  ["No default"] = false;
  32.171  ["No delegation"] = false;
  32.172 +["No delegation active"] = false;
  32.173  ["No events selected to list"] = false;
  32.174  ["No membership at all"] = false;
  32.175  ["No support at all"] = false;
  32.176 @@ -380,6 +415,8 @@
  32.177  ["Policies"] = false;
  32.178  ["Policy"] = false;
  32.179  ["Policy '#{name}'"] = false;
  32.180 +["Policy list"] = false;
  32.181 +["Policy successfully updated"] = false;
  32.182  ["Population"] = false;
  32.183  ["Posts"] = false;
  32.184  ["Potential support"] = false;
  32.185 @@ -428,6 +465,7 @@
  32.186  ["Saved as contact"] = false;
  32.187  ["Saved contacts"] = false;
  32.188  ["Search"] = false;
  32.189 +["Search in initiatives for text:"] = false;
  32.190  ["Search initiatives"] = false;
  32.191  ["Search issues"] = false;
  32.192  ["Search members"] = false;
  32.193 @@ -456,6 +494,8 @@
  32.194  ["Show member"] = false;
  32.195  ["Show name history"] = false;
  32.196  ["Show only events which match... (or associtated)"] = false;
  32.197 +["Show policies in use"] = false;
  32.198 +["Show policies not in use"] = false;
  32.199  ["So I'm"] = false;
  32.200  ["Software"] = false;
  32.201  ["Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon."] = false;
  32.202 @@ -473,6 +513,7 @@
  32.203  ["Step 3/5: Username"] = false;
  32.204  ["Step 4/5: Login name"] = false;
  32.205  ["Step 5/5: Terms of use and password"] = false;
  32.206 +["Strict majority"] = false;
  32.207  ["Stylesheet URL"] = false;
  32.208  ["Stylesheet URL has been updated"] = false;
  32.209  ["Suggest no initiative"] = false;
  32.210 @@ -490,6 +531,7 @@
  32.211  ["Supported"] = false;
  32.212  ["Supported initiatives"] = false;
  32.213  ["Supporter"] = false;
  32.214 +["Supporters"] = false;
  32.215  ["Syntax help"] = false;
  32.216  ["Tabs"] = false;
  32.217  ["Terms of use"] = false;
  32.218 @@ -498,6 +540,7 @@
  32.219  ["The draft of this initiative has been updated!"] = false;
  32.220  ["The drafts do not differ"] = false;
  32.221  ["The initiators suggest to support the following initiative:"] = false;
  32.222 +["The interested members are updated after some time."] = false;
  32.223  ["There are no more alternative initiatives currently."] = false;
  32.224  ["There were no more alternative initiatives."] = false;
  32.225  ["This email address is too short!"] = false;
  32.226 @@ -513,6 +556,8 @@
  32.227  ["This issue has been finished without any winning initiative."] = false;
  32.228  ["This issue is already closed."] = false;
  32.229  ["This issue is already frozen."] = false;
  32.230 +["This issue is closed"] = false;
  32.231 +["This issue is in voting"] = false;
  32.232  ["This login is already taken, please choose another one!"] = false;
  32.233  ["This login is too short!"] = false;
  32.234  ["This member account has been created at #{created}"] = false;
  32.235 @@ -553,6 +598,7 @@
  32.236  ["Voted no"] = false;
  32.237  ["Voted proposal"] = false;
  32.238  ["Voted yes"] = false;
  32.239 +["Votes"] = false;
  32.240  ["Voting"] = false;
  32.241  ["Voting details"] = false;
  32.242  ["Voting for this issue has already begun."] = false;
  32.243 @@ -575,8 +621,11 @@
  32.244  ["You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter."] = false;
  32.245  ["You are iniator of this initiative"] = false;
  32.246  ["You are interested in this issue"] = false;
  32.247 +["You are interested in this issue by delegation"] = false;
  32.248  ["You are invited to become initiator of this initiative."] = false;
  32.249  ["You are member"] = false;
  32.250 +["You are member of this area"] = false;
  32.251 +["You are not interested in this issue"] = false;
  32.252  ["You are now initiator of this initiative"] = false;
  32.253  ["You are potential supporter of this initiative"] = false;
  32.254  ["You are supporting this initiative"] = false;
  32.255 @@ -586,11 +635,16 @@
  32.256  ["You didn't confirmed your email address '#{email}' within 7 days."] = false;
  32.257  ["You didn't confirmed your email address '#{email}'. You have received an email with an activation link."] = false;
  32.258  ["You didn't saved any member as contact yet."] = false;
  32.259 +["You have delegated globally"] = false;
  32.260 +["You have delegated this area"] = false;
  32.261 +["You have delegated this issue"] = false;
  32.262  ["You have saved this member as contact"] = false;
  32.263  ["You have saved this member as contact."] = false;
  32.264  ["You have to mark 'Are you sure' to revoke!"] = false;
  32.265  ["You need to be logged in, to use all features of this system."] = false;
  32.266  ["You want to vote later"] = false;
  32.267 +["You were interested in this issue"] = false;
  32.268 +["You were interested in this issue by delegation"] = false;
  32.269  ["You've successfully registered and you can login now with your login and password!"] = false;
  32.270  ["Your API key:"] = false;
  32.271  ["Your are interested"] = false;
  32.272 @@ -619,13 +673,25 @@
  32.273  ["Your vote has been discarded. Delegation rules apply if set."] = false;
  32.274  ["Your web browser is not fully supported yet."] = false;
  32.275  ["Z-A"] = false;
  32.276 +["[Change] or [revoke] area delegation [change]"] = "Change";
  32.277 +["[Change] or [revoke] area delegation [midpart]"] = " or ";
  32.278 +["[Change] or [revoke] area delegation [prefix]"] = "";
  32.279 +["[Change] or [revoke] area delegation [revoke]"] = "revoke";
  32.280 +["[Change] or [revoke] area delegation [suffix]"] = " area delegation";
  32.281 +["[Change] or [revoke] global delegation [change]"] = "Change";
  32.282 +["[Change] or [revoke] global delegation [midpart]"] = " or ";
  32.283 +["[Change] or [revoke] global delegation [prefix]"] = "";
  32.284 +["[Change] or [revoke] global delegation [revoke]"] = "revoke";
  32.285 +["[Change] or [revoke] global delegation [suffix]"] = " global delegation";
  32.286  ["[Registered members only]"] = false;
  32.287  ["[not displayed public]"] = false;
  32.288  ["a bit unsatisfied"] = false;
  32.289  ["abandoned"] = false;
  32.290  ["activated"] = false;
  32.291 +["and"] = false;
  32.292  ["and #{count} more initiatives"] = false;
  32.293  ["area"] = false;
  32.294 +["by"] = false;
  32.295  ["deactivated"] = false;
  32.296  ["delete<br /><br />"] = false;
  32.297  ["disabled"] = false;
  32.298 @@ -641,10 +707,12 @@
  32.299  ["must/should not"] = false;
  32.300  ["neutral"] = false;
  32.301  ["not implemented"] = false;
  32.302 +["not yet"] = false;
  32.303  ["requested"] = false;
  32.304  ["satisfied"] = false;
  32.305  ["should"] = false;
  32.306  ["should not"] = false;
  32.307 +["since #{date}"] = false;
  32.308  ["to reset your password please click on the following link:\n\n"] = false;
  32.309  ["until"] = false;
  32.310  ["xmpp"] = false;
    33.1 --- a/model/area.lua	Sat Feb 05 20:01:09 2011 +0100
    33.2 +++ b/model/area.lua	Wed Mar 02 20:06:26 2011 +0100
    33.3 @@ -63,5 +63,12 @@
    33.4    if args.active ~= nil then
    33.5      selector:add_where{ "active = ?", args.active }
    33.6    end
    33.7 +  if args.member_id then
    33.8 +    selector:join("membership", nil, { "membership.area_id = area.id AND membership.member_id = ?", args.member_id })
    33.9 +  end
   33.10 +  if args.not_member_id then
   33.11 +    selector:left_join("membership", nil, { "membership.area_id = area.id AND membership.member_id = ?", args.not_member_id })
   33.12 +    selector:add_where{ "membership.member_id ISNULL" }
   33.13 +  end
   33.14    return selector
   33.15  end
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/model/delegating_interest_snapshot.lua	Wed Mar 02 20:06:26 2011 +0100
    34.3 @@ -0,0 +1,10 @@
    34.4 +DelegatingInterestSnapshot = mondelefant.new_class()
    34.5 +DelegatingInterestSnapshot.table = 'delegating_interest_snapshot'
    34.6 +DelegatingInterestSnapshot.primary_key = { "issue_id", "event", "member_id" }
    34.7 +
    34.8 +function DelegatingInterestSnapshot:by_pk(issue_id, event, member_id)
    34.9 +  return self:new_selector()
   34.10 +    :add_where{ "issue_id = ? AND event = ? AND member_id = ?", issue_id, event, member_id }
   34.11 +    :optional_object_mode()
   34.12 +    :exec()
   34.13 +end
   34.14 \ No newline at end of file
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/model/direct_interest_snapshot.lua	Wed Mar 02 20:06:26 2011 +0100
    35.3 @@ -0,0 +1,10 @@
    35.4 +DirectInterestSnapshot = mondelefant.new_class()
    35.5 +DirectInterestSnapshot.table = 'direct_interest_snapshot'
    35.6 +DirectInterestSnapshot.primary_key = { "issue_id", "event", "member_id" }
    35.7 +
    35.8 +function DirectInterestSnapshot:by_pk(issue_id, event, member_id)
    35.9 +  return self:new_selector()
   35.10 +    :add_where{ "issue_id = ? AND event = ? AND member_id = ?", issue_id, event, member_id }
   35.11 +    :optional_object_mode()
   35.12 +    :exec()
   35.13 +end
   35.14 \ No newline at end of file
    36.1 --- a/model/issue.lua	Sat Feb 05 20:01:09 2011 +0100
    36.2 +++ b/model/issue.lua	Wed Mar 02 20:06:26 2011 +0100
    36.3 @@ -23,7 +23,8 @@
    36.4    this_key      = 'id',
    36.5    that_key      = 'issue_id',
    36.6    ref           = 'initiatives',
    36.7 -  back_ref      = 'issue'
    36.8 +  back_ref      = 'issue',
    36.9 +  default_order = 'initiative.rank, initiative.admitted ISNULL, initiative.admitted DESC, initiative.positive_votes::float / initiative.negative_votes::float DESC, initiative.supporter_count DESC'
   36.10  }
   36.11  
   36.12  Issue:add_reference{
   36.13 @@ -85,7 +86,7 @@
   36.14    connected_by_that_key = 'member_id',
   36.15    ref                   = 'members'
   36.16  }
   36.17 -
   36.18 +--[[
   36.19  Issue:add_reference{
   36.20    mode                  = 'mm',
   36.21    to                    = "Member",
   36.22 @@ -96,7 +97,7 @@
   36.23    connected_by_that_key = 'member_id',
   36.24    ref                   = 'interested_members_snapshot'
   36.25  }
   36.26 -
   36.27 +--]]
   36.28  Issue:add_reference{
   36.29    mode                  = 'mm',
   36.30    to                    = "Member",
   36.31 @@ -108,6 +109,133 @@
   36.32    ref                   = 'direct_voters'
   36.33  }
   36.34  
   36.35 +Issue:add_reference{
   36.36 +  mode                  = 'mm',
   36.37 +  to                    = "Member",
   36.38 +  this_key              = 'id',
   36.39 +  that_key              = 'id',
   36.40 +  connected_by_table    = 'direct_interest_snapshot',
   36.41 +  connected_by_this_key = 'issue_id',
   36.42 +  connected_by_that_key = 'member_id',
   36.43 +  ref                   = 'interested_members_snapshot',
   36.44 +  selector_generator = function(list, options)
   36.45 +    -- build list of issue ids
   36.46 +    local ids = { sep = ", " }
   36.47 +    for i, object in ipairs(list) do
   36.48 +      local id = object.id
   36.49 +      if id ~= nil then
   36.50 +        ids[#ids+1] = {"?", id}
   36.51 +      end
   36.52 +    end
   36.53 +
   36.54 +    if #ids == 0 then
   36.55 +      return Member:new_selector():empty_list_mode()
   36.56 +    end
   36.57 +    
   36.58 +    local selector = Member:new_selector()
   36.59 +    selector:join("direct_interest_snapshot", nil, { "direct_interest_snapshot.member_id = member.id AND direct_interest_snapshot.issue_id IN ($)", ids })
   36.60 +    selector:join("issue", nil, "direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.event = issue.latest_snapshot_event")
   36.61 +    selector:add_order_by('direct_interest_snapshot.weight DESC')
   36.62 +    return selector
   36.63 +  end
   36.64 +}
   36.65 +
   36.66 +Issue:add_reference{
   36.67 +  mode          = '11',
   36.68 +  to            = "DelegatingInterestSnapshot",
   36.69 +  this_key      = 'id',
   36.70 +  that_key      = 'issue_id',
   36.71 +  ref           = 'delegating_interest_snapshot_for_member',
   36.72 +  back_ref      = 'issue',
   36.73 +  selector_generator = function(list, options)
   36.74 +    local member_id = assert(options.member_id)
   36.75 +  
   36.76 +    -- build list of issue ids
   36.77 +    local ids = { sep = ", " }
   36.78 +    for i, object in ipairs(list) do
   36.79 +      local id = object.id
   36.80 +      if id ~= nil then
   36.81 +        ids[#ids+1] = {"?", id}
   36.82 +      end
   36.83 +    end
   36.84 +
   36.85 +    if #ids == 0 then
   36.86 +      return DelegatingInterestSnapshot:new_selector():empty_list_mode()
   36.87 +    end
   36.88 +    
   36.89 +    local selector = DelegatingInterestSnapshot:new_selector()
   36.90 +    selector:join("issue", nil, "delegating_interest_snapshot.issue_id = issue.id AND delegating_interest_snapshot.event = issue.latest_snapshot_event")
   36.91 +    selector:add_where{ 'delegating_interest_snapshot.issue_id IN ($)', ids }
   36.92 +    selector:add_where{ 'delegating_interest_snapshot.member_id = ?', options.member_id }
   36.93 +    
   36.94 +    return selector
   36.95 +  end
   36.96 +}
   36.97 +
   36.98 +Issue:add_reference{
   36.99 +  mode          = '11',
  36.100 +  to            = "Interest",
  36.101 +  this_key      = 'id',
  36.102 +  that_key      = 'issue_id',
  36.103 +  ref           = 'interest_for_member',
  36.104 +  back_ref      = 'issue',
  36.105 +  selector_generator = function(list, options)
  36.106 +
  36.107 +    local member_id = assert(options.member_id)
  36.108 +  
  36.109 +    -- build list of issue ids
  36.110 +    local ids = { sep = ", " }
  36.111 +    for i, object in ipairs(list) do
  36.112 +      local id = object.id
  36.113 +      if id ~= nil then
  36.114 +        ids[#ids+1] = {"?", id}
  36.115 +      end
  36.116 +    end
  36.117 +
  36.118 +    if #ids == 0 then
  36.119 +      return Interest:new_selector():empty_list_mode()
  36.120 +    end
  36.121 +    
  36.122 +    local selector = Interest:new_selector()
  36.123 +    selector:add_where{ 'interest.issue_id IN ($)', ids }
  36.124 +    selector:add_where{ 'interest.member_id = ?', member_id }
  36.125 +    return selector
  36.126 +
  36.127 +  end
  36.128 +}
  36.129 +
  36.130 +Issue:add_reference{
  36.131 +  mode          = '1m',
  36.132 +  to            = "Delegation",
  36.133 +  this_key      = 'id',
  36.134 +  that_key      = 'issue_id',
  36.135 +  ref           = 'outgoing_delegations_for_member',
  36.136 +  back_ref      = 'issue',
  36.137 +  selector_generator = function(list, options)
  36.138 +
  36.139 +    local member_id = assert(options.member_id)
  36.140 +  
  36.141 +    -- build list of issue ids
  36.142 +    local ids = { sep = ", " }
  36.143 +    for i, object in ipairs(list) do
  36.144 +      local id = object.id
  36.145 +      if id ~= nil then
  36.146 +        ids[#ids+1] = {"?", id}
  36.147 +      end
  36.148 +    end
  36.149 +
  36.150 +    if #ids == 0 then
  36.151 +      return Delegation:new_selector():empty_list_mode()
  36.152 +    end
  36.153 +    
  36.154 +    local selector = Delegation:new_selector()
  36.155 +    selector:add_where{ 'delegation.issue_id IN ($)', ids }
  36.156 +    selector:add_where{ 'delegation.truster_id = ?', member_id }
  36.157 +    return selector
  36.158 +
  36.159 +  end
  36.160 +}
  36.161 +
  36.162  
  36.163  
  36.164  function Issue:get_state_name_for_state(value)
  36.165 @@ -169,6 +297,33 @@
  36.166    end
  36.167  end
  36.168  
  36.169 +function Issue:build_selector(args)
  36.170 +  local selector = self:new_selector()
  36.171 +  if args.area_id then
  36.172 +    selector:add_where{ "issue.area_id = ?", args.area_id }
  36.173 +  end
  36.174 +  if args.state == "closed" then
  36.175 +    selector:add_where("issue.closed NOTNULL")
  36.176 +  elseif args.state == "voting" then
  36.177 +    selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
  36.178 +  elseif args.state == "frozen" then
  36.179 +    selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL")
  36.180 +  elseif args.state == "discussion" then
  36.181 +    selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
  36.182 +  elseif args.state == "new" then
  36.183 +    selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
  36.184 +  end
  36.185 +  if args.order == "time_left" then
  36.186 +    selector:add_order_by("issue.closed DESC")
  36.187 +  elseif args.order == "last_change" then
  36.188 +    selector:add_order_by("issue.closed DESC")
  36.189 +  elseif args.order == "interest" then
  36.190 +    selector:add_order_by("issue.population DESC")
  36.191 +  end
  36.192 +  
  36.193 +  return selector
  36.194 +end
  36.195 +
  36.196  function Issue.object_get:state()
  36.197    if self.closed then
  36.198      if self.fully_frozen then
    37.1 Binary file static/lf2/icon_award_gold.png has changed
    38.1 Binary file static/lf2/icon_award_silver.png has changed
    39.1 Binary file static/lf2/icon_cross.png has changed
    40.1 Binary file static/lf2/icon_delegated_star.png has changed
    41.1 Binary file static/lf2/icon_delegation.png has changed
    42.1 Binary file static/lf2/icon_delegation_area.png has changed
    43.1 Binary file static/lf2/icon_delegation_global.png has changed
    44.1 Binary file static/lf2/icon_eye.png has changed
    45.1 Binary file static/lf2/icon_search.png has changed
    46.1 Binary file static/lf2/icon_search_crossed.png has changed
    47.1 Binary file static/lf2/icon_star.png has changed
    48.1 Binary file static/lf2/icon_star_crossed.png has changed
    49.1 Binary file static/lf2/icon_star_grey.png has changed
    50.1 Binary file static/lf2/icon_suggestion.png has changed
    51.1 Binary file static/lf2/icon_supporter.png has changed
    52.1 Binary file static/lf2/icon_text.png has changed
    53.1 Binary file static/lf2/icon_vote.png has changed

Impressum / About Us