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