liquid_feedback_frontend

diff app/main/suggestion/_list.lua @ 19:00d1004545f1

Dynamic interface using XMLHttpRequests, and many other changes

Bugfixes:
- Only allow voting on admitted initiatives
- Repaired issue search
- Don't display delegations for closed issues on member page
- Don't show revoke link in initiative, when issue is already half_frozen
- Localization for voting JavaScript
- Display author of suggestions

Disclosure of voting data after voting is finished:
- Possibility to inspect every ballot including preferences
- Show number of voters preferring one initiative to another initiative

Interface behaviour changes:
- Reversed default order of drafts
- Default order of suggestions changed
- Show new drafts of initiatives only once per day in timeline

Accessibility:
- Barrier-free voting implemented
- POST links are now accessible without JavaScript
- Changed gray for unsatisfied supporters in bar graph to a lighter gray

Other interface improvements:
- Optical enhancements
- Dynamic interface using XMLHttpRequests
- Show usage terms in about section
- Show own membership in area listing
- Show uninformed supporters greyed out and marked with yellow question mark
- Warning box in non-admitted initiatives
- When voted, don't display voting notice and change label of voting link
- Show object counts in more tabulator heads
- Enlarged member statement input field

Miscellaneous:
- Code cleanup
- Added README file containing installation instructions
- Use new WebMCP function ui.filters{...} instead of own ui.filter and ui.order functions
author bsw/jbe
date Sat Feb 20 22:10:31 2010 +0100 (2010-02-20)
parents afd9f769c7ae
children 0849be391140
line diff
     1.1 --- a/app/main/suggestion/_list.lua	Tue Feb 02 00:31:06 2010 +0100
     1.2 +++ b/app/main/suggestion/_list.lua	Sat Feb 20 22:10:31 2010 +0100
     1.3 @@ -1,61 +1,66 @@
     1.4  
     1.5  local initiative = param.get("initiative", "table")
     1.6  local suggestions_selector = param.get("suggestions_selector", "table")
     1.7 +local tab_id = param.get("tab_id")
     1.8 +local show_name = param.get("show_name", atom.boolean)
     1.9 +if show_name == nil then
    1.10 +  show_name = true
    1.11 +end
    1.12 +local show_filter = param.get("show_filter", atom.boolean)
    1.13 +if show_filter == nil then
    1.14 +  show_filter = true
    1.15 +end
    1.16  
    1.17 -ui.order{
    1.18 -  name = name,
    1.19 +local partial = {
    1.20 +  routing = {
    1.21 +    default = {
    1.22 +      mode = "redirect",
    1.23 +      module = "initiative",
    1.24 +      view = "show_tab",
    1.25 +      params = {
    1.26 +        initiative_id = initiative.id,
    1.27 +        tab = "suggestions",
    1.28 +        tab_id = tab_id
    1.29 +      },
    1.30 +    }
    1.31 +  }
    1.32 +}
    1.33 +
    1.34 +local ui_filters = ui.filters
    1.35 +if not show_filter then
    1.36 +  ui_filters = function(args) args.content() end
    1.37 +end
    1.38 +
    1.39 +ui_filters{
    1.40 +  label = _"Show filter",
    1.41    selector = suggestions_selector,
    1.42 -  options = {
    1.43 +  {
    1.44 +    label = _"Order by",
    1.45      {
    1.46 -      name = "all",
    1.47 -      label = _"all",
    1.48 -      order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count + plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id"
    1.49 +      name = "plus_unfulfilled",
    1.50 +      label = _"requested",
    1.51 +      selector_modifier = function(selector) selector:add_order_by("plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id") end
    1.52      },
    1.53      {
    1.54        name = "plus2",
    1.55        label = _"must",
    1.56 -      order_by = "plus2_unfulfilled_count + plus2_fulfilled_count DESC, id"
    1.57 +      selector_modifier = function(selector) selector:add_order_by("plus2_unfulfilled_count + plus2_fulfilled_count DESC, id") end
    1.58      },
    1.59      {
    1.60        name = "plus",
    1.61        label = _"must/should",
    1.62 -      order_by = "plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id"
    1.63 +      selector_modifier = function(selector) selector:add_order_by("plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id") end
    1.64      },
    1.65      {
    1.66        name = "minus",
    1.67        label = _"must/should not",
    1.68 -      order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count DESC, id"
    1.69 +      selector_modifier = function(selector) selector:add_order_by("minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count DESC, id") end
    1.70      },
    1.71      {
    1.72        name = "minus2",
    1.73        label = _"must not",
    1.74 -      order_by = "minus2_unfulfilled_count + minus2_fulfilled_count DESC, id"
    1.75 -    },
    1.76 -    {
    1.77 -      name = "unfulfilled",
    1.78 -      label = _"not implemented",
    1.79 -      order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id"
    1.80 -    },
    1.81 -    {
    1.82 -      name = "plus2_unfulfilled",
    1.83 -      label = _"must",
    1.84 -      order_by = "plus2_unfulfilled_count DESC, id"
    1.85 -    },
    1.86 -    {
    1.87 -      name = "plus_unfulfilled",
    1.88 -      label = _"must/should",
    1.89 -      order_by = "plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id"
    1.90 -    },
    1.91 -    {
    1.92 -      name = "minus_unfulfilled",
    1.93 -      label = _"must/should not",
    1.94 -      order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count DESC, id"
    1.95 -    },
    1.96 -    {
    1.97 -      name = "minus2_unfulfilled",
    1.98 -      label = _"must not",
    1.99 -      order_by = "minus2_unfulfilled_count DESC, id"
   1.100 -    },
   1.101 +      selector_modifier = function(selector) selector:add_order_by("minus2_unfulfilled_count + minus2_fulfilled_count DESC, id") end
   1.102 +    }
   1.103    },
   1.104    content = function()
   1.105      ui.paginate{
   1.106 @@ -66,14 +71,16 @@
   1.107            records = suggestions_selector:exec(),
   1.108            columns = {
   1.109              {
   1.110 -              label = _"Suggestion",
   1.111 +              label = show_name and _"Suggestion" or nil,
   1.112                content = function(record)
   1.113 -                ui.link{
   1.114 -                  text = record.name,
   1.115 -                  module = "suggestion",
   1.116 -                  view = "show",
   1.117 -                  id = record.id
   1.118 -                }
   1.119 +                if show_name then
   1.120 +                  ui.link{
   1.121 +                    text = record.name,
   1.122 +                    module = "suggestion",
   1.123 +                    view = "show",
   1.124 +                    id = record.id
   1.125 +                  }
   1.126 +                end
   1.127                end
   1.128              },
   1.129              {
   1.130 @@ -108,65 +115,98 @@
   1.131                  ui.container{
   1.132                    attr = { class = "suggestion_my_opinion" },
   1.133                    content = function()
   1.134 -                    ui.link{
   1.135 -                      attr = { class = "action" .. (degree == -2 and " active_red2" or "") },
   1.136 -                      text = _"must not",
   1.137 -                      module = "opinion",
   1.138 -                      action = "update",
   1.139 -                      routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.140 -                      params = {
   1.141 -                        suggestion_id = record.id,
   1.142 -                        degree = -2
   1.143 +                    if initiative.issue.state == "voting" or initiative.issue.state == "closed" then
   1.144 +                      ui.tag{
   1.145 +                        tag = "span",
   1.146 +                        attr = { class = "action" .. (degree == -2 and " active_red2" or "") },
   1.147 +                        content = _"must not"
   1.148 +                      }
   1.149 +                      ui.tag{
   1.150 +                        tag = "span",
   1.151 +                        attr = { class = "action" .. (degree == -1 and " active_red1" or "") },
   1.152 +                        content = _"should not"
   1.153 +                      }
   1.154 +                      ui.tag{
   1.155 +                        tag = "span",
   1.156 +                        attr = { class = "action" .. (degree == nil and " active" or "") },
   1.157 +                        content = _"neutral"
   1.158                        }
   1.159 -                    }
   1.160 -                    slot.put(" ")
   1.161 -                    ui.link{
   1.162 -                      attr = { class = "action" .. (degree == -1 and " active_red1" or "") },
   1.163 -                      text = _"should not",
   1.164 -                      module = "opinion",
   1.165 -                      action = "update",
   1.166 -                      routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.167 -                      params = {
   1.168 -                        suggestion_id = record.id,
   1.169 -                        degree = -1
   1.170 +                      ui.tag{
   1.171 +                        tag = "span",
   1.172 +                        attr = { class = "action" .. (degree == 1 and " active_green1" or "") },
   1.173 +                        content = _"should"
   1.174 +                      }
   1.175 +                      ui.tag{
   1.176 +                        tag = "span",
   1.177 +                        attr = { class = "action" .. (degree == 2 and " active_green2" or "") },
   1.178 +                        content = _"must"
   1.179 +                      }
   1.180 +                    else
   1.181 +                      ui.link{
   1.182 +                        attr = { class = "action" .. (degree == -2 and " active_red2" or "") },
   1.183 +                        text = _"must not",
   1.184 +                        module = "opinion",
   1.185 +                        action = "update",
   1.186 +                        routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.187 +                        params = {
   1.188 +                          suggestion_id = record.id,
   1.189 +                          degree = -2
   1.190 +                        },
   1.191 +                        partial = partial
   1.192                        }
   1.193 -                    }
   1.194 -                    slot.put(" ")
   1.195 -                    ui.link{
   1.196 -                      attr = { class = "action" .. (degree == nil and " active" or "") },
   1.197 -                      text = _"neutral",
   1.198 -                      module = "opinion",
   1.199 -                      action = "update",
   1.200 -                      routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.201 -                      params = {
   1.202 -                        suggestion_id = record.id,
   1.203 -                        delete = true
   1.204 +                      slot.put(" ")
   1.205 +                      ui.link{
   1.206 +                        attr = { class = "action" .. (degree == -1 and " active_red1" or "") },
   1.207 +                        text = _"should not",
   1.208 +                        module = "opinion",
   1.209 +                        action = "update",
   1.210 +                        routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.211 +                        params = {
   1.212 +                          suggestion_id = record.id,
   1.213 +                          degree = -1
   1.214 +                        },
   1.215 +                        partial = partial
   1.216 +                      }
   1.217 +                      slot.put(" ")
   1.218 +                      ui.link{
   1.219 +                        attr = { class = "action" .. (degree == nil and " active" or "") },
   1.220 +                        text = _"neutral",
   1.221 +                        module = "opinion",
   1.222 +                        action = "update",
   1.223 +                        routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.224 +                        params = {
   1.225 +                          suggestion_id = record.id,
   1.226 +                          delete = true
   1.227 +                        },
   1.228 +                        partial = partial
   1.229                        }
   1.230 -                    }
   1.231 -                    slot.put(" ")
   1.232 -                    ui.link{
   1.233 -                      attr = { class = "action" .. (degree == 1 and " active_green1" or "") },
   1.234 -                      text = _"should",
   1.235 -                      module = "opinion",
   1.236 -                      action = "update",
   1.237 -                      routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.238 -                      params = {
   1.239 -                        suggestion_id = record.id,
   1.240 -                        degree = 1
   1.241 +                      slot.put(" ")
   1.242 +                      ui.link{
   1.243 +                        attr = { class = "action" .. (degree == 1 and " active_green1" or "") },
   1.244 +                        text = _"should",
   1.245 +                        module = "opinion",
   1.246 +                        action = "update",
   1.247 +                        routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.248 +                        params = {
   1.249 +                          suggestion_id = record.id,
   1.250 +                          degree = 1
   1.251 +                        },
   1.252 +                        partial = partial
   1.253                        }
   1.254 -                    }
   1.255 -                    slot.put(" ")
   1.256 -                    ui.link{
   1.257 -                      attr = { class = "action" .. (degree == 2 and " active_green2" or "") },
   1.258 -                      text = _"must",
   1.259 -                      module = "opinion",
   1.260 -                      action = "update",
   1.261 -                      routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.262 -                      params = {
   1.263 -                        suggestion_id = record.id,
   1.264 -                        degree = 2
   1.265 +                      slot.put(" ")
   1.266 +                      ui.link{
   1.267 +                        attr = { class = "action" .. (degree == 2 and " active_green2" or "") },
   1.268 +                        text = _"must",
   1.269 +                        module = "opinion",
   1.270 +                        action = "update",
   1.271 +                        routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
   1.272 +                        params = {
   1.273 +                          suggestion_id = record.id,
   1.274 +                          degree = 2
   1.275 +                        },
   1.276 +                        partial = partial
   1.277                        }
   1.278 -                    }
   1.279 +                    end
   1.280                    end
   1.281                  }
   1.282                end
   1.283 @@ -254,7 +294,8 @@
   1.284                        params = {
   1.285                          suggestion_id = record.id,
   1.286                          fulfilled = true
   1.287 -                      }
   1.288 +                      },
   1.289 +                      partial = partial
   1.290                      }
   1.291                    else
   1.292                      if opinion.degree > 0 then
   1.293 @@ -271,7 +312,8 @@
   1.294                        params = {
   1.295                          suggestion_id = record.id,
   1.296                          fulfilled = false
   1.297 -                      }
   1.298 +                      },
   1.299 +                      partial = partial
   1.300                      }
   1.301                    end
   1.302                  end
   1.303 @@ -295,7 +337,3 @@
   1.304      }
   1.305    end
   1.306  }
   1.307 -
   1.308 -if initiative then
   1.309 -  ui.field.timestamp{ label = _"Last snapshot:", value = initiative.issue.snapshot }
   1.310 -end

Impressum / About Us