rev |
line source |
bsw/jbe@1309
|
1 local initiative = param.get("initiative", "table")
|
bsw/jbe@1309
|
2 local direct_supporter
|
bsw/jbe@1309
|
3 if app.session.member_id then
|
bsw/jbe@1309
|
4 direct_supporter = initiative.issue.member_info.own_participation and initiative.member_info.supported
|
bsw/jbe@1309
|
5 end
|
bsw/jbe@1309
|
6
|
bsw/jbe@1309
|
7
|
bsw/jbe@1309
|
8 ui.link { attr = { name = "suggestions" }, text = "" }
|
bsw/jbe@1309
|
9
|
bsw/jbe@1309
|
10
|
bsw/jbe@1309
|
11 ui.container {
|
bsw/jbe@1309
|
12 attr = { class = "section suggestions" },
|
bsw/jbe@1309
|
13 content = function ()
|
bsw/jbe@1309
|
14
|
bsw/jbe@1309
|
15 if # ( initiative.suggestions ) > 0 then
|
bsw/jbe@1309
|
16
|
bsw/jbe@1309
|
17 ui.heading {
|
bsw/jbe@1309
|
18 level = 1,
|
bsw/jbe@1309
|
19 content = _("Suggestions for improvement (#{count})", { count = # ( initiative.suggestions ) } )
|
bsw/jbe@1309
|
20 }
|
bsw/jbe@1309
|
21 ui.container { content = _"written and rated by the supportes of this initiative to improve the proposal and its reasons" }
|
bsw/jbe@1309
|
22 slot.put("<br />")
|
bsw/jbe@1309
|
23
|
bsw/jbe@1309
|
24 for i, suggestion in ipairs(initiative.suggestions) do
|
bsw/jbe@1309
|
25
|
bsw/jbe@1309
|
26 local opinion = Opinion:by_pk(app.session.member_id, suggestion.id)
|
bsw/jbe@1309
|
27
|
bsw/jbe@1309
|
28 local class = "mdl-card mdl-card__fullwidth mdl-shadow--2dp not-folded"
|
bsw/jbe@1309
|
29 if suggestion.id == param.get("suggestion_id", atom.number) then
|
bsw/jbe@1309
|
30 class = class .. " highlighted"
|
bsw/jbe@1309
|
31 end
|
bsw/jbe@1309
|
32 if member and not initiative.issue.fully_frozen and not initiative.issue.closed and initiative.member_info.supported then
|
bsw/jbe@1309
|
33 class = class .. " rateable"
|
bsw/jbe@1309
|
34 end
|
bsw/jbe@1309
|
35
|
bsw/jbe@1309
|
36 ui.link { attr = { name = "s" .. suggestion.id }, text = "" }
|
bsw/jbe@1309
|
37 ui.tag { tag = "div", attr = { class = class, id = "s" .. suggestion.id }, content = function ()
|
bsw/jbe@1309
|
38 ui.tag{ attr = { class = "mdl-card__title mdl-card--border" }, content = function()
|
bsw/jbe@1309
|
39 ui.heading { level = 2,
|
bsw/jbe@1309
|
40 attr = { class = "mdl-card__title-text" },
|
bsw/jbe@1309
|
41 content = format.string(suggestion.name, {
|
bsw/jbe@1309
|
42 truncate_at = 160, truncate_suffix = true
|
bsw/jbe@1309
|
43 }) }
|
bsw/jbe@1309
|
44
|
bsw/jbe@1309
|
45 if opinion then
|
bsw/jbe@1309
|
46
|
bsw/jbe@1309
|
47 ui.container { attr = { class = "mdl-card__content"}, content = function()
|
bsw/jbe@1309
|
48 local class = ""
|
bsw/jbe@1309
|
49 local text = ""
|
bsw/jbe@1309
|
50
|
bsw/jbe@1309
|
51 if opinion.degree == 2 then
|
bsw/jbe@1309
|
52 class = "must"
|
bsw/jbe@1309
|
53 text = _"must"
|
bsw/jbe@1309
|
54 elseif opinion.degree == 1 then
|
bsw/jbe@1309
|
55 class = "should"
|
bsw/jbe@1309
|
56 text = _"should"
|
bsw/jbe@1309
|
57 elseif opinion.degree == 0 then
|
bsw/jbe@1309
|
58 class = "neutral"
|
bsw/jbe@1309
|
59 text = _"neutral"
|
bsw/jbe@1309
|
60 elseif opinion.degree == -1 then
|
bsw/jbe@1309
|
61 class = "shouldnot"
|
bsw/jbe@1309
|
62 text = _"should not"
|
bsw/jbe@1309
|
63 elseif opinion.degree == -2 then
|
bsw/jbe@1309
|
64 class = "mustnot"
|
bsw/jbe@1309
|
65 text = _"must not"
|
bsw/jbe@1309
|
66 end
|
bsw/jbe@1309
|
67
|
bsw/jbe@1309
|
68 ui.tag {
|
bsw/jbe@1309
|
69 attr = { class = class },
|
bsw/jbe@1309
|
70 content = text
|
bsw/jbe@1309
|
71 }
|
bsw/jbe@1309
|
72
|
bsw/jbe@1309
|
73 slot.put ( " " )
|
bsw/jbe@1309
|
74
|
bsw/jbe@1309
|
75 if
|
bsw/jbe@1309
|
76 (opinion.degree > 0 and not opinion.fulfilled)
|
bsw/jbe@1309
|
77 or (opinion.degree < 0 and opinion.fulfilled)
|
bsw/jbe@1309
|
78 then
|
bsw/jbe@1309
|
79 ui.tag{ content = _"but" }
|
bsw/jbe@1309
|
80 else
|
bsw/jbe@1309
|
81 ui.tag{ content = _"and" }
|
bsw/jbe@1309
|
82 end
|
bsw/jbe@1309
|
83
|
bsw/jbe@1309
|
84 slot.put ( " " )
|
bsw/jbe@1309
|
85
|
bsw/jbe@1309
|
86 local class = ""
|
bsw/jbe@1309
|
87 local text = ""
|
bsw/jbe@1309
|
88
|
bsw/jbe@1309
|
89 if opinion.fulfilled then
|
bsw/jbe@1309
|
90 class = "implemented"
|
bsw/jbe@1309
|
91 text = _"is implemented"
|
bsw/jbe@1309
|
92 else
|
bsw/jbe@1309
|
93 class = "notimplemented"
|
bsw/jbe@1309
|
94 text = _"is not implemented"
|
bsw/jbe@1309
|
95 end
|
bsw/jbe@1309
|
96
|
bsw/jbe@1309
|
97 ui.tag {
|
bsw/jbe@1309
|
98 attr = { class = class },
|
bsw/jbe@1309
|
99 content = text
|
bsw/jbe@1309
|
100 }
|
bsw/jbe@1309
|
101
|
bsw/jbe@1309
|
102 if
|
bsw/jbe@1309
|
103 (opinion.degree > 0 and not opinion.fulfilled)
|
bsw/jbe@1309
|
104 or (opinion.degree < 0 and opinion.fulfilled)
|
bsw/jbe@1309
|
105 then
|
bsw/jbe@1309
|
106 if math.abs(opinion.degree) > 1 then
|
bsw/jbe@1309
|
107 slot.put(" !!")
|
bsw/jbe@1309
|
108 else
|
bsw/jbe@1309
|
109 slot.put(" !")
|
bsw/jbe@1309
|
110 end
|
bsw/jbe@1309
|
111 else
|
bsw/jbe@1309
|
112 slot.put(" ✓")
|
bsw/jbe@1309
|
113 end
|
bsw/jbe@1309
|
114
|
bsw/jbe@1309
|
115 end }
|
bsw/jbe@1309
|
116
|
bsw/jbe@1309
|
117 end
|
bsw/jbe@1309
|
118
|
bsw/jbe@1309
|
119 end }
|
bsw/jbe@1309
|
120
|
bsw/jbe@1309
|
121 ui.container{ attr = { class = "suggestion-content" }, content = function()
|
bsw/jbe@1309
|
122
|
bsw/jbe@1309
|
123 local plus2 = (suggestion.plus2_unfulfilled_count or 0)
|
bsw/jbe@1309
|
124 + (suggestion.plus2_fulfilled_count or 0)
|
bsw/jbe@1309
|
125 local plus1 = (suggestion.plus1_unfulfilled_count or 0)
|
bsw/jbe@1309
|
126 + (suggestion.plus1_fulfilled_count or 0)
|
bsw/jbe@1309
|
127 local minus1 = (suggestion.minus1_unfulfilled_count or 0)
|
bsw/jbe@1309
|
128 + (suggestion.minus1_fulfilled_count or 0)
|
bsw/jbe@1309
|
129 local minus2 = (suggestion.minus2_unfulfilled_count or 0)
|
bsw/jbe@1309
|
130 + (suggestion.minus2_fulfilled_count or 0)
|
bsw/jbe@1309
|
131
|
bsw/jbe@1309
|
132 local with_opinion = plus2 + plus1 + minus1 + minus2
|
bsw/jbe@1309
|
133
|
bsw/jbe@1309
|
134 local neutral = (suggestion.initiative.supporter_count or 0)
|
bsw/jbe@1309
|
135 - with_opinion
|
bsw/jbe@1309
|
136
|
bsw/jbe@1309
|
137 local neutral2 = with_opinion
|
bsw/jbe@1309
|
138 - (suggestion.plus2_fulfilled_count or 0)
|
bsw/jbe@1309
|
139 - (suggestion.plus1_fulfilled_count or 0)
|
bsw/jbe@1309
|
140 - (suggestion.minus1_fulfilled_count or 0)
|
bsw/jbe@1309
|
141 - (suggestion.minus2_fulfilled_count or 0)
|
bsw/jbe@1309
|
142
|
bsw/jbe@1309
|
143 ui.container {
|
bsw/jbe@1309
|
144 attr = { class = "mdl-card__content mdl-card--border suggestionInfo" },
|
bsw/jbe@1309
|
145 content = function ()
|
bsw/jbe@1309
|
146
|
bsw/jbe@1309
|
147 if app.session:has_access("authors_pseudonymous") then
|
bsw/jbe@1309
|
148 util.micro_avatar ( suggestion.author )
|
bsw/jbe@1309
|
149 end
|
bsw/jbe@1309
|
150
|
bsw/jbe@1309
|
151 if with_opinion > 0 then
|
bsw/jbe@1309
|
152 ui.container { attr = { class = "suggestion-rating" }, content = function ()
|
bsw/jbe@1309
|
153 ui.tag { content = _"collective rating:" }
|
bsw/jbe@1309
|
154 slot.put(" ")
|
bsw/jbe@1309
|
155 ui.bargraph{
|
bsw/jbe@1309
|
156 max_value = suggestion.initiative.supporter_count,
|
bsw/jbe@1309
|
157 width = 100,
|
bsw/jbe@1309
|
158 bars = {
|
bsw/jbe@1309
|
159 { color = "#0a0", value = plus2 },
|
bsw/jbe@1309
|
160 { color = "#8a8", value = plus1 },
|
bsw/jbe@1309
|
161 { color = "#eee", value = neutral },
|
bsw/jbe@1309
|
162 { color = "#a88", value = minus1 },
|
bsw/jbe@1309
|
163 { color = "#a00", value = minus2 },
|
bsw/jbe@1309
|
164 }
|
bsw/jbe@1309
|
165 }
|
bsw/jbe@1309
|
166 slot.put(" | ")
|
bsw/jbe@1309
|
167 ui.tag { content = _"implemented:" }
|
bsw/jbe@1309
|
168 slot.put ( " " )
|
bsw/jbe@1309
|
169 ui.bargraph{
|
bsw/jbe@1309
|
170 max_value = with_opinion,
|
bsw/jbe@1309
|
171 width = 100,
|
bsw/jbe@1309
|
172 bars = {
|
bsw/jbe@1309
|
173 { color = "#0a0", value = suggestion.plus2_fulfilled_count },
|
bsw/jbe@1309
|
174 { color = "#8a8", value = suggestion.plus1_fulfilled_count },
|
bsw/jbe@1309
|
175 { color = "#eee", value = neutral2 },
|
bsw/jbe@1309
|
176 { color = "#a88", value = suggestion.minus1_fulfilled_count },
|
bsw/jbe@1309
|
177 { color = "#a00", value = suggestion.minus2_fulfilled_count },
|
bsw/jbe@1309
|
178 }
|
bsw/jbe@1309
|
179 }
|
bsw/jbe@1309
|
180 end }
|
bsw/jbe@1309
|
181 end
|
bsw/jbe@1309
|
182
|
bsw/jbe@1309
|
183 end
|
bsw/jbe@1309
|
184 }
|
bsw/jbe@1309
|
185
|
bsw/jbe@1309
|
186 ui.container {
|
bsw/jbe@1309
|
187 attr = { class = "mdl-card__content mdl-card--border suggestion-text draft" },
|
bsw/jbe@1309
|
188 content = function ()
|
bsw/jbe@1309
|
189 slot.put ( suggestion:get_content( "html" ) )
|
bsw/jbe@1309
|
190
|
bsw/jbe@1309
|
191 end
|
bsw/jbe@1309
|
192 }
|
bsw/jbe@1309
|
193
|
bsw/jbe@1309
|
194 if direct_supporter then
|
bsw/jbe@1309
|
195 ui.container{ attr = { class = "mdl-card__content rating" }, content = function ()
|
bsw/jbe@1309
|
196
|
bsw/jbe@1309
|
197 if not opinion then
|
bsw/jbe@1309
|
198 opinion = {}
|
bsw/jbe@1309
|
199 end
|
bsw/jbe@1309
|
200 ui.form {
|
bsw/jbe@1309
|
201 module = "opinion", action = "update", params = {
|
bsw/jbe@1309
|
202 suggestion_id = suggestion.id
|
bsw/jbe@1309
|
203 },
|
bsw/jbe@1309
|
204 routing = { default = {
|
bsw/jbe@1309
|
205 mode = "redirect",
|
bsw/jbe@1309
|
206 module = "initiative", view = "show", id = suggestion.initiative_id,
|
bsw/jbe@1309
|
207 params = { suggestion_id = suggestion.id },
|
bsw/jbe@1309
|
208 anchor = "s" .. suggestion.id -- TODO webmcp
|
bsw/jbe@1309
|
209 } },
|
bsw/jbe@1309
|
210 content = function ()
|
bsw/jbe@1309
|
211
|
bsw/jbe@1309
|
212 ui.container{ attr = { class = "opinon-question" }, content = _"Should the initiator implement this suggestion?" }
|
bsw/jbe@1309
|
213 ui.container { content = function ()
|
bsw/jbe@1309
|
214
|
bsw/jbe@1309
|
215 local options = {
|
bsw/jbe@1309
|
216 { degree = 2, label = _"must" },
|
bsw/jbe@1309
|
217 { degree = 1, label = _"should" },
|
bsw/jbe@1309
|
218 { degree = 0, label = _"neutral" },
|
bsw/jbe@1309
|
219 { degree = -1, label = _"should not" },
|
bsw/jbe@1309
|
220 { degree = -2, label = _"must not" },
|
bsw/jbe@1309
|
221 }
|
bsw/jbe@1309
|
222
|
bsw/jbe@1309
|
223 for i, option in ipairs(options) do
|
bsw@1491
|
224 local active = opinion.degree == option.degree or opinion.degree == nil and option.degree == 0
|
bsw/jbe@1309
|
225 ui.tag{
|
bsw/jbe@1309
|
226 tag = "label",
|
bsw/jbe@1309
|
227 attr = { class = "mdl-radio mdl-js-radio mdl-js-ripple-effect" },
|
bsw/jbe@1309
|
228 ["for"] = "s" .. suggestion.id .. "_degree" .. option.degree,
|
bsw/jbe@1309
|
229 content = function()
|
bsw/jbe@1309
|
230 ui.tag{
|
bsw/jbe@1309
|
231 tag = "input",
|
bsw/jbe@1309
|
232 attr = {
|
bsw/jbe@1309
|
233 class = "mdl-radio__button",
|
bsw/jbe@1309
|
234 type = "radio",
|
bsw/jbe@1309
|
235 name = "degree",
|
bsw/jbe@1309
|
236 value = option.degree,
|
bsw/jbe@1309
|
237 id = "s" .. suggestion.id .. "_degree" .. option.degree,
|
bsw/jbe@1309
|
238 checked = active and "checked" or nil
|
bsw/jbe@1309
|
239 }
|
bsw/jbe@1309
|
240 }
|
bsw/jbe@1309
|
241 ui.tag{
|
bsw/jbe@1309
|
242 attr = { class = "mdl-radio__label" },
|
bsw/jbe@1309
|
243 content = option.label
|
bsw/jbe@1309
|
244 }
|
bsw/jbe@1309
|
245 end
|
bsw/jbe@1309
|
246 }
|
bsw/jbe@1309
|
247 slot.put(" ")
|
bsw/jbe@1309
|
248 end
|
bsw/jbe@1309
|
249 end }
|
bsw/jbe@1309
|
250
|
bsw/jbe@1309
|
251 slot.put("<br />")
|
bsw/jbe@1309
|
252
|
bsw/jbe@1309
|
253 ui.container{ attr = { class = "opinon-question" }, content = _"Did the initiator implement this suggestion?" }
|
bsw/jbe@1309
|
254 ui.container { content = function ()
|
bsw/jbe@1309
|
255
|
bsw/jbe@1309
|
256 local options = {
|
bsw/jbe@1309
|
257 { degree = "false", id = "notfulfilled", label = _"No (not yet)" },
|
bsw/jbe@1309
|
258 { degree = "true", id = "fulfilled", label = _"Yes, it's implemented" },
|
bsw/jbe@1309
|
259 }
|
bsw/jbe@1309
|
260
|
bsw/jbe@1309
|
261 for i, option in ipairs(options) do
|
bsw/jbe@1309
|
262 local active = opinion.fulfilled == (option.degree == "true" and true or false)
|
bsw/jbe@1309
|
263 ui.tag{
|
bsw/jbe@1309
|
264 tag = "label",
|
bsw/jbe@1309
|
265 attr = { class = "mdl-radio mdl-js-radio mdl-js-ripple-effect" },
|
bsw/jbe@1309
|
266 ["for"] = "s" .. suggestion.id .. "_" .. option.id,
|
bsw/jbe@1309
|
267 content = function()
|
bsw/jbe@1309
|
268 ui.tag{
|
bsw/jbe@1309
|
269 tag = "input",
|
bsw/jbe@1309
|
270 attr = {
|
bsw/jbe@1309
|
271 class = "mdl-radio__button",
|
bsw/jbe@1309
|
272 type = "radio",
|
bsw/jbe@1309
|
273 name = "fulfilled",
|
bsw/jbe@1309
|
274 value = option.degree,
|
bsw/jbe@1309
|
275 id = "s" .. suggestion.id .. "_" .. option.id,
|
bsw/jbe@1309
|
276 checked = active and "checked" or nil
|
bsw/jbe@1309
|
277 }
|
bsw/jbe@1309
|
278 }
|
bsw/jbe@1309
|
279 ui.tag{
|
bsw/jbe@1309
|
280 attr = { class = "mdl-radio__label" },
|
bsw/jbe@1309
|
281 content = option.label
|
bsw/jbe@1309
|
282 }
|
bsw/jbe@1309
|
283 end
|
bsw/jbe@1309
|
284 }
|
bsw/jbe@1309
|
285 slot.put(" ")
|
bsw/jbe@1309
|
286 end
|
bsw/jbe@1309
|
287 end }
|
bsw/jbe@1309
|
288
|
bsw/jbe@1309
|
289 slot.put("<br />")
|
bsw/jbe@1309
|
290
|
bsw/jbe@1309
|
291 ui.tag{
|
bsw/jbe@1309
|
292 tag = "input",
|
bsw/jbe@1309
|
293 attr = {
|
bsw/jbe@1309
|
294 type = "submit",
|
bsw/jbe@1309
|
295 class = "mdl-button mdl-js-button mdl-button--raised mdl-button--colored",
|
bsw/jbe@1309
|
296 value = _"publish my rating"
|
bsw/jbe@1309
|
297 },
|
bsw/jbe@1309
|
298 content = ""
|
bsw/jbe@1309
|
299 }
|
bsw/jbe@1309
|
300
|
bsw/jbe@1309
|
301 end
|
bsw/jbe@1309
|
302 }
|
bsw/jbe@1309
|
303
|
bsw/jbe@1309
|
304 end }
|
bsw/jbe@1309
|
305 end
|
bsw/jbe@1309
|
306
|
bsw/jbe@1309
|
307 end }
|
bsw/jbe@1309
|
308
|
bsw/jbe@1309
|
309 ui.container { attr = { class = "rating-button" }, content = function()
|
bsw/jbe@1309
|
310
|
bsw/jbe@1309
|
311 local text = _"Read more"
|
bsw/jbe@1309
|
312
|
bsw/jbe@1309
|
313 if direct_supporter then
|
bsw/jbe@1309
|
314 text = text .. " / " .. _"Rate suggestion"
|
bsw/jbe@1309
|
315 end
|
bsw/jbe@1309
|
316
|
bsw/jbe@1309
|
317 ui.link {
|
bsw/jbe@1309
|
318 attr = {
|
bsw/jbe@1309
|
319 class = "mdl-button mdl-js-button suggestion-more",
|
bsw/jbe@1309
|
320 onclick = "document.querySelector('#s" .. suggestion.id .. "').classList.remove('folded');document.querySelector('#s" .. suggestion.id .. "').classList.add('unfolded'); return false;"
|
bsw/jbe@1309
|
321 },
|
bsw/jbe@1309
|
322 text = text
|
bsw/jbe@1309
|
323 }
|
bsw/jbe@1309
|
324
|
bsw/jbe@1309
|
325 ui.link {
|
bsw/jbe@1309
|
326 attr = {
|
bsw/jbe@1309
|
327 class = "mdl-button suggestion-less",
|
bsw/jbe@1309
|
328 onclick = "document.querySelector('#s" .. suggestion.id .. "').classList.add('folded');document.querySelector('#s" .. suggestion.id .. "').classList.remove('unfolded'); return false;"
|
bsw/jbe@1309
|
329 },
|
bsw/jbe@1309
|
330 text = _"Show less"
|
bsw/jbe@1309
|
331 }
|
bsw/jbe@1309
|
332 --[[
|
bsw/jbe@1309
|
333 ui.link{
|
bsw/jbe@1309
|
334 attr = { class = "mdl-button" },
|
bsw/jbe@1309
|
335 content = _"Details",
|
bsw/jbe@1309
|
336 module = "suggestion", view = "show", id = suggestion.id
|
bsw/jbe@1309
|
337 }
|
bsw/jbe@1309
|
338 --]]
|
bsw/jbe@1309
|
339 end }
|
bsw/jbe@1309
|
340 ui.script{ script = [[
|
bsw/jbe@1309
|
341 window.addEventListener("load", function() {
|
bsw/jbe@1309
|
342 var textEl = document.querySelector('#s]] .. suggestion.id .. [[ .suggestion-content');
|
bsw/jbe@1309
|
343 var height = textEl.clientHeight;
|
bsw/jbe@1309
|
344 if (height > 180) {
|
bsw/jbe@1309
|
345 document.querySelector('#s]] .. suggestion.id .. [[').classList.add('folded');
|
bsw/jbe@1309
|
346 document.querySelector('#s]] .. suggestion.id .. [[ .rating-button').classList.add('mdl-card__actions');
|
bsw/jbe@1309
|
347 document.querySelector('#s]] .. suggestion.id .. [[ .rating-button').classList.add('mdl-card--border');
|
bsw/jbe@1309
|
348 }
|
bsw/jbe@1309
|
349 });
|
bsw/jbe@1309
|
350 ]] }
|
bsw/jbe@1309
|
351
|
bsw/jbe@1309
|
352 end }
|
bsw/jbe@1309
|
353
|
bsw/jbe@1309
|
354 end -- for i, suggestion
|
bsw/jbe@1309
|
355
|
bsw/jbe@1309
|
356 end -- if #initiative.suggestions > 0
|
bsw/jbe@1309
|
357 end
|
bsw/jbe@1309
|
358 }
|