liquid_feedback_frontend
view app/main/draft/new.lua @ 1704:cd3b521dc735
merge
| author | bsw | 
|---|---|
| date | Mon Sep 27 10:58:26 2021 +0200 (2021-09-27) | 
| parents | 05d2f46c60c5 | 
| 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("   ")
   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("   ")
   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("   ")
   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 }
