liquid_feedback_frontend

view app/main/draft/new.lua @ 1663:05d2f46c60c5

Fixed cancel link in preview
author bsw
date Mon Feb 15 14:20:07 2021 +0100 (2021-02-15)
parents 59cbb870253c
children 9b8dc1828f1f
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 if issue or initiative then
97 execute.view {
98 module = "issue", view = "_head", params = {
99 issue = issue or initiative.issue,
100 member = app.session.member
101 }
102 }
103 else
104 execute.view {
105 module = "area", view = "_head", params = {
106 area = area,
107 member = app.session.member
108 }
109 }
110 end
112 ui.grid{ content = function()
113 ui.cell_main{ content = function()
114 ui.container{ attr = { class = "mdl-card mdl-shadow--2dp mdl-card__fullwidth" }, content = function()
115 ui.container{ attr = { class = "mdl-card__title mdl-card--border" }, content = function()
116 if initiative then
117 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = initiative.display_name }
118 elseif param.get("name") then
119 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = param.get("name") }
120 elseif issue then
121 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = _("New competing initiative in issue '#{issue}'", { issue = issue.name }) }
122 elseif area then
123 ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = _"New issue" }
124 end
125 end }
126 ui.container{ attr = { class = "mdl-card__content mdl-card--border" }, content = function()
128 -- -------- PREVIEW
129 if param.get("preview") and slot.get_content("error") == "" then
130 ui.sectionRow( function()
131 if not issue and not initiative then
132 ui.container { content = policy and policy.name or "" }
133 end
134 if param.get("free_timing") then
135 ui.container { content = param.get("free_timing") }
136 end
137 slot.put("<br />")
138 ui.field.hidden{ name = "policy_id", value = param.get("policy_id") }
139 ui.field.hidden{ name = "name", value = param.get("name") }
140 if config.initiative_abstract then
141 ui.field.hidden{ name = "abstract", value = param.get("abstract") }
142 ui.container{
143 attr = { class = "abstract" },
144 content = param.get("abstract")
145 }
146 slot.put("<br />")
147 end
148 local draft_text = param.get("content")
149 local draft_text = util.wysihtml_preproc(draft_text)
150 ui.field.hidden{ name = "content", value = draft_text }
151 ui.container{
152 attr = { class = "draft" },
153 content = function()
154 slot.put(draft_text)
155 end
156 }
157 slot.put("<br />")
159 if config.attachments then
160 local file_upload_session = param.get("file_upload_session") or multirand.string(
161 32,
162 '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
163 )
164 file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "")
165 ui.field.hidden{ name = "file_upload_session", value = file_upload_session }
166 if initiative then
167 local files = File:new_selector()
168 :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id")
169 :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id }
170 :reset_fields()
171 :add_field("file.id")
172 :add_field("draft_attachment.title")
173 :add_field("draft_attachment.description")
174 :add_order_by("draft_attachment.id")
175 :exec()
177 if #files > 0 then
178 ui.container {
179 content = function()
180 for i, file in ipairs(files) do
181 if param.get("file_delete_" .. file.id, atom.boolean) then
182 ui.field.hidden{ name = "file_delete_" .. file.id, value = "1" }
183 else
184 ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } }
185 ui.container{ content = function()
186 ui.tag{ tag = "strong", content = file.title or "" }
187 end }
188 ui.container{ content = file.description or "" }
189 slot.put("<br /><br />")
190 end
191 end
192 end
193 }
194 end
195 end
196 local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json")
197 local fh = io.open(filename, "r")
198 if fh then
199 local file_uploads = json.import(fh:read("*a"))
200 for i, file_upload in ipairs(file_uploads) do
201 ui.image{ module = "draft", view = "show_file_upload", params = {
202 file_upload_session = file_upload_session, file_id = file_upload.id, preview = true
203 } }
204 ui.container{ content = function()
205 ui.tag{ tag = "strong", content = file_upload.title or "" }
206 end }
207 ui.container{ content = file_upload.description or "" }
208 slot.put("<br />")
209 end
210 end
211 end
213 ui.tag{
214 tag = "input",
215 attr = {
216 type = "submit",
217 class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored",
218 value = _'Publish now'
219 },
220 content = ""
221 }
222 slot.put(" &nbsp; ")
224 ui.tag{
225 tag = "input",
226 attr = {
227 type = "submit",
228 name = "edit",
229 class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect",
230 value = _'Edit again'
231 },
232 content = ""
233 }
234 slot.put(" &nbsp; ")
236 ui.link{
237 attr = { class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" },
238 content = _"Cancel",
239 module = initiative and "initiative" or "index",
240 view = initiative and "show" or "index",
241 id = initiative_id,
242 params = { unit = area and area.unit_id or nil, area = area_id }
243 }
244 end )
246 -- -------- EDIT
247 else
249 if not issue_id and not initiative_id then
250 local tmp = { { id = -1, name = "" } }
251 for i, allowed_policy in ipairs(area.allowed_policies) do
252 if not allowed_policy.polling or app.session.member:has_polling_right_for_unit_id(area.unit_id) then
253 tmp[#tmp+1] = allowed_policy
254 end
255 end
256 ui.container{ content = _"Please choose a policy for the new issue:" }
257 ui.field.select{
258 name = "policy_id",
259 foreign_records = tmp,
260 foreign_id = "id",
261 foreign_name = "name",
262 value = param.get("policy_id", atom.integer) or area.default_policy and area.default_policy.id
263 }
264 if policy and policy.free_timeable then
265 local available_timings
266 if config.free_timing and config.free_timing.available_func then
267 available_timings = config.free_timing.available_func(policy)
268 if available_timings == false then
269 slot.put_into("error", "error in free timing config")
270 return false
271 end
272 end
273 ui.heading{ level = 4, content = _"Free timing:" }
274 if available_timings then
275 ui.field.select{
276 name = "free_timing",
277 foreign_records = available_timings,
278 foreign_id = "id",
279 foreign_name = "name",
280 value = param.get("free_timing")
281 }
282 else
283 ui.field.text{
284 name = "free_timing",
285 value = param.get("free_timing")
286 }
287 end
288 end
289 end
291 if issue and issue.policy.polling and app.session.member:has_polling_right_for_unit_id(area.unit_id) then
292 slot.put("<br />")
293 ui.field.boolean{ name = "polling", label = _"No admission needed", value = polling }
294 end
296 if not initiative then
297 ui.container{ attr = { class = "mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-card__fullwidth" }, content = function ()
298 ui.field.text{
299 attr = { id = "lf-initiative__name", class = "mdl-textfield__input" },
300 label_attr = { class = "mdl-textfield__label", ["for"] = "lf-initiative__name" },
301 label = _"Title",
302 name = "name",
303 value = param.get("name")
304 }
305 end }
306 end
308 if config.initiative_abstract then
309 ui.container { content = _"Enter abstract:" }
310 ui.container{ attr = { class = "mdl-textfield mdl-js-textfield mdl-textfield--expandable mdl-textfield__fullwidth" }, content = function()
311 ui.field.text{
312 name = "abstract",
313 multiline = true,
314 attr = { id = "abstract", style = "height: 20ex; width: 100%;" },
315 value = param.get("abstract")
316 }
317 end }
318 end
320 ui.container { content = _"Enter your proposal and/or reasons:" }
321 ui.field.wysihtml{
322 name = "content",
323 multiline = true,
324 attr = { id = "draft", style = "height: 50ex; width: 100%;" },
325 value = param.get("content")
326 }
327 if not issue or issue.state == "admission" or issue.state == "discussion" then
328 ui.container { content = _"You can change your text again anytime during admission and discussion phase" }
329 else
330 ui.container { content = _"You cannot change your text again later, because this issue is already in verfication phase!" }
331 end
333 slot.put("<br />")
334 if config.attachments then
335 local file_upload_session = param.get("file_upload_session") or multirand.string(
336 32,
337 '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
338 )
339 file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "")
340 ui.field.hidden{ name = "file_upload_session", value = file_upload_session }
341 if initiative then
342 local files = File:new_selector()
343 :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id")
344 :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id }
345 :reset_fields()
346 :add_field("file.id")
347 :add_field("draft_attachment.title")
348 :add_field("draft_attachment.description")
349 :add_order_by("draft_attachment.id")
350 :exec()
352 if #files > 0 then
353 ui.container {
354 content = function()
355 for i, file in ipairs(files) do
356 ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } }
357 ui.container{ content = function()
358 ui.tag{ tag = "strong", content = file.title or "" }
359 end }
360 ui.container{ content = file.description or "" }
361 ui.field.boolean{ label = _"delete", name = "file_delete_" .. file.id, value = param.get("file_delete_" .. file.id) and true or false }
362 slot.put("<br /><br />")
363 end
364 end
365 }
366 end
367 end
368 local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json")
369 local fh = io.open(filename, "r")
370 if fh then
371 local file_uploads = json.import(fh:read("*a"))
372 for i, file_upload in ipairs(file_uploads) do
373 ui.image{ module = "draft", view = "show_file_upload", params = {
374 file_upload_session = file_upload_session, file_id = file_upload.id, preview = true
375 } }
376 ui.container{ content = function()
377 ui.tag{ tag = "strong", content = file_upload.title or "" }
378 end }
379 ui.container{ content = file_upload.description or "" }
380 ui.field.boolean{ label = _"delete", name = "file_upload_delete_" .. file_upload.id }
381 slot.put("<br />")
382 end
383 end
384 ui.container{ attr = { id = "file_upload_template", style = "display: none;" }, content = function()
385 ui.field.text{ label = _"Title", name = "__ID_title__" }
386 ui.field.text{ label = _"Description", name = "__ID_description__" }
387 ui.field.image{ field_name = "__ID_file__" }
388 end }
389 ui.container{ attr = { id = "file_upload" }, content = function()
390 end }
391 ui.field.hidden{ attr = { id = "file_upload_last_id" }, name = "file_upload_last_id" }
392 ui.script{ script = [[ var file_upload_id = 1; ]] }
393 ui.tag{ tag = "a", content = _"Attach image", attr = {
394 href = "#",
395 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;"
396 } }
397 slot.put("<br />")
399 slot.put("<br />")
401 end
403 ui.tag{
404 tag = "input",
405 attr = {
406 type = "submit",
407 name = "preview",
408 class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored",
409 value = _'Preview'
410 },
411 content = ""
412 }
413 slot.put(" &nbsp; ")
415 ui.link{
416 content = _"Cancel",
417 module = initiative and "initiative" or issue and "issue" or "index",
418 view = area and not issue and "index" or "show",
419 id = initiative_id or issue_id,
420 params = { area = area_id, unit = area and area.unit_id or nil },
421 attr = { class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" }
422 }
424 end
425 end }
426 end }
427 end }
429 if config.map or config.firstlife then
430 ui.cell_sidebar{ content = function()
431 ui.container{ attr = { class = "mdl-special-card map mdl-shadow--2dp" }, content = function()
432 local location = param.get("location")
433 local lat = param.get("lat", atom.number)
434 local lon = param.get("lon", atom.number)
435 if lat and lon then
436 location = json.export(json.object{
437 type = "Point",
438 coordinates = json.array{ lon, lat }
439 })
440 end
441 ui.field.location{ name = "location", value = location }
442 end }
443 end }
444 end
446 if config.firstlife then
447 ui.field.hidden{ name = "external_reference", value = param.get("external_reference") }
448 end
450 end }
451 end
452 }

Impressum / About Us