liquid_feedback_frontend
annotate app/main/initiative/show.lua @ 11:77d58efe99fd
Version beta7
Important security fixes:
- Added missing HTML encoding to postal address of member
- Link to discussion URL only if it starts with http(s)://
Other bugfixes:
- Fixed wrong display of 2nd level delegating voters for an initiative
- Do not display invited initiators as initiators while voting
- Added missing translation
New features:
- Public message of the day
- Both direct and indirect supporter count is shown in tab heads
- Support shown in initiative lists
Language chooser at the login page has been added (again)
Important security fixes:
- Added missing HTML encoding to postal address of member
- Link to discussion URL only if it starts with http(s)://
Other bugfixes:
- Fixed wrong display of 2nd level delegating voters for an initiative
- Do not display invited initiators as initiators while voting
- Added missing translation
New features:
- Public message of the day
- Both direct and indirect supporter count is shown in tab heads
- Support shown in initiative lists
Language chooser at the login page has been added (again)
author | bsw |
---|---|
date | Fri Jan 22 12:00:00 2010 +0100 (2010-01-22) |
parents | 72c5e0ee7c98 |
children | 00d1004545f1 |
rev | line source |
---|---|
bsw/jbe@0 | 1 local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() |
bsw/jbe@0 | 2 |
bsw/jbe@5 | 3 slot.select("actions", function() |
bsw/jbe@5 | 4 ui.link{ |
bsw/jbe@5 | 5 content = function() |
bsw/jbe@5 | 6 ui.image{ static = "icons/16/script.png" } |
bsw/jbe@5 | 7 slot.put(_"Show all initiatives") |
bsw/jbe@5 | 8 end, |
bsw/jbe@5 | 9 module = "issue", |
bsw/jbe@5 | 10 view = "show", |
bsw/jbe@5 | 11 id = initiative.issue.id |
bsw/jbe@5 | 12 } |
bsw/jbe@5 | 13 end) |
bsw/jbe@4 | 14 |
bsw/jbe@4 | 15 execute.view{ |
bsw/jbe@4 | 16 module = "issue", |
bsw/jbe@4 | 17 view = "_show_head", |
bsw/jbe@4 | 18 params = { issue = initiative.issue } |
bsw/jbe@4 | 19 } |
bsw/jbe@4 | 20 |
bsw@10 | 21 if initiative.revoked then |
bsw@10 | 22 ui.container{ |
bsw@10 | 23 attr = { class = "revoked_info" }, |
bsw@10 | 24 content = function() |
bsw@10 | 25 slot.put(_("This initiative has been revoked at #{revoked}", { revoked = format.timestamp(initiative.revoked) })) |
bsw@10 | 26 local suggested_initiative = initiative.suggested_initiative |
bsw@10 | 27 if suggested_initiative then |
bsw@10 | 28 slot.put("<br /><br />") |
bsw@10 | 29 slot.put(_("The initiators suggest to support the following initiative:")) |
bsw@10 | 30 slot.put("<br />") |
bsw@10 | 31 ui.link{ |
bsw@10 | 32 content = _("Issue ##{id}", { id = suggested_initiative.issue.id } ) .. ": " .. encode.html(suggested_initiative.name), |
bsw@10 | 33 module = "initiative", |
bsw@10 | 34 view = "show", |
bsw@10 | 35 id = suggested_initiative.id |
bsw@10 | 36 } |
bsw@10 | 37 end |
bsw@10 | 38 end |
bsw@10 | 39 } |
bsw@10 | 40 end |
bsw@10 | 41 |
bsw/jbe@4 | 42 local initiator = Initiator:by_pk(initiative.id, app.session.member.id) |
bsw/jbe@4 | 43 |
bsw@3 | 44 --slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(initiative.id) .. '.rss" />') |
bsw/jbe@0 | 45 |
bsw/jbe@0 | 46 |
bsw/jbe@0 | 47 slot.select("actions", function() |
bsw/jbe@4 | 48 if not initiative.issue.fully_frozen and not initiative.issue.closed then |
bsw@2 | 49 ui.link{ |
bsw@3 | 50 attr = { class = "action" }, |
bsw@3 | 51 content = function() |
bsw@3 | 52 ui.image{ static = "icons/16/script_add.png" } |
bsw/jbe@4 | 53 slot.put(_"Create alternative initiative") |
bsw@3 | 54 end, |
bsw@3 | 55 module = "initiative", |
bsw@3 | 56 view = "new", |
bsw@3 | 57 params = { issue_id = initiative.issue.id } |
bsw@3 | 58 } |
bsw@3 | 59 end |
bsw/jbe@4 | 60 end) |
bsw/jbe@4 | 61 |
bsw@10 | 62 slot.put_into("sub_title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) )) |
bsw@10 | 63 |
bsw@10 | 64 slot.select("support", function() |
bsw@10 | 65 ui.container{ |
bsw@10 | 66 attr = { class = "actions" }, |
bsw@10 | 67 content = function() |
bsw@10 | 68 execute.view{ |
bsw@10 | 69 module = "supporter", |
bsw@10 | 70 view = "_show_box", |
bsw@10 | 71 params = { initiative = initiative } |
bsw@10 | 72 } |
bsw@10 | 73 if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then |
bsw@10 | 74 ui.link{ |
bsw@10 | 75 attr = { class = "action", style = "float: left;" }, |
bsw@10 | 76 content = function() |
bsw@10 | 77 ui.image{ static = "icons/16/script_delete.png" } |
bsw@10 | 78 slot.put(_"Revoke initiative") |
bsw@10 | 79 end, |
bsw@10 | 80 module = "initiative", |
bsw@10 | 81 view = "revoke", |
bsw@10 | 82 id = initiative.id |
bsw@10 | 83 } |
bsw@10 | 84 end |
bsw@10 | 85 end |
bsw@10 | 86 } |
bsw@10 | 87 end) |
bsw/jbe@4 | 88 |
bsw/jbe@4 | 89 util.help("initiative.show") |
bsw/jbe@4 | 90 |
bsw@10 | 91 if initiator and initiator.accepted == nil then |
bsw@10 | 92 ui.container{ |
bsw@10 | 93 attr = { class = "initiator_invite_info" }, |
bsw@10 | 94 content = function() |
bsw@10 | 95 slot.put(_"You are invited to become initiator of this initiative.") |
bsw@10 | 96 slot.put(" ") |
bsw@10 | 97 ui.link{ |
bsw@10 | 98 content = function() |
bsw@10 | 99 ui.image{ static = "icons/16/tick.png" } |
bsw@10 | 100 slot.put(_"Accept invitation") |
bsw@10 | 101 end, |
bsw@10 | 102 module = "initiative", |
bsw@10 | 103 action = "accept_invitation", |
bsw@10 | 104 id = initiative.id, |
bsw@10 | 105 routing = { |
bsw@10 | 106 default = { |
bsw@10 | 107 mode = "redirect", |
bsw@10 | 108 module = request.get_module(), |
bsw@10 | 109 view = request.get_view(), |
bsw@10 | 110 id = param.get_id_cgi(), |
bsw@10 | 111 params = param.get_all_cgi() |
bsw@10 | 112 } |
bsw@10 | 113 } |
bsw@10 | 114 } |
bsw@10 | 115 slot.put(" ") |
bsw@10 | 116 ui.link{ |
bsw@10 | 117 content = function() |
bsw@10 | 118 ui.image{ static = "icons/16/cross.png" } |
bsw@10 | 119 slot.put(_"Refuse invitation") |
bsw@10 | 120 end, |
bsw@10 | 121 module = "initiative", |
bsw@10 | 122 action = "reject_initiator_invitation", |
bsw@10 | 123 params = { |
bsw@10 | 124 initiative_id = initiative.id, |
bsw@10 | 125 member_id = app.session.member.id |
bsw@10 | 126 }, |
bsw@10 | 127 routing = { |
bsw@10 | 128 default = { |
bsw@10 | 129 mode = "redirect", |
bsw@10 | 130 module = request.get_module(), |
bsw@10 | 131 view = request.get_view(), |
bsw@10 | 132 id = param.get_id_cgi(), |
bsw@10 | 133 params = param.get_all_cgi() |
bsw@10 | 134 } |
bsw@10 | 135 } |
bsw@10 | 136 } |
bsw@10 | 137 end |
bsw@10 | 138 } |
bsw@10 | 139 slot.put("<br />") |
bsw@10 | 140 end |
bsw/jbe@4 | 141 |
bsw@10 | 142 if (initiative.discussion_url and #initiative.discussion_url > 0) |
bsw@10 | 143 or (initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked) then |
bsw@10 | 144 ui.container{ |
bsw@10 | 145 attr = { class = "vertical" }, |
bsw@10 | 146 content = function() |
bsw@10 | 147 ui.container{ |
bsw@10 | 148 attr = { class = "ui_field_label" }, |
bsw@10 | 149 content = _"Discussion with initiators" |
bsw@10 | 150 } |
bsw@10 | 151 ui.tag{ |
bsw@10 | 152 tag = "span", |
bsw@10 | 153 content = function() |
bsw@11 | 154 if initiative.discussion_url:find("^https?://") then |
bsw@11 | 155 if initiative.discussion_url and #initiative.discussion_url > 0 then |
bsw@11 | 156 ui.link{ |
bsw@11 | 157 attr = { |
bsw@11 | 158 class = "actions", |
bsw@11 | 159 target = "_blank", |
bsw@11 | 160 title = initiative.discussion_url |
bsw@11 | 161 }, |
bsw@11 | 162 content = function() |
bsw@11 | 163 slot.put(encode.html(initiative.discussion_url)) |
bsw@11 | 164 end, |
bsw@11 | 165 external = initiative.discussion_url |
bsw@11 | 166 } |
bsw@11 | 167 end |
bsw@11 | 168 else |
bsw@11 | 169 slot.put(encode.html(initiative.discussion_url)) |
bsw@10 | 170 end |
bsw@10 | 171 slot.put(" ") |
bsw@10 | 172 if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then |
bsw@10 | 173 ui.link{ |
bsw@10 | 174 attr = { class = "actions" }, |
bsw@10 | 175 content = _"(change URL)", |
bsw@10 | 176 module = "initiative", |
bsw@10 | 177 view = "edit", |
bsw@10 | 178 id = initiative.id |
bsw@10 | 179 } |
bsw@10 | 180 end |
bsw/jbe@4 | 181 end |
bsw@10 | 182 } |
bsw@10 | 183 end |
bsw@10 | 184 } |
bsw@10 | 185 end |
bsw/jbe@0 | 186 |
bsw/jbe@0 | 187 |
bsw/jbe@0 | 188 ui.container{ |
bsw/jbe@0 | 189 attr = { id = "add_suggestion_form", class = "hidden_inline_form" }, |
bsw/jbe@0 | 190 content = function() |
bsw/jbe@0 | 191 |
bsw/jbe@0 | 192 ui.link{ |
bsw/jbe@0 | 193 content = _"Close", |
bsw/jbe@0 | 194 attr = { |
bsw/jbe@0 | 195 onclick = "document.getElementById('add_suggestion_form').style.display='none';return(false)", |
bsw/jbe@0 | 196 style = "float: right;" |
bsw/jbe@0 | 197 } |
bsw/jbe@0 | 198 } |
bsw/jbe@0 | 199 |
bsw/jbe@0 | 200 ui.field.text{ attr = { class = "head" }, value = _"Add new suggestion" } |
bsw/jbe@0 | 201 |
bsw/jbe@0 | 202 |
bsw/jbe@0 | 203 ui.form{ |
bsw/jbe@0 | 204 module = "suggestion", |
bsw/jbe@0 | 205 action = "add", |
bsw/jbe@0 | 206 params = { initiative_id = initiative.id }, |
bsw/jbe@0 | 207 routing = { |
bsw/jbe@0 | 208 default = { |
bsw/jbe@0 | 209 mode = "redirect", |
bsw/jbe@0 | 210 module = "initiative", |
bsw/jbe@0 | 211 view = "show", |
bsw/jbe@0 | 212 id = initiative.id, |
bsw/jbe@0 | 213 params = { tab = "suggestion" } |
bsw/jbe@0 | 214 } |
bsw/jbe@0 | 215 }, |
bsw/jbe@0 | 216 attr = { class = "vertical" }, |
bsw/jbe@0 | 217 content = function() |
bsw/jbe@4 | 218 local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false |
bsw/jbe@4 | 219 if not supported then |
bsw/jbe@4 | 220 ui.field.text{ |
bsw/jbe@4 | 221 attr = { class = "warning" }, |
bsw/jbe@4 | 222 value = _"You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter." |
bsw/jbe@4 | 223 } |
bsw/jbe@4 | 224 end |
bsw/jbe@4 | 225 ui.field.text{ label = _"Title (80 chars max)", name = "name" } |
bsw/jbe@0 | 226 ui.field.text{ label = _"Description", name = "description", multiline = true } |
bsw/jbe@0 | 227 ui.field.select{ |
bsw/jbe@0 | 228 label = _"Degree", |
bsw/jbe@0 | 229 name = "degree", |
bsw/jbe@0 | 230 foreign_records = { |
bsw/jbe@0 | 231 { id = 1, name = _"should"}, |
bsw/jbe@0 | 232 { id = 2, name = _"must"}, |
bsw/jbe@0 | 233 }, |
bsw/jbe@0 | 234 foreign_id = "id", |
bsw/jbe@0 | 235 foreign_name = "name" |
bsw/jbe@0 | 236 } |
bsw/jbe@0 | 237 ui.submit{ text = _"Commit suggestion" } |
bsw/jbe@0 | 238 end |
bsw/jbe@0 | 239 } |
bsw/jbe@0 | 240 end |
bsw/jbe@0 | 241 } |
bsw/jbe@0 | 242 |
bsw@2 | 243 local supporter = app.session.member:get_reference_selector("supporters") |
bsw@2 | 244 :add_where{ "initiative_id = ?", initiative.id } |
bsw@2 | 245 :optional_object_mode() |
bsw@2 | 246 :exec() |
bsw@2 | 247 |
bsw@2 | 248 if supporter then |
bsw@2 | 249 local old_draft_id = supporter.draft_id |
bsw@2 | 250 local new_draft_id = initiative.current_draft.id |
bsw@2 | 251 if old_draft_id ~= new_draft_id then |
bsw@2 | 252 ui.container{ |
bsw@2 | 253 attr = { class = "draft_updated_info" }, |
bsw@2 | 254 content = function() |
bsw@11 | 255 slot.put(_"The draft of this initiative has been updated!") |
bsw@2 | 256 slot.put(" ") |
bsw@2 | 257 ui.link{ |
bsw@2 | 258 content = _"Show diff", |
bsw@2 | 259 module = "draft", |
bsw@2 | 260 view = "diff", |
bsw@2 | 261 params = { |
bsw@2 | 262 old_draft_id = old_draft_id, |
bsw@2 | 263 new_draft_id = new_draft_id |
bsw@2 | 264 } |
bsw@2 | 265 } |
bsw@2 | 266 slot.put(" ") |
bsw@2 | 267 ui.link{ |
bsw@2 | 268 content = _"Refresh support to current draft", |
bsw@2 | 269 module = "initiative", |
bsw@2 | 270 action = "add_support", |
bsw@2 | 271 id = initiative.id, |
bsw@2 | 272 routing = { |
bsw@2 | 273 default = { |
bsw@2 | 274 mode = "redirect", |
bsw@2 | 275 module = "initiative", |
bsw@2 | 276 view = "show", |
bsw@2 | 277 id = initiative.id |
bsw@2 | 278 } |
bsw@2 | 279 } |
bsw@2 | 280 } |
bsw@2 | 281 end |
bsw@2 | 282 } |
bsw@2 | 283 end |
bsw@2 | 284 end |
bsw/jbe@0 | 285 |
bsw/jbe@4 | 286 |
bsw/jbe@6 | 287 local current_draft_name = _"Current draft" |
bsw/jbe@6 | 288 if initiative.issue.half_frozen then |
bsw/jbe@6 | 289 current_draft_name = _"Voting proposal" |
bsw/jbe@6 | 290 end |
bsw/jbe@6 | 291 |
bsw/jbe@6 | 292 if initiative.issue.state == "finished" then |
bsw/jbe@6 | 293 current_draft_name = _"Voted proposal" |
bsw/jbe@6 | 294 end |
bsw/jbe@6 | 295 |
bsw/jbe@6 | 296 local tabs = { |
bsw/jbe@0 | 297 { |
bsw/jbe@0 | 298 name = "current_draft", |
bsw/jbe@6 | 299 label = current_draft_name, |
bsw/jbe@0 | 300 content = function() |
bsw@10 | 301 if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then |
bsw/jbe@4 | 302 ui.link{ |
bsw/jbe@4 | 303 content = function() |
bsw/jbe@4 | 304 ui.image{ static = "icons/16/script_add.png" } |
bsw/jbe@4 | 305 slot.put(_"Edit draft") |
bsw/jbe@4 | 306 end, |
bsw/jbe@4 | 307 module = "draft", |
bsw/jbe@4 | 308 view = "new", |
bsw/jbe@4 | 309 params = { initiative_id = initiative.id } |
bsw/jbe@4 | 310 } |
bsw/jbe@4 | 311 end |
bsw/jbe@0 | 312 execute.view{ module = "draft", view = "_show", params = { draft = initiative.current_draft } } |
bsw/jbe@0 | 313 end |
bsw/jbe@6 | 314 } |
bsw/jbe@6 | 315 } |
bsw/jbe@6 | 316 |
bsw/jbe@6 | 317 if initiative.issue.ranks_available then |
bsw/jbe@6 | 318 tabs[#tabs+1] = { |
bsw/jbe@6 | 319 name = "voter", |
bsw/jbe@6 | 320 label = _"Voter", |
bsw/jbe@0 | 321 content = function() |
bsw@3 | 322 execute.view{ |
bsw@3 | 323 module = "member", |
bsw@3 | 324 view = "_list", |
bsw@3 | 325 params = { |
bsw@3 | 326 initiative = initiative, |
bsw/jbe@6 | 327 members_selector = initiative.issue:get_reference_selector("direct_voters") |
bsw/jbe@6 | 328 :left_join("vote", nil, { "vote.initiative_id = ? AND vote.member_id = member.id", initiative.id }) |
bsw/jbe@6 | 329 :add_field("direct_voter.weight as voter_weight") |
bsw/jbe@6 | 330 :add_field("coalesce(vote.grade, 0) as grade") |
bsw@3 | 331 } |
bsw@3 | 332 } |
bsw/jbe@0 | 333 end |
bsw/jbe@6 | 334 } |
bsw/jbe@6 | 335 end |
bsw/jbe@6 | 336 |
bsw@10 | 337 local suggestion_count = initiative:get_reference_selector("suggestions"):count() |
bsw@10 | 338 |
bsw/jbe@6 | 339 tabs[#tabs+1] = { |
bsw/jbe@6 | 340 name = "suggestion", |
bsw@10 | 341 label = _"Suggestions" .. " (" .. tostring(suggestion_count) .. ")", |
bsw/jbe@6 | 342 content = function() |
bsw/jbe@6 | 343 execute.view{ |
bsw/jbe@6 | 344 module = "suggestion", |
bsw/jbe@6 | 345 view = "_list", |
bsw/jbe@6 | 346 params = { |
bsw/jbe@6 | 347 initiative = initiative, |
bsw/jbe@6 | 348 suggestions_selector = initiative:get_reference_selector("suggestions") |
bsw/jbe@6 | 349 } |
bsw/jbe@6 | 350 } |
bsw/jbe@6 | 351 slot.put("<br />") |
bsw@10 | 352 if not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then |
bsw/jbe@6 | 353 ui.link{ |
bsw@2 | 354 content = function() |
bsw/jbe@6 | 355 ui.image{ static = "icons/16/comment_add.png" } |
bsw/jbe@6 | 356 slot.put(_"Add new suggestion") |
bsw/jbe@6 | 357 end, |
bsw/jbe@6 | 358 attr = { onclick = "document.getElementById('add_suggestion_form').style.display='block';return(false)" }, |
bsw/jbe@6 | 359 static = "#" |
bsw@2 | 360 } |
bsw@2 | 361 end |
bsw/jbe@6 | 362 end |
bsw/jbe@6 | 363 } |
bsw/jbe@6 | 364 |
bsw@11 | 365 local members_selector = initiative:get_reference_selector("supporting_members_snapshot") |
bsw@10 | 366 :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") |
bsw@10 | 367 :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id") |
bsw@10 | 368 :add_field("direct_interest_snapshot.weight") |
bsw@10 | 369 :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") |
bsw@10 | 370 :add_where("direct_supporter_snapshot.satisfied") |
bsw@10 | 371 |
bsw@11 | 372 local tmp = db:query("SELECT count(1) AS count, sum(weight) AS weight FROM (" .. tostring(members_selector) .. ") as subquery", "object") |
bsw@11 | 373 local direct_satisfied_supporter_count = tmp.count |
bsw@11 | 374 local indirect_satisfied_supporter_count = (tmp.weight or 0) - tmp.count |
bsw@11 | 375 |
bsw@11 | 376 local count_string |
bsw@11 | 377 if indirect_satisfied_supporter_count > 0 then |
bsw@11 | 378 count_string = "(" .. tostring(direct_satisfied_supporter_count) .. "+" .. tostring(indirect_satisfied_supporter_count) .. ")" |
bsw@11 | 379 else |
bsw@11 | 380 count_string = "(" .. tostring(direct_satisfied_supporter_count) .. ")" |
bsw@11 | 381 end |
bsw@10 | 382 |
bsw/jbe@6 | 383 tabs[#tabs+1] = { |
bsw/jbe@6 | 384 name = "satisfied_supporter", |
bsw@11 | 385 label = _"Supporter" .. " " .. count_string, |
bsw@10 | 386 content = function() |
bsw@10 | 387 execute.view{ |
bsw@10 | 388 module = "member", |
bsw@10 | 389 view = "_list", |
bsw@10 | 390 params = { |
bsw@10 | 391 initiative = initiative, |
bsw@10 | 392 members_selector = members_selector |
bsw@10 | 393 } |
bsw@10 | 394 } |
bsw@10 | 395 end |
bsw@10 | 396 } |
bsw@10 | 397 |
bsw@10 | 398 local members_selector = initiative:get_reference_selector("supporting_members_snapshot") |
bsw@10 | 399 :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") |
bsw@10 | 400 :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id") |
bsw@10 | 401 :add_field("direct_interest_snapshot.weight") |
bsw@10 | 402 :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") |
bsw@10 | 403 :add_where("NOT direct_supporter_snapshot.satisfied") |
bsw@10 | 404 |
bsw@11 | 405 local tmp = db:query("SELECT count(1) AS count, sum(weight) AS weight FROM (" .. tostring(members_selector) .. ") as subquery", "object") |
bsw@11 | 406 local direct_potential_supporter_count = tmp.count |
bsw@11 | 407 local indirect_potential_supporter_count = (tmp.weight or 0) - tmp.count |
bsw@11 | 408 |
bsw@11 | 409 local count_string |
bsw@11 | 410 if indirect_potential_supporter_count > 0 then |
bsw@11 | 411 count_string = "(" .. tostring(direct_potential_supporter_count) .. "+" .. tostring(indirect_potential_supporter_count) .. ")" |
bsw@11 | 412 else |
bsw@11 | 413 count_string = "(" .. tostring(direct_potential_supporter_count) .. ")" |
bsw@11 | 414 end |
bsw@10 | 415 |
bsw@10 | 416 tabs[#tabs+1] = { |
bsw@10 | 417 name = "supporter", |
bsw@11 | 418 label = _"Potential supporter" .. " " .. count_string, |
bsw/jbe@6 | 419 content = function() |
bsw/jbe@6 | 420 execute.view{ |
bsw/jbe@6 | 421 module = "member", |
bsw/jbe@6 | 422 view = "_list", |
bsw/jbe@6 | 423 params = { |
bsw/jbe@6 | 424 initiative = initiative, |
bsw@10 | 425 members_selector = members_selector |
bsw/jbe@6 | 426 } |
bsw/jbe@6 | 427 } |
bsw/jbe@6 | 428 end |
bsw/jbe@6 | 429 } |
bsw/jbe@6 | 430 |
bsw@10 | 431 local initiator_count = initiative:get_reference_selector("initiators"):add_where("accepted"):count() |
bsw@10 | 432 |
bsw/jbe@6 | 433 tabs[#tabs+1] = { |
bsw@10 | 434 name = "initiators", |
bsw@10 | 435 label = _"Initiators" .. " (" .. tostring(initiator_count) .. ")", |
bsw/jbe@6 | 436 content = function() |
bsw@10 | 437 if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then |
bsw@10 | 438 ui.link{ |
bsw@10 | 439 attr = { class = "action" }, |
bsw@10 | 440 content = function() |
bsw@10 | 441 ui.image{ static = "icons/16/user_add.png" } |
bsw@10 | 442 slot.put(_"Invite initiator") |
bsw@10 | 443 end, |
bsw@10 | 444 module = "initiative", |
bsw@10 | 445 view = "add_initiator", |
bsw@10 | 446 params = { initiative_id = initiative.id } |
bsw@10 | 447 } |
bsw@10 | 448 if initiator_count > 1 then |
bsw@10 | 449 ui.link{ |
bsw@10 | 450 content = function() |
bsw@10 | 451 ui.image{ static = "icons/16/user_delete.png" } |
bsw@10 | 452 slot.put(_"Remove initiator") |
bsw@10 | 453 end, |
bsw@10 | 454 module = "initiative", |
bsw@10 | 455 view = "remove_initiator", |
bsw@10 | 456 params = { initiative_id = initiative.id } |
bsw@10 | 457 } |
bsw@10 | 458 end |
bsw@10 | 459 end |
bsw@10 | 460 if initiator and initiator.accepted == false then |
bsw@10 | 461 ui.link{ |
bsw@10 | 462 content = function() |
bsw@10 | 463 ui.image{ static = "icons/16/user_delete.png" } |
bsw@10 | 464 slot.put(_"Cancel refuse of invitation") |
bsw@10 | 465 end, |
bsw@10 | 466 module = "initiative", |
bsw@10 | 467 action = "remove_initiator", |
bsw@10 | 468 params = { |
bsw@10 | 469 initiative_id = initiative.id, |
bsw@10 | 470 member_id = app.session.member.id |
bsw@10 | 471 }, |
bsw@10 | 472 routing = { |
bsw@10 | 473 ok = { |
bsw@10 | 474 mode = "redirect", |
bsw@10 | 475 module = "initiative", |
bsw@10 | 476 view = "show", |
bsw@10 | 477 id = initiative.id |
bsw@10 | 478 } |
bsw@10 | 479 } |
bsw@10 | 480 } |
bsw@10 | 481 end |
bsw@10 | 482 local members_selector = initiative:get_reference_selector("initiating_members") |
bsw@10 | 483 :add_field("initiator.accepted", "accepted") |
bsw@10 | 484 if not (initiator and initiator.accepted) then |
bsw@10 | 485 members_selector:add_where("accepted") |
bsw@10 | 486 end |
bsw/jbe@6 | 487 execute.view{ |
bsw/jbe@6 | 488 module = "member", |
bsw/jbe@6 | 489 view = "_list", |
bsw/jbe@6 | 490 params = { |
bsw@10 | 491 members_selector = members_selector, |
bsw@10 | 492 initiator = initiator |
bsw/jbe@6 | 493 } |
bsw/jbe@6 | 494 } |
bsw/jbe@6 | 495 end |
bsw/jbe@6 | 496 } |
bsw/jbe@6 | 497 |
bsw@10 | 498 local drafts_count = initiative:get_reference_selector("drafts"):count() |
bsw/jbe@6 | 499 |
bsw/jbe@6 | 500 tabs[#tabs+1] = { |
bsw/jbe@6 | 501 name = "drafts", |
bsw@10 | 502 label = _"Draft history" .. " (" .. tostring(drafts_count) .. ")", |
bsw/jbe@6 | 503 content = function() |
bsw/jbe@6 | 504 execute.view{ module = "draft", view = "_list", params = { drafts = initiative.drafts } } |
bsw/jbe@6 | 505 end |
bsw/jbe@6 | 506 } |
bsw/jbe@6 | 507 |
bsw/jbe@6 | 508 tabs[#tabs+1] = { |
bsw/jbe@6 | 509 name = "details", |
bsw/jbe@6 | 510 label = _"Details", |
bsw/jbe@6 | 511 content = function() |
bsw/jbe@6 | 512 ui.form{ |
bsw/jbe@6 | 513 attr = { class = "vertical" }, |
bsw/jbe@6 | 514 record = initiative, |
bsw/jbe@6 | 515 readonly = true, |
bsw/jbe@6 | 516 content = function() |
bsw/jbe@6 | 517 ui.field.text{ label = _"Issue policy", value = initiative.issue.policy.name } |
bsw/jbe@6 | 518 ui.field.text{ |
bsw/jbe@6 | 519 label = _"Created at", |
bsw/jbe@6 | 520 value = tostring(initiative.created) |
bsw/jbe@6 | 521 } |
bsw/jbe@6 | 522 ui.field.text{ |
bsw/jbe@6 | 523 label = _"Created at", |
bsw/jbe@6 | 524 value = format.timestamp(initiative.created) |
bsw/jbe@6 | 525 } |
bsw@10 | 526 -- ui.field.date{ label = _"Revoked at", name = "revoked" } |
bsw/jbe@6 | 527 ui.field.boolean{ label = _"Admitted", name = "admitted" } |
bsw/jbe@6 | 528 end |
bsw/jbe@6 | 529 } |
bsw/jbe@6 | 530 end |
bsw/jbe@0 | 531 } |
bsw/jbe@0 | 532 |
bsw/jbe@0 | 533 |
bsw/jbe@6 | 534 ui.tabs(tabs) |
bsw/jbe@6 | 535 |