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