bsw@1496: local issue bsw@1496: local area bsw@1496: local area_id bsw/jbe@0: bsw@1496: local issue_id = param.get("issue_id", atom.integer) bsw@1496: if issue_id then bsw@1496: issue = Issue:new_selector():add_where{"id=?",issue_id}:single_object_mode():exec() bsw@1496: issue:load_everything_for_member_id(app.session.member_id) bsw@1496: area = issue.area bsw@1496: else bsw@1496: area_id = param.get("area_id", atom.integer) bsw@1496: if area_id then bsw@1496: area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec() bsw@1496: area:load_delegation_info_once_for_member_id(app.session.member_id) bsw@1496: end bsw@1496: end bsw@1496: bsw@1496: local polling = param.get("polling", atom.boolean) bsw@1496: bsw@1496: local policy_id = param.get("policy_id", atom.integer) bsw@1496: local policy bsw@1496: bsw@1496: local preview = param.get("preview") bsw@1496: bsw@1496: if #(slot.get_content("error")) > 0 then bsw@1496: preview = false bsw@1496: end bsw@1496: bsw@1496: if policy_id then bsw@1496: policy = Policy:by_id(policy_id) bsw@1135: end bsw@1135: bsw@1535: local callback = param.get("callback") bsw@1496: bsw@1496: bsw@1496: local initiative_id = param.get("initiative_id") bsw@1496: local initiative = Initiative:by_id(initiative_id) bsw@1496: local draft bsw@1496: if initiative then bsw@1496: initiative:load_everything_for_member_id(app.session.member_id) bsw@1496: initiative.issue:load_everything_for_member_id(app.session.member_id) bsw@1496: bsw@1496: if initiative.issue.closed then bsw@1496: slot.put_into("error", _"This issue is already closed.") bsw@1496: return bsw@1496: elseif initiative.issue.half_frozen then bsw@1496: slot.put_into("error", _"This issue is already frozen.") bsw@1496: return bsw@1496: elseif initiative.issue.phase_finished then bsw@1496: slot.put_into("error", _"Current phase is already closed.") bsw@1496: return bsw/jbe@1309: end bsw@1496: bsw@1496: draft = initiative.current_draft bsw@1496: if config.initiative_abstract then bsw@1496: draft.abstract = string.match(draft.content, "(.+)") bsw@1496: if draft.abstract then bsw@1496: draft.content = string.match(draft.content, "(.*)") bsw@1496: end bsw@1496: end bsw@1496: end bsw@1496: bsw@1496: if not initiative and not issue and not area then bsw@1496: ui.heading{ content = _"Missing parameter" } bsw@1496: return false bsw/jbe@1309: end bsw@95: bsw/jbe@0: ui.form{ bsw/jbe@1309: record = draft, bsw@1495: attr = { class = "vertical section", enctype = 'multipart/form-data' }, bsw/jbe@0: module = "draft", bsw/jbe@0: action = "add", bsw@1496: params = { bsw@1496: area_id = area and area.id, bsw@1496: issue_id = issue and issue.id or nil, bsw@1535: initiative_id = initiative_id, bsw@1535: callback = callback bsw@1496: }, bsw/jbe@0: routing = { bsw@95: ok = { bsw/jbe@0: mode = "redirect", bsw/jbe@0: module = "initiative", bsw/jbe@0: view = "show", bsw@1496: id = initiative_id bsw/jbe@0: } bsw/jbe@0: }, bsw/jbe@0: content = function() bsw@1045: bsw/jbe@1309: ui.grid{ content = function() bsw/jbe@1309: ui.cell_main{ content = function() bsw/jbe@1309: ui.container{ attr = { class = "mdl-card mdl-shadow--2dp mdl-card__fullwidth" }, content = function() bsw/jbe@1309: ui.container{ attr = { class = "mdl-card__title mdl-card--border" }, content = function() bsw@1496: if initiative then bsw@1496: ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = initiative.display_name } bsw@1496: elseif param.get("name") then bsw@1496: ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = param.get("name") } bsw@1496: elseif issue then bsw@1496: ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = _("New competing initiative in issue '#{issue}'", { issue = issue.name }) } bsw@1496: elseif area then bsw@1496: ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = _("New issue in area '#{area}'", { area = area.name }) } bsw@1496: end bsw/jbe@1309: end } bsw/jbe@1309: ui.container{ attr = { class = "mdl-card__content mdl-card--border" }, content = function() bsw@1496: bsw@1496: -- -------- PREVIEW bsw/jbe@1309: if param.get("preview") then bsw/jbe@1309: ui.sectionRow( function() bsw@1496: if not issue and not initiative then bsw@1496: ui.container { content = policy.name } bsw@1496: end bsw@1496: if param.get("free_timing") then bsw@1496: ui.container { content = param.get("free_timing") } bsw@1496: end bsw@1496: slot.put("
") bsw@1496: ui.field.hidden{ name = "policy_id", value = param.get("policy_id") } bsw@1496: ui.field.hidden{ name = "name", value = param.get("name") } bsw/jbe@1309: if config.initiative_abstract then bsw/jbe@1309: ui.field.hidden{ name = "abstract", value = param.get("abstract") } bsw/jbe@1309: ui.container{ bsw/jbe@1309: attr = { class = "abstract" }, bsw/jbe@1309: content = param.get("abstract") bsw/jbe@1309: } bsw/jbe@1309: slot.put("
") bsw/jbe@1309: end bsw/jbe@1309: local draft_text = param.get("content") bsw/jbe@1309: local draft_text = util.wysihtml_preproc(draft_text) bsw/jbe@1309: ui.field.hidden{ name = "content", value = draft_text } bsw/jbe@1309: ui.container{ bsw/jbe@1309: attr = { class = "draft" }, bsw/jbe@1309: content = function() bsw/jbe@1309: slot.put(draft_text) bsw/jbe@1309: end bsw/jbe@1309: } bsw/jbe@1309: slot.put("
") bsw@95: bsw@1495: if config.attachments then bsw@1495: local file_upload_session = param.get("file_upload_session") or multirand.string( bsw@1495: 32, bsw@1495: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' bsw@1495: ) bsw@1495: file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "") bsw@1495: ui.field.hidden{ name = "file_upload_session", value = file_upload_session } bsw@1496: if initiative then bsw@1496: local files = File:new_selector() bsw@1496: :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id") bsw@1496: :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id } bsw@1496: :reset_fields() bsw@1496: :add_field("file.id") bsw@1496: :add_field("draft_attachment.title") bsw@1496: :add_field("draft_attachment.description") bsw@1496: :add_order_by("draft_attachment.id") bsw@1496: :exec() bsw@1495: bsw@1496: if #files > 0 then bsw@1496: ui.container { bsw@1496: content = function() bsw@1496: for i, file in ipairs(files) do bsw@1496: if param.get("file_delete_" .. file.id, atom.boolean) then bsw@1496: ui.field.hidden{ name = "file_delete_" .. file.id, value = "1" } bsw@1496: else bsw@1496: ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } } bsw@1496: ui.container{ content = function() bsw@1496: ui.tag{ tag = "strong", content = file.title or "" } bsw@1496: end } bsw@1496: ui.container{ content = file.description or "" } bsw@1496: slot.put("

") bsw@1496: end bsw@1495: end bsw@1495: end bsw@1496: } bsw@1496: end bsw@1495: end bsw@1495: local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json") bsw@1495: local fh = io.open(filename, "r") bsw@1495: if fh then bsw@1495: local file_uploads = json.import(fh:read("*a")) bsw@1495: for i, file_upload in ipairs(file_uploads) do bsw@1495: ui.image{ module = "draft", view = "show_file_upload", params = { bsw@1495: file_upload_session = file_upload_session, file_id = file_upload.id, preview = true bsw@1495: } } bsw@1496: ui.container{ content = function() bsw@1496: ui.tag{ tag = "strong", content = file_upload.title or "" } bsw@1496: end } bsw@1495: ui.container{ content = file_upload.description or "" } bsw@1495: slot.put("
") bsw@1495: end bsw@1495: end bsw@1495: end bsw@1495: bsw/jbe@1309: ui.tag{ bsw/jbe@1309: tag = "input", bsw/jbe@1309: attr = { bsw/jbe@1309: type = "submit", bsw/jbe@1309: class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored", bsw/jbe@1309: value = _'Publish now' bsw/jbe@1309: }, bsw/jbe@1309: content = "" bsw/jbe@1309: } bsw/jbe@1309: slot.put("   ") bsw/jbe@1309: bsw/jbe@1309: ui.tag{ bsw/jbe@1309: tag = "input", bsw/jbe@1309: attr = { bsw/jbe@1309: type = "submit", bsw/jbe@1309: name = "edit", bsw/jbe@1309: class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect", bsw/jbe@1309: value = _'Edit again' bsw/jbe@1309: }, bsw/jbe@1309: content = "" bsw/jbe@1309: } bsw/jbe@1309: slot.put("   ") bsw@95: bsw/jbe@1309: ui.link{ bsw/jbe@1309: attr = { class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" }, bsw/jbe@1309: content = _"Cancel", bsw@1496: module = initiative and "initiative" or "area", bsw/jbe@1309: view = "show", bsw@1496: id = initiative_id or area_id bsw/jbe@1309: } bsw/jbe@1309: end ) bsw@1045: bsw@1496: -- -------- EDIT bsw/jbe@1309: else bsw@1496: bsw@1496: if not issue_id and not initiative_id then bsw@1496: local tmp = { { id = -1, name = "" } } bsw@1496: for i, allowed_policy in ipairs(area.allowed_policies) do bsw@1496: if not allowed_policy.polling or app.session.member:has_polling_right_for_unit_id(area.unit_id) then bsw@1496: tmp[#tmp+1] = allowed_policy bsw@1496: end bsw@1496: end bsw@1496: ui.container{ content = _"Please choose a policy for the new issue:" } bsw@1496: ui.field.select{ bsw@1496: name = "policy_id", bsw@1496: foreign_records = tmp, bsw@1496: foreign_id = "id", bsw@1496: foreign_name = "name", bsw@1496: value = param.get("policy_id", atom.integer) or area.default_policy and area.default_policy.id bsw@1496: } bsw@1496: if policy and policy.free_timeable then bsw@1496: local available_timings bsw@1496: if config.free_timing and config.free_timing.available_func then bsw@1496: available_timings = config.free_timing.available_func(policy) bsw@1496: if available_timings == false then bsw@1496: slot.put_into("error", "error in free timing config") bsw@1496: return false bsw@1496: end bsw@1496: end bsw@1496: ui.heading{ level = 4, content = _"Free timing:" } bsw@1496: if available_timings then bsw@1496: ui.field.select{ bsw@1496: name = "free_timing", bsw@1496: foreign_records = available_timings, bsw@1496: foreign_id = "id", bsw@1496: foreign_name = "name", bsw@1496: value = param.get("free_timing") bsw@1496: } bsw@1496: else bsw/jbe@1309: ui.field.text{ bsw@1496: name = "free_timing", bsw@1496: value = param.get("free_timing") bsw/jbe@1309: } bsw@1496: end bsw/jbe@1309: end bsw@1496: end bsw@1496: bsw@1496: if issue and issue.policy.polling and app.session.member:has_polling_right_for_unit_id(area.unit_id) then bsw@1496: slot.put("
") bsw@1496: ui.field.boolean{ name = "polling", label = _"No admission needed", value = polling } bsw@1496: end bsw@1496: bsw@1496: if not initiative then bsw@1496: ui.container{ attr = { class = "mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-card__fullwidth" }, content = function () bsw@1496: ui.field.text{ bsw@1496: attr = { id = "lf-initiative__name", class = "mdl-textfield__input" }, bsw@1496: label_attr = { class = "mdl-textfield__label", ["for"] = "lf-initiative__name" }, bsw@1496: label = _"Title", bsw@1496: name = "name", bsw@1496: value = param.get("name") bsw@1496: } bsw@1496: end } bsw@1496: end bsw@1495: bsw@1496: if config.initiative_abstract then bsw@1496: ui.container { content = _"Enter abstract:" } bsw@1496: ui.container{ attr = { class = "mdl-textfield mdl-js-textfield mdl-textfield--expandable mdl-textfield__fullwidth" }, content = function() bsw@1496: ui.field.text{ bsw@1496: name = "abstract", bsw@1496: multiline = true, bsw@1496: attr = { id = "abstract", style = "height: 20ex; width: 100%;" }, bsw@1496: value = param.get("abstract") bsw@1496: } bsw@1496: end } bsw@1496: end bsw@1496: bsw@1496: ui.container { content = _"Enter your proposal and/or reasons:" } bsw@1496: ui.field.wysihtml{ bsw@1496: name = "content", bsw@1496: multiline = true, bsw@1496: attr = { id = "draft", style = "height: 50ex; width: 100%;" }, bsw@1496: value = param.get("content") bsw@1496: } bsw@1496: if not issue or issue.state == "admission" or issue.state == "discussion" then bsw@1496: ui.container { content = _"You can change your text again anytime during admission and discussion phase" } bsw@1496: else bsw@1496: ui.container { content = _"You cannot change your text again later, because this issue is already in verfication phase!" } bsw@1496: end bsw@1496: bsw@1496: slot.put("
") bsw@1496: if config.attachments then bsw@1496: local file_upload_session = param.get("file_upload_session") or multirand.string( bsw@1496: 32, bsw@1496: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' bsw@1496: ) bsw@1496: file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "") bsw@1496: ui.field.hidden{ name = "file_upload_session", value = file_upload_session } bsw@1496: if initiative then bsw@1495: local files = File:new_selector() bsw@1495: :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id") bsw@1495: :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id } bsw@1495: :reset_fields() bsw@1495: :add_field("file.id") bsw@1495: :add_field("draft_attachment.title") bsw@1495: :add_field("draft_attachment.description") bsw@1495: :add_order_by("draft_attachment.id") bsw@1495: :exec() bsw@1495: bsw@1495: if #files > 0 then bsw@1495: ui.container { bsw@1495: content = function() bsw@1495: for i, file in ipairs(files) do bsw@1495: ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } } bsw@1496: ui.container{ content = function() bsw@1496: ui.tag{ tag = "strong", content = file.title or "" } bsw@1496: end } bsw@1495: ui.container{ content = file.description or "" } bsw@1495: ui.field.boolean{ label = _"delete", name = "file_delete_" .. file.id, value = param.get("file_delete_" .. file.id) and true or false } bsw@1495: slot.put("

") bsw@1495: end bsw@1495: end bsw@1495: } bsw@1495: end bsw@1496: end bsw@1496: local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json") bsw@1496: local fh = io.open(filename, "r") bsw@1496: if fh then bsw@1496: local file_uploads = json.import(fh:read("*a")) bsw@1496: for i, file_upload in ipairs(file_uploads) do bsw@1496: ui.image{ module = "draft", view = "show_file_upload", params = { bsw@1496: file_upload_session = file_upload_session, file_id = file_upload.id, preview = true bsw@1496: } } bsw@1496: ui.container{ content = function() bsw@1496: ui.tag{ tag = "strong", content = file_upload.title or "" } bsw@1496: end } bsw@1496: ui.container{ content = file_upload.description or "" } bsw@1496: ui.field.boolean{ label = _"delete", name = "file_upload_delete_" .. file_upload.id } bsw@1496: slot.put("
") bsw@1495: end bsw@1496: end bsw@1496: ui.container{ attr = { id = "file_upload_template", style = "display: none;" }, content = function() bsw@1496: ui.field.text{ label = _"Title", name = "__ID_title__" } bsw@1496: ui.field.text{ label = _"Description", name = "__ID_description__" } bsw@1496: ui.field.image{ field_name = "__ID_file__" } bsw@1496: end } bsw@1496: ui.container{ attr = { id = "file_upload" }, content = function() bsw@1496: end } bsw@1496: ui.field.hidden{ attr = { id = "file_upload_last_id" }, name = "file_upload_last_id" } bsw@1496: ui.script{ script = [[ var file_upload_id = 1; ]] } bsw@1496: ui.tag{ tag = "a", content = _"Attach image", attr = { bsw@1496: href = "#", bsw@1496: 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: } } bsw@1496: slot.put("
") bsw@1496: bsw@1496: slot.put("
") bsw@1495: bsw@1496: end bsw@1045: bsw@1496: ui.tag{ bsw@1496: tag = "input", bsw@1496: attr = { bsw@1496: type = "submit", bsw@1496: name = "preview", bsw@1496: class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored", bsw@1496: value = _'Preview' bsw@1496: }, bsw@1496: content = "" bsw@1496: } bsw@1496: slot.put("   ") bsw@1496: bsw@1496: ui.link{ bsw@1496: content = _"Cancel", bsw@1496: module = initiative and "initiative" or issue and "issue" or "index", bsw@1497: view = area and not issue and "index" or "show", bsw@1496: id = initiative_id or issue_id, bsw@1496: params = { area = area_id, unit = area and area.unit_id or nil }, bsw@1496: attr = { class = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" } bsw@1496: } bsw@1496: bsw/jbe@1309: end bsw/jbe@1309: end } bsw/jbe@1309: end } bsw/jbe@1309: end } bsw@1520: bsw@1520: if config.map or config.firstlife then bsw@1520: ui.cell_sidebar{ content = function() bsw@1520: ui.container{ attr = { class = "mdl-special-card map mdl-shadow--2dp" }, content = function() bsw@1520: ui.field.location{ name = "location", value = param.get("location") } bsw@1520: end } bsw@1520: end } bsw@1520: end bsw@1520: bsw/jbe@1309: end } bsw/jbe@0: end bsw/jbe@0: }