rev |
line source |
bsw/jbe@19
|
1 local issue = Issue:by_id(param.get("issue_id"), atom.integer)
|
bsw/jbe@19
|
2
|
bsw/jbe@1309
|
3 -- TODO patch for project voting
|
bsw/jbe@1309
|
4 if not issue.closed and config.alternative_voting and config.alternative_voting[tostring(issue.policy.id)] then
|
bsw/jbe@1309
|
5 local voting_config = config.alternative_voting[tostring(issue.policy.id)]
|
bsw/jbe@1309
|
6
|
bsw/jbe@1309
|
7 local url = encode.url {
|
bsw/jbe@1309
|
8 module = voting_config.module,
|
bsw/jbe@1309
|
9 view = voting_config.view,
|
bsw/jbe@1309
|
10 params = { issue_id = issue.id }
|
bsw/jbe@1309
|
11 }
|
bsw/jbe@1309
|
12
|
bsw/jbe@1309
|
13 return request.redirect{ external = url }
|
bsw/jbe@1309
|
14 end
|
bsw/jbe@1309
|
15
|
bsw/jbe@1309
|
16 if not issue then
|
bsw/jbe@1309
|
17 execute.view { module = "index", view = "404" }
|
bsw/jbe@1309
|
18 return
|
bsw/jbe@1309
|
19 end
|
bsw/jbe@1309
|
20
|
bsw/jbe@19
|
21 local member_id = param.get("member_id", atom.integer)
|
bsw/jbe@19
|
22 local member
|
jbe@945
|
23 local readonly = false
|
bsw/jbe@19
|
24
|
jbe@950
|
25 local preview = param.get("preview") and true or false
|
poelzi@156
|
26
|
bsw/jbe@19
|
27 if member_id then
|
bsw/jbe@1309
|
28 if not issue.closed then
|
bsw/jbe@1309
|
29 execute.view{ module = "index", view = "403" }
|
bsw/jbe@1309
|
30 return
|
bsw/jbe@19
|
31 end
|
bsw/jbe@19
|
32 member = Member:by_id(member_id)
|
bsw/jbe@19
|
33 readonly = true
|
bsw/jbe@19
|
34 end
|
bsw/jbe@19
|
35
|
poelzi@138
|
36 if issue.closed then
|
poelzi@156
|
37 if not member then
|
poelzi@158
|
38 member = app.session.member
|
poelzi@158
|
39 end
|
poelzi@156
|
40 readonly = true
|
poelzi@138
|
41 end
|
poelzi@138
|
42
|
bsw@1045
|
43 if preview then
|
bsw@1045
|
44 readonly = true
|
bsw@1045
|
45 end
|
bsw@1045
|
46
|
bsw@879
|
47 local submit_button_text = _"Finish voting"
|
bsw@1045
|
48 local edit_button_text = _"Edit again"
|
bsw@879
|
49
|
bsw@879
|
50 if issue.closed then
|
bsw@1045
|
51 submit_button_text = _"Save voting comment"
|
bsw@1045
|
52 edit_button_text = _"Edit voting comment"
|
bsw@879
|
53 end
|
bsw@879
|
54
|
bsw@1045
|
55 execute.view {
|
bsw@1045
|
56 module = "issue", view = "_head", params = { issue = issue }
|
bsw@1045
|
57 }
|
bsw@1045
|
58
|
bsw@879
|
59 local direct_voter
|
bsw@879
|
60
|
bsw/jbe@19
|
61 if member then
|
bsw@879
|
62 direct_voter = DirectVoter:by_pk(issue.id, member.id)
|
bsw/jbe@19
|
63 else
|
bsw/jbe@19
|
64 member = app.session.member
|
bsw@879
|
65 direct_voter = DirectVoter:by_pk(issue.id, member.id)
|
bsw/jbe@19
|
66 end
|
bsw/jbe@19
|
67
|
bsw/jbe@19
|
68
|
bsw@879
|
69
|
bsw/jbe@19
|
70 local tempvoting_string = param.get("scoring")
|
bsw/jbe@19
|
71
|
bsw/jbe@19
|
72 local tempvotings = {}
|
bsw/jbe@19
|
73 if tempvoting_string then
|
bsw/jbe@19
|
74 for match in tempvoting_string:gmatch("([^;]+)") do
|
bsw/jbe@19
|
75 for initiative_id, grade in match:gmatch("([^:;]+):([^:;]+)") do
|
bsw/jbe@19
|
76 tempvotings[tonumber(initiative_id)] = tonumber(grade)
|
bsw/jbe@19
|
77 end
|
bsw/jbe@5
|
78 end
|
bsw/jbe@19
|
79 end
|
bsw/jbe@5
|
80
|
bsw@95
|
81 local initiatives = issue:get_reference_selector("initiatives"):add_where("initiative.admitted"):add_order_by("initiative.satisfied_supporter_count DESC"):exec()
|
bsw/jbe@5
|
82
|
bsw/jbe@5
|
83 local min_grade = -1;
|
bsw/jbe@5
|
84 local max_grade = 1;
|
bsw/jbe@5
|
85
|
bsw/jbe@5
|
86 for i, initiative in ipairs(initiatives) do
|
bsw/jbe@5
|
87 -- TODO performance
|
bsw/jbe@19
|
88 initiative.vote = Vote:by_pk(initiative.id, member.id)
|
bsw/jbe@19
|
89 if tempvotings[initiative.id] then
|
bsw/jbe@19
|
90 initiative.vote = {}
|
bsw/jbe@19
|
91 initiative.vote.grade = tempvotings[initiative.id]
|
bsw/jbe@19
|
92 end
|
bsw/jbe@5
|
93 if initiative.vote then
|
bsw/jbe@5
|
94 if initiative.vote.grade > max_grade then
|
bsw/jbe@5
|
95 max_grade = initiative.vote.grade
|
bsw/jbe@5
|
96 end
|
bsw/jbe@5
|
97 if initiative.vote.grade < min_grade then
|
bsw/jbe@5
|
98 min_grade = initiative.vote.grade
|
bsw/jbe@5
|
99 end
|
bsw/jbe@5
|
100 end
|
bsw/jbe@5
|
101 end
|
bsw/jbe@5
|
102
|
bsw/jbe@5
|
103 local sections = {}
|
bsw/jbe@5
|
104 for i = min_grade, max_grade do
|
bsw/jbe@5
|
105 sections[i] = {}
|
bsw/jbe@5
|
106 for j, initiative in ipairs(initiatives) do
|
bsw/jbe@5
|
107 if (initiative.vote and initiative.vote.grade == i) or (not initiative.vote and i == 0) then
|
bsw/jbe@5
|
108 sections[i][#(sections[i])+1] = initiative
|
bsw/jbe@5
|
109 end
|
bsw/jbe@5
|
110 end
|
bsw/jbe@5
|
111 end
|
bsw/jbe@5
|
112
|
bsw/jbe@19
|
113 local approval_count, disapproval_count = 0, 0
|
bsw/jbe@19
|
114 for i = min_grade, -1 do
|
bsw/jbe@19
|
115 if #sections[i] > 0 then
|
bsw/jbe@19
|
116 disapproval_count = disapproval_count + 1
|
bsw/jbe@19
|
117 end
|
bsw/jbe@19
|
118 end
|
bsw/jbe@19
|
119 local approval_count = 0
|
bsw/jbe@19
|
120 for i = 1, max_grade do
|
bsw/jbe@19
|
121 if #sections[i] > 0 then
|
bsw/jbe@19
|
122 approval_count = approval_count + 1
|
bsw/jbe@19
|
123 end
|
bsw/jbe@19
|
124 end
|
bsw/jbe@5
|
125
|
bsw/jbe@19
|
126 if not readonly then
|
bsw/jbe@19
|
127 slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/dragdrop.js"></script>')
|
bsw/jbe@19
|
128 slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/voting.js"></script>')
|
bsw/jbe@19
|
129 end
|
bsw/jbe@19
|
130
|
bsw/jbe@19
|
131 ui.script{
|
bsw/jbe@19
|
132 script = function()
|
bsw/jbe@19
|
133 slot.put(
|
bsw/jbe@19
|
134 "voting_text_approval_single = ", encode.json(_"Approval [single entry]"), ";\n",
|
bsw/jbe@19
|
135 "voting_text_approval_multi = ", encode.json(_"Approval [many entries]"), ";\n",
|
bsw/jbe@19
|
136 "voting_text_first_preference_single = ", encode.json(_"Approval (first preference) [single entry]"), ";\n",
|
bsw/jbe@19
|
137 "voting_text_first_preference_multi = ", encode.json(_"Approval (first preference) [many entries]"), ";\n",
|
bsw/jbe@19
|
138 "voting_text_second_preference_single = ", encode.json(_"Approval (second preference) [single entry]"), ";\n",
|
bsw/jbe@19
|
139 "voting_text_second_preference_multi = ", encode.json(_"Approval (second preference) [many entries]"), ";\n",
|
bsw/jbe@19
|
140 "voting_text_third_preference_single = ", encode.json(_"Approval (third preference) [single entry]"), ";\n",
|
bsw/jbe@19
|
141 "voting_text_third_preference_multi = ", encode.json(_"Approval (third preference) [many entries]"), ";\n",
|
bsw/jbe@19
|
142 "voting_text_numeric_preference_single = ", encode.json(_"Approval (#th preference) [single entry]"), ";\n",
|
bsw/jbe@19
|
143 "voting_text_numeric_preference_multi = ", encode.json(_"Approval (#th preference) [many entries]"), ";\n",
|
bsw/jbe@19
|
144 "voting_text_abstention_single = ", encode.json(_"Abstention [single entry]"), ";\n",
|
bsw/jbe@19
|
145 "voting_text_abstention_multi = ", encode.json(_"Abstention [many entries]"), ";\n",
|
bsw/jbe@19
|
146 "voting_text_disapproval_above_one_single = ", encode.json(_"Disapproval (prefer to lower block) [single entry]"), ";\n",
|
bsw/jbe@19
|
147 "voting_text_disapproval_above_one_multi = ", encode.json(_"Disapproval (prefer to lower block) [many entries]"), ";\n",
|
bsw/jbe@19
|
148 "voting_text_disapproval_above_many_single = ", encode.json(_"Disapproval (prefer to lower blocks) [single entry]"), ";\n",
|
bsw/jbe@19
|
149 "voting_text_disapproval_above_many_multi = ", encode.json(_"Disapproval (prefer to lower blocks) [many entries]"), ";\n",
|
bsw/jbe@19
|
150 "voting_text_disapproval_above_last_single = ", encode.json(_"Disapproval (prefer to last block) [single entry]"), ";\n",
|
bsw/jbe@19
|
151 "voting_text_disapproval_above_last_multi = ", encode.json(_"Disapproval (prefer to last block) [many entries]"), ";\n",
|
bsw/jbe@19
|
152 "voting_text_disapproval_single = ", encode.json(_"Disapproval [single entry]"), ";\n",
|
bsw/jbe@19
|
153 "voting_text_disapproval_multi = ", encode.json(_"Disapproval [many entries]"), ";\n"
|
bsw/jbe@19
|
154 )
|
bsw/jbe@19
|
155 end
|
bsw/jbe@19
|
156 }
|
bsw/jbe@5
|
157
|
bsw@1045
|
158 if issue.state == "finished_with_winner"
|
bsw@1045
|
159 or issue.state == "finished_without_winner"
|
bsw@1045
|
160 then
|
bsw@1045
|
161
|
bsw@1045
|
162 local members_selector = Member:new_selector()
|
bsw@1045
|
163 :join("delegating_voter", nil, "delegating_voter.member_id = member.id")
|
bsw@1045
|
164 :add_where{ "delegating_voter.issue_id = ?", issue.id }
|
bsw@1045
|
165 :add_where{ "delegating_voter.delegate_member_ids[1] = ?", member.id }
|
bsw@1045
|
166 :add_field("delegating_voter.weight", "voter_weight")
|
bsw@1557
|
167 :add_field("delegating_voter.ownweight", "ownweight")
|
bsw@1045
|
168 :join("issue", nil, "issue.id = delegating_voter.issue_id")
|
bsw@1045
|
169
|
bsw@1045
|
170 ui.sidebar( "tab-members", function()
|
bsw@1045
|
171 ui.sidebarHead(function()
|
bsw/jbe@1309
|
172 ui.heading{ level = 4, content = _"Incoming delegations" }
|
bsw@1045
|
173 end)
|
bsw@1045
|
174 execute.view{
|
bsw@1045
|
175 module = "member",
|
bsw@1045
|
176 view = "_list",
|
bsw@1045
|
177 params = {
|
bsw@1045
|
178 members_selector = members_selector,
|
bsw@1045
|
179 trustee = member,
|
bsw@1045
|
180 issue = issue,
|
bsw@1045
|
181 initiative = initiative,
|
bsw@1045
|
182 for_votes = true, no_filter = true,
|
bsw@1045
|
183 member_class = "sidebarRow sidebarRowNarrow",
|
bsw/jbe@5
|
184 }
|
bsw@1045
|
185 }
|
bsw@1045
|
186 end)
|
bsw@1045
|
187 end
|
bsw@1045
|
188
|
bsw/jbe@1309
|
189 ui.container{ attr = { class = "mdl-grid" }, content = function()
|
bsw/jbe@1309
|
190 ui.container{ attr = { class = "mdl-cell mdl-cell--12-col" }, content = function()
|
bsw@1045
|
191
|
bsw/jbe@1309
|
192 ui.container{ attr = { class = "mdl-card mdl-card__fullwidth mdl-shadow--2dp" }, content = function()
|
bsw/jbe@1309
|
193 ui.container{ attr = { class = "mdl-card__title mdl-card--border" }, content = function()
|
bsw/jbe@1309
|
194 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = function()
|
bsw/jbe@1309
|
195 if preview then
|
bsw/jbe@1309
|
196 ui.tag{ content = _"Preview of voting ballot" }
|
bsw/jbe@1309
|
197 elseif readonly then
|
bsw/jbe@1309
|
198 local str = _("Ballot of '#{member_name}'", { member_name = string.format(
|
bsw/jbe@1309
|
199 '<a href="%s">%s</a>',
|
bsw/jbe@1309
|
200 encode.url{ module = "member", view = "show", id = member.id },
|
bsw/jbe@1309
|
201 encode.html(member.name)
|
bsw/jbe@1309
|
202 ) })
|
bsw/jbe@1309
|
203 ui.tag{ content = function () slot.put ( str ) end }
|
bsw/jbe@1309
|
204 else
|
bsw/jbe@1309
|
205 ui.tag{ content = _"Voting" }
|
bsw/jbe@5
|
206 end
|
bsw/jbe@1309
|
207 end }
|
bsw/jbe@1309
|
208 end }
|
bsw/jbe@1309
|
209
|
bsw/jbe@1309
|
210 ui.container{ attr = { class = "mdl-card__content" }, content = function()
|
bsw/jbe@1309
|
211
|
bsw/jbe@1309
|
212 ui.form{
|
bsw/jbe@1309
|
213 record = direct_voter,
|
bsw/jbe@1309
|
214 attr = {
|
bsw/jbe@1309
|
215 id = "voting_form",
|
bsw/jbe@1309
|
216 class = readonly and "voting_form_readonly" or "voting_form_active"
|
bsw/jbe@1309
|
217 },
|
bsw/jbe@1309
|
218 module = "vote",
|
bsw/jbe@1309
|
219 action = "update",
|
bsw/jbe@1309
|
220 params = { issue_id = issue.id },
|
bsw@1045
|
221 content = function()
|
bsw/jbe@1309
|
222 if not readonly or preview then
|
bsw/jbe@1309
|
223 local scoring = param.get("scoring")
|
bsw/jbe@1309
|
224 if not scoring then
|
bsw/jbe@1309
|
225 for i, initiative in ipairs(initiatives) do
|
bsw/jbe@1309
|
226 local vote = initiative.vote
|
bsw/jbe@1309
|
227 if vote then
|
bsw/jbe@1309
|
228 tempvotings[initiative.id] = vote.grade
|
bsw/jbe@1309
|
229 else
|
bsw/jbe@1309
|
230 tempvotings[initiative.id] = 0
|
bsw/jbe@1309
|
231 end
|
bsw/jbe@1309
|
232 end
|
bsw/jbe@1309
|
233 local tempvotings_list = {}
|
bsw/jbe@1309
|
234 for key, val in pairs(tempvotings) do
|
bsw/jbe@1309
|
235 tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val)
|
bsw/jbe@1309
|
236 end
|
bsw/jbe@1309
|
237 if #tempvotings_list > 0 then
|
bsw/jbe@1309
|
238 scoring = table.concat(tempvotings_list, ";")
|
bsw/jbe@1309
|
239 else
|
bsw/jbe@1309
|
240 scoring = ""
|
bsw/jbe@1309
|
241 end
|
bsw@1045
|
242 end
|
bsw/jbe@1309
|
243 slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>')
|
bsw/jbe@1309
|
244 end
|
bsw/jbe@1309
|
245 if preview then
|
bsw/jbe@1309
|
246 ui.container{ content = _"Your choice" }
|
bsw/jbe@1309
|
247 elseif not readonly then
|
bsw/jbe@1309
|
248 ui.container{ content = _"Make your choice by placing the initiatives" }
|
bsw/jbe@1309
|
249 end
|
bsw/jbe@1309
|
250
|
bsw/jbe@1309
|
251 ui.container{
|
bsw/jbe@1309
|
252 attr = { id = "voting" },
|
bsw/jbe@1309
|
253 content = function()
|
bsw/jbe@1309
|
254 local approval_index, disapproval_index = 0, 0
|
bsw/jbe@1309
|
255 local approval_used, disapproval_used
|
bsw/jbe@1309
|
256 for grade = max_grade, min_grade, -1 do
|
bsw/jbe@1309
|
257 local entries = sections[grade]
|
bsw/jbe@1309
|
258 local class
|
bsw/jbe@1309
|
259 if grade > 0 then
|
bsw/jbe@1309
|
260 class = "approval"
|
bsw/jbe@1309
|
261 elseif grade < 0 then
|
bsw/jbe@1309
|
262 class = "disapproval"
|
bsw/jbe@1309
|
263 else
|
bsw/jbe@1309
|
264 class = "abstention"
|
bsw/jbe@1309
|
265 end
|
bsw/jbe@1309
|
266 if
|
bsw/jbe@1309
|
267 #entries > 0 or
|
bsw/jbe@1309
|
268 (grade == 1 and not approval_used) or
|
bsw/jbe@1309
|
269 (grade == -1 and not disapproval_used) or
|
bsw/jbe@1309
|
270 grade == 0
|
bsw/jbe@1309
|
271 then
|
bsw/jbe@1309
|
272 ui.container{
|
bsw/jbe@1309
|
273 attr = { class = class },
|
bsw/jbe@1309
|
274 content = function()
|
bsw/jbe@1309
|
275 local heading
|
bsw/jbe@1309
|
276 if class == "approval" then
|
bsw/jbe@1309
|
277 approval_used = true
|
bsw/jbe@1309
|
278 approval_index = approval_index + 1
|
bsw/jbe@1309
|
279 if approval_count > 1 then
|
bsw/jbe@1309
|
280 if approval_index == 1 then
|
bsw/jbe@1309
|
281 if #entries == 1 then
|
bsw/jbe@1309
|
282 heading = _"Approval (first preference) [single entry]"
|
bsw/jbe@1309
|
283 else
|
bsw/jbe@1309
|
284 heading = _"Approval (first preference) [many entries]"
|
bsw/jbe@1309
|
285 end
|
bsw/jbe@1309
|
286 elseif approval_index == 2 then
|
bsw/jbe@1309
|
287 if #entries == 1 then
|
bsw/jbe@1309
|
288 heading = _"Approval (second preference) [single entry]"
|
bsw/jbe@1309
|
289 else
|
bsw/jbe@1309
|
290 heading = _"Approval (second preference) [many entries]"
|
bsw/jbe@1309
|
291 end
|
bsw/jbe@1309
|
292 elseif approval_index == 3 then
|
bsw/jbe@1309
|
293 if #entries == 1 then
|
bsw/jbe@1309
|
294 heading = _"Approval (third preference) [single entry]"
|
bsw/jbe@1309
|
295 else
|
bsw/jbe@1309
|
296 heading = _"Approval (third preference) [many entries]"
|
bsw/jbe@1309
|
297 end
|
bsw/jbe@1309
|
298 else
|
bsw/jbe@1309
|
299 if #entries == 1 then
|
bsw/jbe@1309
|
300 heading = _"Approval (#th preference) [single entry]"
|
bsw/jbe@1309
|
301 else
|
bsw/jbe@1309
|
302 heading = _"Approval (#th preference) [many entries]"
|
bsw/jbe@1309
|
303 end
|
bsw/jbe@1309
|
304 end
|
bsw@1045
|
305 else
|
bsw/jbe@1309
|
306 if #entries == 1 then
|
bsw/jbe@1309
|
307 heading = _"Approval [single entry]"
|
bsw/jbe@1309
|
308 else
|
bsw/jbe@1309
|
309 heading = _"Approval [many entries]"
|
bsw/jbe@1309
|
310 end
|
bsw@1045
|
311 end
|
bsw/jbe@1309
|
312 elseif class == "abstention" then
|
bsw/jbe@1309
|
313 if #entries == 1 then
|
bsw/jbe@1309
|
314 heading = _"Abstention [single entry]"
|
bsw/jbe@1309
|
315 else
|
bsw/jbe@1309
|
316 heading = _"Abstention [many entries]"
|
bsw/jbe@1309
|
317 end
|
bsw/jbe@1309
|
318 elseif class == "disapproval" then
|
bsw/jbe@1309
|
319 disapproval_used = true
|
bsw/jbe@1309
|
320 disapproval_index = disapproval_index + 1
|
bsw/jbe@1309
|
321 if disapproval_count > disapproval_index + 1 then
|
bsw/jbe@1309
|
322 if #entries == 1 then
|
bsw/jbe@1309
|
323 heading = _"Disapproval (prefer to lower blocks) [single entry]"
|
bsw/jbe@1309
|
324 else
|
bsw/jbe@1309
|
325 heading = _"Disapproval (prefer to lower blocks) [many entries]"
|
bsw/jbe@1309
|
326 end
|
bsw/jbe@1309
|
327 elseif disapproval_count == 2 and disapproval_index == 1 then
|
bsw/jbe@1309
|
328 if #entries == 1 then
|
bsw/jbe@1309
|
329 heading = _"Disapproval (prefer to lower block) [single entry]"
|
bsw/jbe@1309
|
330 else
|
bsw/jbe@1309
|
331 heading = _"Disapproval (prefer to lower block) [many entries]"
|
bsw/jbe@1309
|
332 end
|
bsw/jbe@1309
|
333 elseif disapproval_index == disapproval_count - 1 then
|
bsw/jbe@1309
|
334 if #entries == 1 then
|
bsw/jbe@1309
|
335 heading = _"Disapproval (prefer to last block) [single entry]"
|
bsw/jbe@1309
|
336 else
|
bsw/jbe@1309
|
337 heading = _"Disapproval (prefer to last block) [many entries]"
|
bsw/jbe@1309
|
338 end
|
bsw@1045
|
339 else
|
bsw/jbe@1309
|
340 if #entries == 1 then
|
bsw/jbe@1309
|
341 heading = _"Disapproval [single entry]"
|
bsw/jbe@1309
|
342 else
|
bsw/jbe@1309
|
343 heading = _"Disapproval [many entries]"
|
bsw/jbe@1309
|
344 end
|
bsw@1045
|
345 end
|
bsw@1045
|
346 end
|
bsw/jbe@1309
|
347 ui.tag {
|
bsw/jbe@1309
|
348 tag = "div",
|
bsw/jbe@1309
|
349 attr = { class = "cathead " },
|
bsw/jbe@1309
|
350 content = heading
|
bsw/jbe@1309
|
351 }
|
bsw/jbe@1309
|
352 for i, initiative in ipairs(entries) do
|
bsw@1045
|
353 ui.container{
|
bsw/jbe@1309
|
354 attr = {
|
bsw/jbe@1309
|
355 class = "movable",
|
bsw/jbe@1309
|
356 id = "entry_" .. tostring(initiative.id)
|
bsw/jbe@1309
|
357 },
|
bsw@1045
|
358 content = function()
|
bsw/jbe@1309
|
359 local initiators_selector = initiative:get_reference_selector("initiating_members")
|
bsw/jbe@1309
|
360 :add_where("accepted")
|
bsw/jbe@1309
|
361 local initiators = initiators_selector:exec()
|
bsw/jbe@1309
|
362 local initiator_names = {}
|
bsw/jbe@1309
|
363 for i, initiator in ipairs(initiators) do
|
bsw/jbe@1309
|
364 initiator_names[#initiator_names+1] = initiator.name
|
bsw/jbe@1309
|
365 end
|
bsw/jbe@1309
|
366 local initiator_names_string = table.concat(initiator_names, ", ")
|
bsw/jbe@1309
|
367 ui.container{
|
bsw/jbe@1309
|
368 attr = { style = "float: right; position: relative;" },
|
bsw/jbe@1309
|
369 content = function()
|
bsw/jbe@1309
|
370 ui.link{
|
bsw/jbe@1309
|
371 attr = { class = "clickable" },
|
bsw/jbe@1309
|
372 content = _"Show",
|
bsw/jbe@1309
|
373 module = "initiative",
|
bsw/jbe@1309
|
374 view = "show",
|
bsw/jbe@1309
|
375 id = initiative.id
|
bsw/jbe@1309
|
376 }
|
bsw/jbe@1309
|
377 slot.put(" ")
|
bsw/jbe@1309
|
378 ui.link{
|
bsw/jbe@1309
|
379 attr = { class = "clickable", target = "_blank" },
|
bsw/jbe@1309
|
380 content = _"(new window)",
|
bsw/jbe@1309
|
381 module = "initiative",
|
bsw/jbe@1309
|
382 view = "show",
|
bsw/jbe@1309
|
383 id = initiative.id
|
bsw/jbe@1309
|
384 }
|
bsw/jbe@1309
|
385 if not readonly then
|
bsw/jbe@1309
|
386 slot.put(" ")
|
bsw/jbe@1309
|
387 ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" }
|
bsw/jbe@1309
|
388 end
|
bsw/jbe@1309
|
389 end
|
bsw@1045
|
390 }
|
bsw@1045
|
391 if not readonly then
|
bsw/jbe@1309
|
392 ui.container{
|
bsw/jbe@1309
|
393 attr = { style = "float: left; position: relative;" },
|
bsw/jbe@1309
|
394 content = function()
|
bsw/jbe@1309
|
395 ui.tag{
|
bsw/jbe@1309
|
396 tag = "button",
|
bsw/jbe@1309
|
397 attr = {
|
bsw/jbe@1309
|
398 onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);",
|
bsw/jbe@1309
|
399 name = "move_up_" .. tostring(initiative.id),
|
bsw/jbe@1309
|
400 class = "clickable mdl-button mdl-js-button mdl-button--icon",
|
bsw/jbe@1309
|
401 alt = _"Move up",
|
bsw/jbe@1309
|
402 },
|
bsw/jbe@1309
|
403 content = function()
|
bsw/jbe@1309
|
404 ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "arrow_upward" }
|
bsw/jbe@1309
|
405 end
|
bsw/jbe@1309
|
406 }
|
bsw/jbe@1309
|
407 ui.tag{
|
bsw/jbe@1309
|
408 tag = "button",
|
bsw/jbe@1309
|
409 attr = {
|
bsw/jbe@1309
|
410 onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);",
|
bsw/jbe@1309
|
411 name = "move_down_" .. tostring(initiative.id),
|
bsw/jbe@1309
|
412 class = "clickable mdl-button mdl-js-button mdl-button--icon",
|
bsw/jbe@1309
|
413 alt = _"Move down"
|
bsw/jbe@1309
|
414 },
|
bsw/jbe@1309
|
415 content = function()
|
bsw/jbe@1309
|
416 ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "arrow_downward" }
|
bsw/jbe@1309
|
417 end
|
bsw/jbe@1309
|
418 }
|
bsw/jbe@1309
|
419 slot.put(" ")
|
bsw/jbe@1309
|
420 end
|
bsw@286
|
421 }
|
bsw@1045
|
422 end
|
bsw/jbe@1309
|
423 ui.container{
|
bsw/jbe@1309
|
424 content = function()
|
bsw/jbe@1309
|
425 ui.tag{ attr = { class = "initiative_name" }, content = function()
|
bsw/jbe@1309
|
426 ui.tag{ content = "i" .. initiative.id .. ": " }
|
bsw/jbe@1309
|
427 ui.tag{ content = initiative.shortened_name }
|
bsw/jbe@1309
|
428 end }
|
bsw/jbe@1309
|
429 slot.put("<br />")
|
bsw/jbe@1309
|
430 for i, initiator in ipairs(initiators) do
|
bsw/jbe@1309
|
431 ui.link{
|
bsw/jbe@1309
|
432 attr = { class = "clickable" },
|
bsw/jbe@1309
|
433 content = function ()
|
bsw/jbe@1309
|
434 execute.view{
|
bsw/jbe@1309
|
435 module = "member_image",
|
bsw/jbe@1309
|
436 view = "_show",
|
bsw/jbe@1309
|
437 params = {
|
bsw/jbe@1309
|
438 member = initiator,
|
bsw/jbe@1309
|
439 image_type = "avatar",
|
bsw/jbe@1309
|
440 show_dummy = true,
|
bsw/jbe@1309
|
441 class = "micro_avatar",
|
bsw/jbe@1309
|
442 popup_text = text
|
bsw/jbe@1309
|
443 }
|
bsw/jbe@1309
|
444 }
|
bsw/jbe@1309
|
445 end,
|
bsw/jbe@1309
|
446 module = "member", view = "show", id = initiator.id
|
bsw@1045
|
447 }
|
bsw/jbe@1309
|
448 slot.put(" ")
|
bsw/jbe@1309
|
449 ui.tag{ content = initiator.name }
|
bsw/jbe@1309
|
450 slot.put(" ")
|
bsw/jbe@1309
|
451 end
|
bsw/jbe@1309
|
452 end
|
bsw/jbe@1309
|
453 }
|
bsw@1045
|
454 end
|
bsw@1045
|
455 }
|
bsw/jbe@19
|
456 end
|
bsw/jbe@1309
|
457 end
|
bsw/jbe@1309
|
458 }
|
bsw/jbe@1309
|
459 end
|
bsw/jbe@1309
|
460 end
|
bsw/jbe@1309
|
461 end
|
bsw/jbe@1309
|
462 }
|
bsw/jbe@1309
|
463 if app.session.member_id and preview then
|
bsw/jbe@1309
|
464 local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine
|
bsw/jbe@1309
|
465 local comment = param.get("comment")
|
bsw/jbe@1309
|
466 if comment and #comment > 0 then
|
bsw/jbe@1309
|
467 local rendered_comment = format.wiki_text(comment, formatting_engine)
|
bsw/jbe@1309
|
468 ui.container{ content = _"Voting comment" }
|
bsw/jbe@1309
|
469 ui.container { attr = { class = "member_statement" }, content = function()
|
bsw/jbe@1309
|
470 slot.put(rendered_comment)
|
bsw/jbe@1309
|
471 end }
|
bsw/jbe@1309
|
472 slot.put("<br />")
|
bsw/jbe@1309
|
473 end
|
bsw/jbe@1309
|
474 end
|
bsw/jbe@1309
|
475 if (readonly or direct_voter and direct_voter.comment) and not preview and not (app.session.member_id == member.id) then
|
bsw/jbe@1309
|
476 local text
|
bsw/jbe@1309
|
477 if direct_voter and direct_voter.comment_changed then
|
bsw/jbe@1309
|
478 text = _("Voting comment (last updated: #{timestamp})", { timestamp = format.timestamp(direct_voter.comment_changed) })
|
bsw/jbe@1309
|
479 elseif direct_voter and direct_voter.comment then
|
bsw/jbe@1309
|
480 text = _"Voting comment"
|
bsw/jbe@1309
|
481 end
|
bsw/jbe@1309
|
482 if text then
|
bsw/jbe@1309
|
483 ui.container{ content = text }
|
bsw/jbe@1309
|
484 end
|
bsw/jbe@1309
|
485 if direct_voter and direct_voter.comment then
|
bsw/jbe@1309
|
486 local rendered_comment = direct_voter:get_content('html')
|
bsw/jbe@1309
|
487 ui.container { attr = { class = "member_statement" }, content = function()
|
bsw/jbe@1309
|
488 slot.put(rendered_comment)
|
bsw/jbe@1309
|
489 end }
|
bsw/jbe@1309
|
490 slot.put("<br />")
|
bsw/jbe@1309
|
491 end
|
bsw/jbe@1309
|
492 end
|
bsw/jbe@1309
|
493 if app.session.member_id and app.session.member_id == member.id then
|
bsw/jbe@1309
|
494 if (not readonly or direct_voter) and not preview then
|
bsw/jbe@1309
|
495 ui.container{ content = function()
|
bsw/jbe@1309
|
496 if not config.enforce_formatting_engine then
|
bsw/jbe@1309
|
497 ui.field.select{
|
bsw/jbe@1309
|
498 label = _"Wiki engine for statement",
|
bsw/jbe@1309
|
499 name = "formatting_engine",
|
bsw/jbe@1309
|
500 foreign_records = config.formatting_engines,
|
bsw/jbe@1309
|
501 attr = {id = "formatting_engine"},
|
bsw/jbe@1309
|
502 foreign_id = "id",
|
bsw/jbe@1309
|
503 foreign_name = "name",
|
bsw/jbe@1309
|
504 value = param.get("formatting_engine") or direct_voter and direct_voter.formatting_engine
|
bsw/jbe@1309
|
505 }
|
bsw@1045
|
506 end
|
bsw/jbe@1309
|
507 ui.container{ content = _"Voting comment (optional)" }
|
bsw/jbe@1309
|
508 ui.field.text{
|
bsw/jbe@1309
|
509 name = "comment",
|
bsw/jbe@1309
|
510 multiline = true,
|
bsw/jbe@1309
|
511 value = param.get("comment") or direct_voter and direct_voter.comment,
|
bsw/jbe@1309
|
512 attr = { style = "height: 10ex; width: 100%;" },
|
bsw/jbe@1309
|
513 }
|
bsw/jbe@1309
|
514 end }
|
bsw/jbe@1309
|
515 end
|
bsw/jbe@1309
|
516
|
bsw/jbe@1309
|
517 if preview then
|
bsw/jbe@1309
|
518 if not config.enforce_formatting_engine then
|
bsw/jbe@1309
|
519 ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") }
|
bsw/jbe@1309
|
520 end
|
bsw/jbe@1309
|
521 ui.field.hidden{ name = "comment", value = param.get("comment") or direct_voter and direct_voter.comment }
|
bsw/jbe@1309
|
522 end
|
bsw/jbe@1309
|
523
|
bsw/jbe@1309
|
524 if not readonly or direct_voter or preview then
|
bsw/jbe@1309
|
525 if preview then
|
bsw/jbe@1309
|
526 slot.put(" ")
|
bsw/jbe@1309
|
527 ui.tag{
|
bsw/jbe@1309
|
528 tag = "input",
|
bsw/jbe@1309
|
529 attr = {
|
bsw/jbe@1309
|
530 type = "submit",
|
bsw/jbe@1309
|
531 class = "mdl-button mdl-js-button mdl-button--raised mdl-button--colored",
|
bsw/jbe@1309
|
532 name = issue.closed and "update_comment" or nil,
|
bsw/jbe@1309
|
533 value = submit_button_text -- finish voting / update comment
|
bsw/jbe@1309
|
534 }
|
bsw/jbe@1309
|
535 }
|
bsw/jbe@1309
|
536 end
|
bsw/jbe@1309
|
537 if not preview then
|
bsw/jbe@1309
|
538 ui.tag{
|
bsw/jbe@1309
|
539 tag = "input",
|
bsw/jbe@1309
|
540 attr = {
|
bsw/jbe@1309
|
541 type = "submit",
|
bsw/jbe@1309
|
542 name = "preview",
|
bsw/jbe@1309
|
543 class = "mdl-button mdl-js-button mdl-button--raised mdl-button--colored",
|
bsw/jbe@1309
|
544 value = _"Preview",
|
bsw/jbe@1309
|
545 }
|
bsw/jbe@1309
|
546 }
|
bsw/jbe@1309
|
547 else
|
bsw/jbe@1309
|
548 slot.put(" ")
|
bsw/jbe@1309
|
549 ui.tag{
|
bsw/jbe@1309
|
550 tag = "input",
|
bsw/jbe@1309
|
551 attr = {
|
bsw/jbe@1309
|
552 type = "submit",
|
bsw/jbe@1309
|
553 name = "edit",
|
bsw/jbe@1309
|
554 class = "mdl-button mdl-js-button mdl-button--raised",
|
bsw/jbe@1309
|
555 value = edit_button_text,
|
bsw/jbe@1309
|
556 }
|
bsw/jbe@1309
|
557 }
|
bsw/jbe@1309
|
558 end
|
bsw@1045
|
559 end
|
bsw@1045
|
560 end
|
bsw@1045
|
561 end
|
bsw@1045
|
562 }
|
bsw/jbe@1309
|
563 slot.put("<br />")
|
bsw/jbe@1309
|
564 ui.link{
|
bsw/jbe@1309
|
565 attr = { class = "mdl-button mdl-js-button mdl-button--raised" },
|
bsw/jbe@1309
|
566 text = _"Cancel",
|
bsw/jbe@1309
|
567 module = "issue",
|
bsw/jbe@1309
|
568 view = "show",
|
bsw/jbe@1309
|
569 id = issue.id
|
bsw/jbe@1309
|
570 }
|
bsw@1558
|
571 if direct_voter and not issue.closed then
|
bsw/jbe@1309
|
572 slot.put(" ")
|
bsw/jbe@1309
|
573 ui.link {
|
bsw/jbe@1309
|
574 attr = { class = "mdl-button mdl-js-button mdl-button--raised" },
|
bsw/jbe@1309
|
575 module = "vote", action = "update",
|
bsw/jbe@1309
|
576 params = {
|
bsw/jbe@1309
|
577 issue_id = issue.id,
|
bsw/jbe@1309
|
578 discard = true
|
bsw/jbe@1309
|
579 },
|
bsw/jbe@1309
|
580 routing = {
|
bsw/jbe@1309
|
581 default = {
|
bsw/jbe@1309
|
582 mode = "redirect",
|
bsw/jbe@1309
|
583 module = "issue",
|
bsw/jbe@1309
|
584 view = "show",
|
bsw/jbe@1309
|
585 id = issue.id
|
bsw@1045
|
586 }
|
bsw/jbe@1309
|
587 },
|
bsw/jbe@1309
|
588 text = _"Discard my vote"
|
bsw/jbe@1309
|
589 }
|
bsw/jbe@5
|
590 end
|
bsw/jbe@1309
|
591
|
bsw/jbe@1309
|
592 end }
|
bsw/jbe@1309
|
593 end }
|
bsw/jbe@1309
|
594 end }
|
bsw/jbe@1309
|
595 end }
|