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