modals: Add edit_fields_modal.js and edit_field_modals.hbs.

We create a new widget edit_fields_modal such that this common
framework can be used in bot-edit modal, linkifier-edit modal
and user-edit modal, which have very similar implementations.

The "edit-fields-modal-status" is used only for edit-linkifier
modal and remains empty for others, so this change does not
cause problems with other modals.
This commit is contained in:
sahil839 2021-06-09 00:11:47 +05:30 committed by Tim Abbott
parent be3b637603
commit 36560da0f0
4 changed files with 81 additions and 0 deletions

View File

@ -0,0 +1,67 @@
import $ from "jquery";
import render_edit_fields_modal from "../templates/settings/edit_fields_modal.hbs";
import * as blueslip from "./blueslip";
import * as overlays from "./overlays";
/*
Look for edit_fields_modal in settings_users.js to see an
example of how to use this widget.
Some things to note:
1) We create the DOM elements on the fly, and we remove the
DOM elements once it's closed.
2) We attach the DOM elements for the modal to modal_fields.parent.
3) The cancel button is driven by bootstrap.js.
4) We do not handle closing the modal on clicking "Save
changes" here, because some modals show errors, if the
request fails, in the modal itself without closing.
5) If a caller needs to run code after the modal body is added
to DOM, it can do so by passing a post_render hook.
*/
export function launch(modal_fields) {
const required_modal_fields = ["modal_label", "parent", "modal_body_html", "on_click"];
for (const field of required_modal_fields) {
if (!modal_fields[field]) {
blueslip.error("programmer omitted " + field);
}
}
const html = render_edit_fields_modal({
modal_label: modal_fields.modal_label,
});
const edit_fields_modal = $(html);
modal_fields.parent.append(edit_fields_modal);
if (overlays.is_modal_open()) {
overlays.close_modal("#edit-fields-modal");
}
edit_fields_modal.find(".edit-fields-modal-body").html(modal_fields.modal_body_html);
if (modal_fields.post_render !== undefined) {
modal_fields.post_render();
}
// Set up handlers.
$(".submit-modal-button").on("click", (e) => {
e.preventDefault();
e.stopPropagation();
modal_fields.on_click();
});
edit_fields_modal.on("hidden.bs.modal", () => {
edit_fields_modal.remove();
});
// Open the modal
overlays.open_modal("#edit-fields-modal");
}

View File

@ -0,0 +1,12 @@
<div id="edit-fields-modal" class="modal modal-bg hide fade" tabindex="-1" role="dialog" aria-labelledby="edit-fields-modal-label" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="{{t 'Close' }}"><span aria-hidden="true">&times;</span></button>
<h3 id="edit-fields-modal-label">{{modal_label}}</h3>
<div class="alert" id="edit-fields-modal-status"></div>
</div>
<div class="modal-body edit-fields-modal-body"></div>
<div class="modal-footer">
<button type="submit" class="button rounded sea-green submit-modal-button">{{t 'Save changes' }}</button>
<button type="button" class="button rounded close-modal-button" data-dismiss="modal">{{t "Cancel" }}</button>
</div>
</div>

View File

@ -134,6 +134,7 @@ js_rules = RuleList(
"static/js/lightbox.js",
"static/js/ui_report.ts",
"static/js/confirm_dialog.js",
"static/js/edit_fields_modal.js",
"frontend_tests/",
},
"description": "Setting HTML content with jQuery .html() can lead to XSS security bugs. Consider .text() or using rendered_foo as a variable name if content comes from handlebars and thus is already sanitized.",

View File

@ -60,6 +60,7 @@ EXEMPT_FILES = {
"static/js/desktop_integration.js",
"static/js/drafts.js",
"static/js/echo.js",
"static/js/edit_fields_modal.js",
"static/js/emoji_picker.js",
"static/js/emojisets.js",
"static/js/favicon.js",