{% extends "base.html" %} {% block title %}<title>Zone Records - {{ domain.name | pretty_domain_name }} - {{ SITE_NAME }}</title>{% endblock %} {% block dashboard_stat %} <div class="content-header"> <div class="container-fluid"> <div class="row mb-2"> <div class="col-sm-6"> <h1 class="m-0 text-dark">Zone Records - {{ domain.name | pretty_domain_name }}</h1> </div> <div class="col-sm-6"> <ol class="breadcrumb float-sm-right"> <li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li> <li class="breadcrumb-item active">Zone Records - {{ domain.name | pretty_domain_name }}</li> </ol> </div> </div> </div> </div> {% endblock %} {% block content %} <section class="content"> <div class="container-fluid"> <div class="row"> <div class="col-12"> <div class="card"> <div class="card-header"> <h3 class="card-title">Zone Editor</h3> <div class="card-tools"> {% if current_user.role.name in ['Administrator', 'Operator'] %} <button type="button" title="Zone Settings" class="btn btn-primary btn-danger mt-2 mb-2" onclick="window.location.href='{{ url_for('domain.setting', domain_name=domain.name) }}'"> <i class="fa-solid fa-toolbox"></i> Zone Settings </button> {% endif %} {% if current_user.role.name in ['Administrator', 'Operator'] or allow_user_view_history %} <button type="button" title="Zone Changelog" class="btn btn-primary ml-2 mt-2 mb-2 button_changelog" id="{{ domain.name }}"> <i class="fa-solid fa-history" aria-hidden="true"></i> Changelog </button> {% endif %} {% if domain.type != 'Slave' %} <button type="button" title="Add Record" class="btn btn-primary ml-2 mt-2 mb-2 button_add_record" id="{{ domain.name }}"> <i class="fa-solid fa-plus"></i> Add Record </button> <button type="button" title="Save Changes" class="btn btn-primary ml-2 mt-2 mb-2 button_apply_changes" id="{{ domain.name }}" value="{{ domain.serial }}"> <i class="fa-solid fa-save"></i> Save Changes </button> {% else %} <button type="button" title="Update from Primary" class="btn btn-primary ml-2 mt-2 mb-2 button_update_from_primary" id="{{ domain.name }}"> <i class="fa-solid fa-sync"></i> Update from Primary </button> {% endif %} </div> </div> <div class="card-body table-responsive"> <table id="tbl_records" class="table table-bordered table-striped table-hover table-sm"> <thead> <tr> <th>Name</th> <th>Type</th> <th>Status</th> <th>TTL</th> <th>Data</th> {% if domain.type != 'Slave' %} <th>Comment</th> <th>Edit</th> <th>Delete</th> {% if current_user.role.name in ['Administrator', 'Operator'] or allow_user_view_history %} <th>Changelog</th> {% endif %} {% else %} <th>Invisible Sorting Column</th> {% endif %} </tr> </thead> <tbody> {% for record in records %} <tr class="odd row_record" id="{{ domain.name }}"> <td>{{ (record.name,domain.name) | display_record_name | pretty_domain_name }}</td> <td>{{ record.type }}</td> <td>{{ record.status }}</td> <td>{{ record.ttl }}</td> <td>{{ record.data | pretty_domain_name }}</td> {% if domain.type != 'Slave' %} <td>{{ record.comment }}</td> <td> {% if record.is_allowed_edit() %} <button type="button" class="btn btn-sm btn-warning button_edit"> <i class="fa-solid fa-edit"></i> </button> {% else %} <button type="button" class="btn btn-sm btn-warning"> <i class="fa-solid fa-exclamation-circle"></i> </button> {% endif %} </td> <td> {% if record.is_allowed_delete() %} <button type="button" class="btn btn-sm btn-danger button_delete"> <i class="fa-solid fa-trash"></i> </button> {% endif %} </td> {% if current_user.role.name in ['Administrator', 'Operator'] or allow_user_view_history %} <td> <button type="button" onclick="show_record_changelog('{{ record.name }}','{{ record.type }}',event)" class="btn btn-primary"> <i class="fa-solid fa-history" aria-hidden="true"></i> </button> </td> {% endif %} {% endif %} <!-- hidden column that we can sort on --> <td>1</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </div> </div> </section> {% endblock %} {% block head_styles %} <style> /* Page Specific Overrides */ table#tbl_records thead th:nth-child(1), table#tbl_records thead th:nth-child(2), table#tbl_records thead th:nth-child(3), table#tbl_records thead th:nth-child(4) { width: 100px; } table#tbl_records tbody td { text-align: center; } table#tbl_records tbody td:nth-child(0n+5), table#tbl_records tbody td:nth-child(0n+6) { text-align: left; word-break: break-all; } </style> {% endblock %} {% block extrascripts %} <script> // superglobals window.records_allow_edit = {{ editable_records | tojson }}; window.ttl_options = {{ ttl_options | tojson }}; window.nEditing = null; window.nNew = false; // set up user data table $("#tbl_records").DataTable({ "paging": true, "lengthChange": true, "searching": true, "ordering": true, "info": true, "autoWidth": false, {% if SETTING.get('default_record_table_size') | string in ['5','15','20'] %} "lengthMenu": [[5, 15, 20, -1], [5, 15, 20, "All"]], {% else %} "lengthMenu": [[5, 15, 20, {{ SETTING.get('default_record_table_size') }}, -1], [5, 15, 20, {{ SETTING.get('default_record_table_size') }}, "All"]], {% endif %} "pageLength": {{ SETTING.get('default_record_table_size') }}, "language": { "lengthMenu": " _MENU_ records" }, "retrieve": true, "columnDefs": [ { type: 'natural', targets: [0, 4] }, { targets: [0, 1, 2, 3, 4, 5], render: $.fn.dataTable.render.text() }, { // hidden column so that we can add new records on top // regardless of whatever sorting is done. See orderFixed visible: false, {% if domain.type != 'Slave' %} {% if current_user.role.name in ['Administrator', 'Operator'] or allow_user_view_history %} targets: [9] {% else %} targets: [8] {% endif %} {% else %} targets: [5] {% endif %} }, { targets: [0], className: "text-right", data: { '_': "0", 'sort': function (row, _type, _set, _meta) { const data = row[0] || ''; return data.split('.').reverse().join('.'); }, }, } ], {% if domain.type != 'Slave' %} {% if current_user.role.name in ['Administrator', 'Operator'] or allow_user_view_history %} "orderFixed": [[9, 'asc']] {% else %} "orderFixed": [[8, 'asc']] {% endif %} {% else %} "orderFixed": [[5, 'asc']] {% endif %} }); function show_record_changelog(record_name, record_type, e) { e.stopPropagation(); window.location.href = "/domain/{{domain.name}}/changelog/" + record_name + "./" + record_type; } // handle changelog button $(document.body).on("click", ".button_changelog", function (e) { e.stopPropagation(); window.location.href = "/domain/{{domain.name}}/changelog"; }); // handle delete button $(document.body).on("click", ".button_delete", function (e) { e.stopPropagation(); var modal = $("#modal_delete"); var table = $("#tbl_records").DataTable(); var record = $(this).prop('id'); var nRow = $(this).parents('tr')[0]; var info = "Are you sure you want to delete " + record + "?"; modal.find('.modal-body p').text(info); modal.modal('show'); $("#button_delete_confirm").unbind().one('click', function (e) { table.row(nRow).remove().draw(); modal.modal('hide'); }); $("#button_delete_cancel").unbind().one('click', function (e) { modal.modal('hide'); }); }); // handle edit button and record click {% if domain.type != 'Slave' %} $(document.body).on("click", ".button_edit{% if quick_edit %}, .row_record{% endif %}", function (e) { e.stopPropagation(); if ($(this).is('tr')) { var nRow = $(this)[0]; } else { var nRow = $(this).parents('tr')[0]; } var table = $("#tbl_records").DataTable(); if (nEditing == nRow) { /* click on row already being edited, do nothing */ } else if (nEditing !== null && nEditing != nRow && nNew == false) { /* Currently editing - but not this row - restore the old before continuing to edit mode */ restoreRow(table, nEditing); editRow(table, nRow); nEditing = nRow; } else if (nNew == true) { /* adding a new row, delete it and start editing */ table.row(nEditing).remove().draw(); nNew = false; editRow(table, nRow); nEditing = nRow; } else { /* No edit in progress - let's start one */ editRow(table, nRow); nEditing = nRow; } }); {% endif %} // handle apply changes button $(document.body).on("click", ".button_apply_changes", function () { if (nNew || nEditing) { showErrorModal("Previous record not saved. Please save it before applying the changes."); return; } var modal = $("#modal_apply_changes"); var table = $("#tbl_records").DataTable(); var domain = $(this).prop('id'); var serial = $(".button_apply_changes").val(); var info = "Are you sure you want to apply your changes?"; modal.find('.modal-body p').text(info); // following unbind("click") is to avoid multiple times execution modal.find('#button_apply_confirm').unbind("click").click(function () { var data = {'serial': serial, 'record': getTableData(table), '_csrf_token': '{{ csrf_token() }}'}; applyRecordChanges(data, domain); modal.modal('hide'); }) modal.modal('show'); }); // handle add record button $(document.body).on("click", ".button_add_record", function (e) { if (nNew || nEditing) { showErrorModal("Previous record not saved. Please save it before adding more record."); return; } // clear search first $("#tbl_records").DataTable().search('').columns().search('').draw(); // add new row var default_type = records_allow_edit[0] {% if current_user.role.name in ['Administrator', 'Operator'] or allow_user_view_history %} var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', window.ttl_options[0][0], '', '', '', '', '', '0']); {% else %} var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', window.ttl_options[0][0], '', '', '', '', '0']); {% endif %} editRow($("#tbl_records").DataTable(), nRow); document.getElementById("edit-row-focus").focus(); nEditing = nRow; nNew = true; }); //handle cancel button $(document.body).on("click", ".button_cancel", function (e) { e.stopPropagation(); var oTable = $("#tbl_records").DataTable(); if (nNew) { oTable.row(nEditing).remove().draw(); nEditing = null; nNew = false; } else { restoreRow(oTable, nEditing); nEditing = null; } }); //handle save button $(document.body).on("click", ".button_save", function (e) { e.stopPropagation(); var table = $("#tbl_records").DataTable(); saveRow(table, nEditing); nEditing = null; nNew = false; }); //handle update_from_primary button $(document.body).on("click", ".button_update_from_primary", function (e) { var domain = $(this).prop('id'); applyChanges({ 'domain': domain, '_csrf_token': '{{ csrf_token() }}' }, $SCRIPT_ROOT + '/domain/' + domain + '/update', true); }); {% if SETTING.get('record_helper') %} //handle wacky record types $(document.body).on("focus", "#current_edit_record_data", function (e) { var record_type = $(this).parents("tr").find('#record_type').val(); var record_data = $(this); if (record_type == "CAA") { var modal = $("#modal_custom_record"); if (record_data.val() == "") { var form = " <label for=\"caa_flag\">CAA Flag</label> \ <input type=\"text\" class=\"form-control\" name=\"caa_flag\" id=\"caa_flag\" placeholder=\"0\"> \ <label for=\"caa_tag\">CAA Tag</label> \ <input type=\"text\" class=\"form-control\" name=\"caa_tag\" id=\"caa_tag\" placeholder=\"issue\"> \ <label for=\"caa_value\">CAA Value</label> \ <input type=\"text\" class=\"form-control\" name=\"caa_value\" id=\"caa_value\" placeholder=\"eg. letsencrypt.org\"> \ "; } else { var parts = record_data.val().split(" "); var form = " <label for=\"caa_flag\">CAA Flag</label> \ <input type=\"text\" class=\"form-control\" name=\"caa_flag\" id=\"caa_flag\" placeholder=\"0\" value=\"" + parts[0] + "\"> \ <label for=\"caa_tag\">CAA Tag</label> \ <input type=\"text\" class=\"form-control\" name=\"caa_tag\" id=\"caa_tag\" placeholder=\"issue\" value=\"" + parts[1] + "\"> \ <label for=\"caa_value\">CAA Value</label> \ <input type=\"text\" class=\"form-control\" name=\"caa_value\" id=\"caa_value\" placeholder=\"eg. letsencrypt.org\" value=\"" + parts[2] + "\"> \ "; } modal.find('.modal-body p').html(form); modal.find('#button_save').click(function () { caa_flag = modal.find('#caa_flag').val(); caa_tag = modal.find('#caa_tag').val(); caa_value = modal.find('#caa_value').val(); data = caa_flag + " " + caa_tag + " " + '"' + caa_value + '"'; record_data.val(data); modal.modal('hide'); }) modal.modal('show'); } else if (record_type == "MX") { var modal = $("#modal_custom_record"); if (record_data.val() == "") { var form = " <label for=\"mx_priority\">MX Priority</label> \ <input type=\"text\" class=\"form-control\" name=\"mx_priority\" id=\"mx_priority\" placeholder=\"eg. 10\"> \ <label for=\"mx_server\">MX Server</label> \ <input type=\"text\" class=\"form-control\" name=\"mx_server\" id=\"mx_server\" placeholder=\"eg. postfix.example.com\"> \ "; } else { var parts = record_data.val().split(" "); var form = " <label for=\"mx_priority\">MX Priority</label> \ <input type=\"text\" class=\"form-control\" name=\"mx_priority\" id=\"mx_priority\" placeholder=\"eg. 10\" value=\"" + parts[0] + "\"> \ <label for=\"mx_server\">MX Server</label> \ <input type=\"text\" class=\"form-control\" name=\"mx_server\" id=\"mx_server\" placeholder=\"eg. postfix.example.com\" value=\"" + parts[1] + "\"> \ "; } modal.find('.modal-body p').html(form); modal.find('#button_save').click(function () { mx_server = modal.find('#mx_server').val(); mx_priority = modal.find('#mx_priority').val(); data = mx_priority + " " + mx_server; if (data && !data.endsWith('.')) { data = data + '.' } record_data.val(data); modal.modal('hide'); }) modal.modal('show'); } else if (record_type == "SRV") { var modal = $("#modal_custom_record"); if (record_data.val() == "") { var form = " <label for=\"srv_priority\">SRV Priority</label> \ <input type=\"text\" class=\"form-control\" name=\"srv_priority\" id=\"srv_priority\" placeholder=\"0\"> \ <label for=\"srv_weight\">SRV Weight</label> \ <input type=\"text\" class=\"form-control\" name=\"srv_weight\" id=\"srv_weight\" placeholder=\"10\"> \ <label for=\"srv_port\">SRV Port</label> \ <input type=\"text\" class=\"form-control\" name=\"srv_port\" id=\"srv_port\" placeholder=\"5060\"> \ <label for=\"srv_target\">SRV Target</label> \ <input type=\"text\" class=\"form-control\" name=\"srv_target\" id=\"srv_target\" placeholder=\"sip.example.com\"> \ "; } else { var parts = record_data.val().split(" "); var form = " <label for=\"srv_priority\">SRV Priority</label> \ <input type=\"text\" class=\"form-control\" name=\"srv_priority\" id=\"srv_priority\" placeholder=\"0\" value=\"" + parts[0] + "\"> \ <label for=\"srv_weight\">SRV Weight</label> \ <input type=\"text\" class=\"form-control\" name=\"srv_weight\" id=\"srv_weight\" placeholder=\"10\" value=\"" + parts[1] + "\"> \ <label for=\"srv_port\">SRV Port</label> \ <input type=\"text\" class=\"form-control\" name=\"srv_port\" id=\"srv_port\" placeholder=\"5060\" value=\"" + parts[2] + "\"> \ <label for=\"srv_target\">SRV Target</label> \ <input type=\"text\" class=\"form-control\" name=\"srv_target\" id=\"srv_target\" placeholder=\"sip.example.com\" value=\"" + parts[3] + "\"> \ "; } modal.find('.modal-body p').html(form); modal.find('#button_save').click(function () { srv_priority = modal.find('#srv_priority').val(); srv_weight = modal.find('#srv_weight').val(); srv_port = modal.find('#srv_port').val(); srv_target = modal.find('#srv_target').val(); data = srv_priority + " " + srv_weight + " " + srv_port + " " + srv_target; if (data && !data.endsWith('.')) { data = data + '.' } record_data.val(data); modal.modal('hide'); }) modal.modal('show'); } else if (record_type == "SOA") { var modal = $("#modal_custom_record"); if (record_data.val() == "") { var form = " <label for=\"soa_primaryns\">Primary Name Server</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_primaryns\" id=\"soa_primaryns\" placeholder=\"ns1.example.com\"> \ <label for=\"soa_adminemail\">Primary Contact</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_adminemail\" id=\"soa_adminemail\" placeholder=\"admin.example.com\"> \ <label for=\"soa_serial\">Serial</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_serial\" id=\"soa_serial\" placeholder=\"2016010101\"> \ <label for=\"soa_zonerefresh\">Zone refresh timer</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_zonerefresh\" id=\"soa_zonerefresh\" placeholder=\"86400\"> \ <label for=\"soa_failedzonerefresh\">Failed refresh retry timer</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_failedzonerefresh\" id=\"soa_failedzonerefresh\" placeholder=\"7200\"> \ <label for=\"soa_zoneexpiry\">Zone expiry timer</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_zoneexpiry\" id=\"soa_zoneexpiry\" placeholder=\"1209600\"> \ <label for=\"soa_minimumttl\">Minimum TTL</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_minimumttl\" id=\"soa_minimumttl\" placeholder=\"300\"> \ "; } else { var parts = record_data.val().split(" "); var form = " <label for=\"soa_primaryns\">Primary Name Server</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_primaryns\" id=\"soa_primaryns\" value=\"" + parts[0] + "\"> \ <label for=\"soa_adminemail\">Primary Contact</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_adminemail\" id=\"soa_adminemail\" value=\"" + parts[1] + "\"> \ <label for=\"soa_serial\">Serial</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_serial\" id=\"soa_serial\" value=\"" + parts[2] + "\"> \ <label for=\"soa_zonerefresh\">Zone refresh timer</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_zonerefresh\" id=\"soa_zonerefresh\" value=\"" + parts[3] + "\"> \ <label for=\"soa_failedzonerefresh\">Failed refresh retry timer</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_failedzonerefresh\" id=\"soa_failedzonerefresh\" value=\"" + parts[4] + "\"> \ <label for=\"soa_zoneexpiry\">Zone expiry timer</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_zoneexpiry\" id=\"soa_zoneexpiry\" value=\"" + parts[5] + "\"> \ <label for=\"soa_minimumttl\">Minimum TTL</label> \ <input type=\"text\" class=\"form-control\" name=\"soa_minimumttl\" id=\"soa_minimumttl\" value=\"" + parts[6] + "\"> \ "; } modal.find('.modal-body p').html(form); modal.find('#button_save').click(function () { soa_primaryns = modal.find('#soa_primaryns').val(); soa_adminemail = modal.find('#soa_adminemail').val(); soa_serial = modal.find('#soa_serial').val(); soa_zonerefresh = modal.find('#soa_zonerefresh').val(); soa_failedzonerefresh = modal.find('#soa_failedzonerefresh').val(); soa_zoneexpiry = modal.find('#soa_zoneexpiry').val(); soa_minimumttl = modal.find('#soa_minimumttl').val(); data = soa_primaryns + " " + soa_adminemail + " " + soa_serial + " " + soa_zonerefresh + " " + soa_failedzonerefresh + " " + soa_zoneexpiry + " " + soa_minimumttl; record_data.val(data); modal.modal('hide'); }) modal.modal('show'); } else if (record_type == "TLSA") { var modal = $("#modal_custom_record"); if (record_data.val() == "") { var form = " <label for=\"tlsa_certificate_usage\">TLSA Certificate Usage</label> \ <input type=\"text\" class=\"form-control\" name=\"tlsa_certificate_usage\" id=\"tlsa_certificate_usage\" placeholder=\"3\"> \ <label for=\"tlsa_selector\">TLSA-Selector</label> \ <input type=\"text\" class=\"form-control\" name=\"tlsa_selector\" id=\"tlsa_selector\" placeholder=\"1\"> \ <label for=\"tlsa_matching\"> TLSA Matching Type</label> \ <input type=\"text\" class=\"form-control\" name=\"tlsa_matching\" id=\"tlsa_matching\" placeholder=\"1\"> \ <label for=\"tlsa_hash\">Hash</label> \ <input type=\"text\" class=\"form-control\" name=\"tlsa_hash\" id=\"tlsa_hash\" placeholder=\"HASH\"> \ "; } else { var parts = record_data.val().split(" "); var form = " <label for=\"tlsa_certificate_usage\">TLSA Certificate Usage</label> \ <input type=\"text\" class=\"form-control\" name=\"tlsa_certificate_usage\" id=\"tlsa_certificate_usage\" value=\"" + parts[0] + "\"> \ <label for=\"tlsa_selector\">TLSA-Selector</label> \ <input type=\"text\" class=\"form-control\" name=\"tlsa_selector\" id=\"tlsa_selector\" value=\"" + parts[1] + "\"> \ <label for=\"tlsa_matching\"> TLSA Matching Type</label> \ <input type=\"text\" class=\"form-control\" name=\"tlsa_matching\" id=\"tlsa_matching\" value=\"" + parts[2] + "\"> \ <label for=\"tlsa_hash\">Hash</label> \ <input type=\"text\" class=\"form-control\" name=\"tlsa_hash\" id=\"tlsa_hash\" value=\"" + parts[3] + "\"> \ "; } modal.find('.modal-body p').html(form); modal.find('#button_save').click(function () { tlsa_certificate_usage = modal.find('#tlsa_certificate_usage').val(); tlsa_selector = modal.find('#tlsa_selector').val(); tlsa_matching = modal.find('#tlsa_matching').val(); tlsa_hash = modal.find('#tlsa_hash').val(); data = tlsa_certificate_usage + " " + tlsa_selector + " " + tlsa_matching + " " + tlsa_hash; record_data.val(data); modal.modal('hide'); }) modal.modal('show'); } else if (record_type == "TXT") { var txt_data = record_data.val().replace(/"/g, '"'); var modal = $("#modal_custom_record"); var form = " <label for=\"txt_record\">TXT Record Data</label> \ <textarea style=\"min-width: 100%;color: #333;\" placeholder=\"Your TXT record data\" rows=\"5\" id=\"txt_record\" name=\"txt_record\">" + txt_data + "</textarea> \ "; modal.find('.modal-body p').html(form); modal.find('#button_save').click(function () { data = modal.find('#txt_record').val(); if (!/^".*"$/.test(data)) { data = '"' + data + '"'; } record_data.val(data); modal.modal('hide'); }); modal.modal('show'); } else if (record_type == "LUA") { var lua_type = record_data.val().split(" ")[0]; var lua_data = record_data.val().substr(record_data.val().indexOf(" ") + 1).replace(/"/g, '"'); var modal = $("#modal_custom_record"); var form = " <label for=\"lua_type\">Lua Record Type</label> \ <input type=\"text\" class=\"form-control\" name=\"lua_type\" id=\"lua_type\" placeholder=\"Initial query type. Example: A, CNAME or PTR \" value=\"" + lua_type + "\"> \ <label for=\"lua_record\">Lua Record Data</label> \ <textarea style=\"min-width: 100%;color: #333;\" placeholder=\"Your LUA snippet\" rows=\"5\" id=\"lua_record\" name=\"lua_record\">" + lua_data + "</textarea> \ "; modal.find('.modal-body p').html(form); modal.find('#button_save').click(function () { type = modal.find('#lua_type').val(); data = modal.find('#lua_record').val(); if (!/^".*"$/.test(data)) { data = '"' + data + '"'; } data = type + ' ' + data; record_data.val(data); modal.modal('hide'); }); modal.modal('show'); } }); {% endif %} window.onload = function () { document.getElementById("loading-spinner").style.display = "none"; } </script> {% endblock %} {% block modals %} <div class="modal fade" id="modal_delete"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">Confirmation</h4> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p></p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary pull-left" id="button_delete_cancel" data-dismiss="modal"> <i class="fa-solid fa-window-close"></i> Close </button> <button type="button" class="btn btn-danger" id="button_delete_confirm"> <i class="fa-solid fa-trash"></i> Delete </button> </div> </div> </div> </div> <div class="modal fade" id="modal_apply_changes"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">Confirmation</h4> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p></p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal"> <i class="fa-solid fa-window-close"></i> Close </button> <button type="button" class="btn btn-success" id="button_apply_confirm"> <i class="fa-solid fa-save"></i> Apply Changes </button> </div> </div> </div> </div> <div class="modal fade" id="modal_custom_record"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">Custom Record</h4> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p></p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal"> <i class="fa-solid fa-window-close"></i> Close </button> <button type="button" class="btn btn-success" id="button_save"> <i class="fa-solid fa-save"></i> Save </button> </div> </div> </div> </div> {% endblock %}