liquid_feedback_frontend

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

Impressum / About Us