liquid_feedback_frontend
view app/main/draft/new.lua @ 1536:feeac2fd945e
merge
author | bsw |
---|---|
date | Tue Oct 06 19:31:38 2020 +0200 (2020-10-06) |
parents | 770ab0a7f79b 0d9bb3937310 |
children | a13a0071f873 |
line source
1 local issue
2 local area
3 local area_id
5 local issue_id = param.get("issue_id", atom.integer)
6 if issue_id then
7 issue = Issue:new_selector():add_where{"id=?",issue_id}:single_object_mode():exec()
8 issue:load_everything_for_member_id(app.session.member_id)
9 area = issue.area
10 else
11 area_id = param.get("area_id", atom.integer)
12 if area_id then
13 area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec()
14 area:load_delegation_info_once_for_member_id(app.session.member_id)
15 else
16 local firstlife_id = param.get("firstlife_id")
17 if firstlife_id then
18 area = Area:new_selector():join("unit", nil, "unit.id = area.unit_id"):add_where{"attr->>'firstlife_id'=?",firstlife_id}:single_object_mode():exec()
19 area:load_delegation_info_once_for_member_id(app.session.member_id)
20 area_id = area.id
21 end
22 end
23 end
25 local polling = param.get("polling", atom.boolean)
27 local policy_id = param.get("policy_id", atom.integer)
28 local policy
30 local preview = param.get("preview")
32 if #(slot.get_content("error")) > 0 then
33 preview = false
34 end
36 if policy_id then
37 policy = Policy:by_id(policy_id)
38 end
40 local callback = param.get("callback")
43 local initiative_id = param.get("initiative_id")
44 local initiative = Initiative:by_id(initiative_id)
45 local draft
46 if initiative then
47 initiative:load_everything_for_member_id(app.session.member_id)
48 initiative.issue:load_everything_for_member_id(app.session.member_id)
50 if initiative.issue.closed then
51 slot.put_into("error", _"This issue is already closed.")
52 return
53 elseif initiative.issue.half_frozen then
54 slot.put_into("error", _"This issue is already frozen.")
55 return
56 elseif initiative.issue.phase_finished then
57 slot.put_into("error", _"Current phase is already closed.")
58 return
59 end
61 draft = initiative.current_draft
62 if config.initiative_abstract then
63 draft.abstract = string.match(draft.content, "(.+)<!%--END_OF_ABSTRACT%-->")
64 if draft.abstract then
65 draft.content = string.match(draft.content, "<!%--END_OF_ABSTRACT%-->(.*)")
66 end
67 end
68 end
70 if not initiative and not issue and not area then
71 ui.heading{ content = _"Missing parameter" }
72 return false
73 end
75 ui.form{
76 record = draft,
77 attr = { class = "vertical section", enctype = 'multipart/form-data' },
78 module = "draft",
79 action = "add",
80 params = {
81 area_id = area and area.id,
82 issue_id = issue and issue.id or nil,
83 initiative_id = initiative_id,
84 callback = callback
85 },
86 routing = {
87 ok = {
88 mode = "redirect",
89 module = "initiative",
90 view = "show",
91 id = initiative_id
92 }
93 },
94 content = function()
96 ui.grid{ content = function()
97 ui.cell_main{ content = function()
98 ui.container{ attr = { class = "mdl-card mdl-shadow--2dp mdl-card__fullwidth" }, content = function()
99 ui.container{ attr = { class = "mdl-card__title mdl-card--border" }, content = function()
100 if initiative then
101 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = initiative.display_name }
102 elseif param.get("name") then
103 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = param.get("name") }
104 elseif issue then
105 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = _("New competing initiative in issue '#{issue}'", { issue = issue.name }) }
106 elseif area then
107 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = _("New issue in area '#{area}'", { area = area.name }) }
108 end
109 end }
110 ui.container{ attr = { class = "mdl-card__content mdl-card--border" }, content = function()
112 -- -------- PREVIEW
113 if param.get("preview") then
114 ui.sectionRow( function()
115 if not issue and not initiative then
116 ui.container { content = policy.name }
117 end
118 if param.get("free_timing") then
119 ui.container { content = param.get("free_timing") }
120 end
121 slot.put("<br />")
122 ui.field.hidden{ name = "policy_id", value = param.get("policy_id") }
123 ui.field.hidden{ name = "name", value = param.get("name") }
124 if config.initiative_abstract then
125 ui.field.hidden{ name = "abstract", value = param.get("abstract") }
126 ui.container{
127 attr = { class = "abstract" },
128 content = param.get("abstract")
129 }
130 slot.put("<br />")
131 end
132 local draft_text = param.get("content")
133 local draft_text = util.wysihtml_preproc(draft_text)
134 ui.field.hidden{ name = "content", value = draft_text }
135 ui.container{
136 attr = { class = "draft" },
137 content = function()
138 slot.put(draft_text)
139 end
140 }
141 slot.put("<br />")
143 if config.attachments then
144 local file_upload_session = param.get("file_upload_session") or multirand.string(
145 32,
146 '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
147 )
148 file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "")
149 ui.field.hidden{ name = "file_upload_session", value = file_upload_session }
150 if initiative then
151 local files = File:new_selector()
152 :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id")
153 :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id }
154 :reset_fields()
155 :add_field("file.id")
156 :add_field("draft_attachment.title")
157 :add_field("draft_attachment.description")
158 :add_order_by("draft_attachment.id")
159 :exec()
161 if #files > 0 then
162 ui.container {
163 content = function()
164 for i, file in ipairs(files) do
165 if param.get("file_delete_" .. file.id, atom.boolean) then
166 ui.field.hidden{ name = "file_delete_" .. file.id, value = "1" }
167 else
168 ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } }
169 ui.container{ content = function()
170 ui.tag{ tag = "strong", content = file.title or "" }
171 end }
172 ui.container{ content = file.description or "" }
173 slot.put("<br /><br />")
174 end
175 end
176 end
177 }
178 end
179 end
180 local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json")
181 local fh = io.open(filename, "r")
182 if fh then
183 local file_uploads = json.import(fh:read("*a"))
184 for i, file_upload in ipairs(file_uploads) do
185 ui.image{ module = "draft", view = "show_file_upload", params = {
186 file_upload_session = file_upload_session, file_id = file_upload.id, preview = true
187 } }
188 ui.container{ content = function()
189 ui.tag{ tag = "strong", content = file_upload.title or "" }
190 end }
191 ui.container{ content = file_upload.description or "" }
192 slot.put("<br />")
193 end
194 end
195 end
197 ui.tag{
198 tag = "input",
199 attr = {
200 type = "submit",
201 class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored",
202 value = _'Publish now'
203 },
204 content = ""
205 }
206 slot.put(" ")
208 ui.tag{
209 tag = "input",
210 attr = {
211 type = "submit",
212 name = "edit",
213 class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect",
214 value = _'Edit again'
215 },
216 content = ""
217 }
218 slot.put(" ")
220 ui.link{
221 attr = { class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" },
222 content = _"Cancel",
223 module = initiative and "initiative" or "area",
224 view = "show",
225 id = initiative_id or area_id
226 }
227 end )
229 -- -------- EDIT
230 else
232 if not issue_id and not initiative_id then
233 local tmp = { { id = -1, name = "" } }
234 for i, allowed_policy in ipairs(area.allowed_policies) do
235 if not allowed_policy.polling or app.session.member:has_polling_right_for_unit_id(area.unit_id) then
236 tmp[#tmp+1] = allowed_policy
237 end
238 end
239 ui.container{ content = _"Please choose a policy for the new issue:" }
240 ui.field.select{
241 name = "policy_id",
242 foreign_records = tmp,
243 foreign_id = "id",
244 foreign_name = "name",
245 value = param.get("policy_id", atom.integer) or area.default_policy and area.default_policy.id
246 }
247 if policy and policy.free_timeable then
248 local available_timings
249 if config.free_timing and config.free_timing.available_func then
250 available_timings = config.free_timing.available_func(policy)
251 if available_timings == false then
252 slot.put_into("error", "error in free timing config")
253 return false
254 end
255 end
256 ui.heading{ level = 4, content = _"Free timing:" }
257 if available_timings then
258 ui.field.select{
259 name = "free_timing",
260 foreign_records = available_timings,
261 foreign_id = "id",
262 foreign_name = "name",
263 value = param.get("free_timing")
264 }
265 else
266 ui.field.text{
267 name = "free_timing",
268 value = param.get("free_timing")
269 }
270 end
271 end
272 end
274 if issue and issue.policy.polling and app.session.member:has_polling_right_for_unit_id(area.unit_id) then
275 slot.put("<br />")
276 ui.field.boolean{ name = "polling", label = _"No admission needed", value = polling }
277 end
279 if not initiative then
280 ui.container{ attr = { class = "mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-card__fullwidth" }, content = function ()
281 ui.field.text{
282 attr = { id = "lf-initiative__name", class = "mdl-textfield__input" },
283 label_attr = { class = "mdl-textfield__label", ["for"] = "lf-initiative__name" },
284 label = _"Title",
285 name = "name",
286 value = param.get("name")
287 }
288 end }
289 end
291 if config.initiative_abstract then
292 ui.container { content = _"Enter abstract:" }
293 ui.container{ attr = { class = "mdl-textfield mdl-js-textfield mdl-textfield--expandable mdl-textfield__fullwidth" }, content = function()
294 ui.field.text{
295 name = "abstract",
296 multiline = true,
297 attr = { id = "abstract", style = "height: 20ex; width: 100%;" },
298 value = param.get("abstract")
299 }
300 end }
301 end
303 ui.container { content = _"Enter your proposal and/or reasons:" }
304 ui.field.wysihtml{
305 name = "content",
306 multiline = true,
307 attr = { id = "draft", style = "height: 50ex; width: 100%;" },
308 value = param.get("content")
309 }
310 if not issue or issue.state == "admission" or issue.state == "discussion" then
311 ui.container { content = _"You can change your text again anytime during admission and discussion phase" }
312 else
313 ui.container { content = _"You cannot change your text again later, because this issue is already in verfication phase!" }
314 end
316 slot.put("<br />")
317 if config.attachments then
318 local file_upload_session = param.get("file_upload_session") or multirand.string(
319 32,
320 '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
321 )
322 file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "")
323 ui.field.hidden{ name = "file_upload_session", value = file_upload_session }
324 if initiative then
325 local files = File:new_selector()
326 :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id")
327 :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id }
328 :reset_fields()
329 :add_field("file.id")
330 :add_field("draft_attachment.title")
331 :add_field("draft_attachment.description")
332 :add_order_by("draft_attachment.id")
333 :exec()
335 if #files > 0 then
336 ui.container {
337 content = function()
338 for i, file in ipairs(files) do
339 ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } }
340 ui.container{ content = function()
341 ui.tag{ tag = "strong", content = file.title or "" }
342 end }
343 ui.container{ content = file.description or "" }
344 ui.field.boolean{ label = _"delete", name = "file_delete_" .. file.id, value = param.get("file_delete_" .. file.id) and true or false }
345 slot.put("<br /><br />")
346 end
347 end
348 }
349 end
350 end
351 local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json")
352 local fh = io.open(filename, "r")
353 if fh then
354 local file_uploads = json.import(fh:read("*a"))
355 for i, file_upload in ipairs(file_uploads) do
356 ui.image{ module = "draft", view = "show_file_upload", params = {
357 file_upload_session = file_upload_session, file_id = file_upload.id, preview = true
358 } }
359 ui.container{ content = function()
360 ui.tag{ tag = "strong", content = file_upload.title or "" }
361 end }
362 ui.container{ content = file_upload.description or "" }
363 ui.field.boolean{ label = _"delete", name = "file_upload_delete_" .. file_upload.id }
364 slot.put("<br />")
365 end
366 end
367 ui.container{ attr = { id = "file_upload_template", style = "display: none;" }, content = function()
368 ui.field.text{ label = _"Title", name = "__ID_title__" }
369 ui.field.text{ label = _"Description", name = "__ID_description__" }
370 ui.field.image{ field_name = "__ID_file__" }
371 end }
372 ui.container{ attr = { id = "file_upload" }, content = function()
373 end }
374 ui.field.hidden{ attr = { id = "file_upload_last_id" }, name = "file_upload_last_id" }
375 ui.script{ script = [[ var file_upload_id = 1; ]] }
376 ui.tag{ tag = "a", content = _"Attach image", attr = {
377 href = "#",
378 onclick = "var html = document.getElementById('file_upload_template').innerHTML; html = html.replace('__ID_file__', 'file_' + file_upload_id); html = html.replace('__ID_title__', 'title_' + file_upload_id); html = html.replace('__ID_description__', 'description_' + file_upload_id); var el = document.createElement('div'); el.innerHTML = html; document.getElementById('file_upload').appendChild(el); document.getElementById('file_upload_last_id').value = file_upload_id; file_upload_id++; return false;"
379 } }
380 slot.put("<br />")
382 slot.put("<br />")
384 end
386 ui.tag{
387 tag = "input",
388 attr = {
389 type = "submit",
390 name = "preview",
391 class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored",
392 value = _'Preview'
393 },
394 content = ""
395 }
396 slot.put(" ")
398 ui.link{
399 content = _"Cancel",
400 module = initiative and "initiative" or issue and "issue" or "index",
401 view = area and not issue and "index" or "show",
402 id = initiative_id or issue_id,
403 params = { area = area_id, unit = area and area.unit_id or nil },
404 attr = { class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" }
405 }
407 end
408 end }
409 end }
410 end }
412 if config.map or config.firstlife then
413 ui.cell_sidebar{ content = function()
414 ui.container{ attr = { class = "mdl-special-card map mdl-shadow--2dp" }, content = function()
415 ui.field.location{ name = "location", value = param.get("location") }
416 end }
417 end }
418 end
420 end }
421 end
422 }