diff --git a/apps/home/static/home/css/index.css b/apps/home/static/home/css/index.css index a6ef60e..5122fc4 100644 --- a/apps/home/static/home/css/index.css +++ b/apps/home/static/home/css/index.css @@ -56,17 +56,23 @@ justify-content: flex-start; align-items: center; flex-wrap: nowrap; + color: var(--bs-text-body); background-color: var(--bg-tertiary-bg); transition: 0.3s; } -.server-item-selector:hover { +.server-item-selector .font-monospace { + color: var(--bs-secondary-color) +} + +.server-item-selector:hover, +.server-item-selector:focus, +.server-item-selector:active, +.server-item-selector.active { background-color: var(--bs-tertiary-bg); } -.server-item-selector:active, .server-item-selector.active { - background-color: var(--bs-tertiary-bg) !important; -} + /* widths */ diff --git a/apps/home/static/home/css/tables.css b/apps/home/static/home/css/tables.css index 88a0cf4..6d864cc 100644 --- a/apps/home/static/home/css/tables.css +++ b/apps/home/static/home/css/tables.css @@ -25,6 +25,18 @@ td > .btn-link { padding-left: 0; } } +/* Empty Table */ + +.table .dt-empty { + padding: 2rem 0; + border-bottom: none !important; +} + +.table tr:hover > .dt-empty { + box-shadow: none !important; +} + + /* Table Search */ .table-search-group { @@ -76,3 +88,31 @@ td > .btn-link { padding-left: 0; } outline: 0; box-shadow: none; } + + +/* Button Controls */ + +.table-search-buttons > div { + margin-left: 1rem; +} + +@media (max-width: 576px) { + .table-search-buttons > div { + margin-left: 0.25rem; + } +} + +.table-search-buttons > div:first-of-type { + margin-left: 0 !important; +} + + +/* Table Border Colour */ + +table.dataTable > thead > tr > th, table.dataTable > thead > tr > td { + border-bottom: 1px solid var(--bs-border-color); +} + +div.dt-container.dt-empty-footer tbody > tr:last-child > * { + border-bottom: 1px solid var(--bs-border-color); +} \ No newline at end of file diff --git a/apps/home/static/home/js/tables.js b/apps/home/static/home/js/tables.js index 53d07ba..40f3ef8 100644 --- a/apps/home/static/home/js/tables.js +++ b/apps/home/static/home/js/tables.js @@ -9,6 +9,9 @@ function initializeDataTable(tableId, columns) { searching: false, autoWidth: false, order: [], + language: { + emptyTable: "No results found" + }, select: { style: "multi+shift", selector: 'th:first-child input[type="checkbox"]' @@ -39,6 +42,7 @@ function initializeDataTable(tableId, columns) { bindTablePageSizer(tableId); bindTableSearch(tableId); bindRefreshButton(tableId); + bindDeleteButton(tableId); bindTableSelectColumn(tableId); } @@ -263,12 +267,19 @@ function bindTableSearch(tableId) { // region Button Controls function bindRefreshButton(tableId) { - let $tableFilters = $(tableId).closest('.js-tableBody').siblings('.js-tableFilters'); + const $tableFilters = $(tableId).closest('.js-tableBody').siblings('.js-tableFilters'); $tableFilters.on("click", ".table-refresh-btn", function() { $(tableId).trigger("doDataLoad"); }) } +function bindDeleteButton(tableId) { + const $tableFilters = $(tableId).closest(".js-tableBody").siblings(".js-tableFilters"); + $tableFilters.on("click", ".table-del-btn", function() { + alert("delete"); + }) +} + // region Select Checkboxes @@ -395,9 +406,53 @@ async function loadModalData($modal, url) { }); } +async function onModalSubmit($modal, $table, url) { + if (!selectedServer) { + return; + } + + let data = { server: selectedServer.id }; + + $modal.find("[data-field]").each(function() { + const type = $(this).attr("type"); + const key = $(this).attr("data-field"); + if (!key) { + return; + } + + let value; + if (type === "checkbox") { + value = $(this).prop("checked"); + } + else { + value = $(this).val(); + } + + data[key] = value; + }); + + const formData = objectToFormData(data); + const id = $modal.data("primary-key"); + const isNewItem = parseInt(id) !== -1; + const method = isNewItem ? "PATCH" : "POST"; + url = isNewItem ? url + `${id}/` : url; + + ajaxRequest(url, method, formData) + .then(response => { + $modal.modal("hide"); + $table.trigger("doDataLoad"); + }) + .catch(error => logError(error)); +} + // region Table Column Types +function renderEditColumn(data) { + const name = sanitise(data); + return `${name}`; +} + function renderBooleanColumn(data) { const iconClass = data ? "bi-check-circle-fill text-success" : "bi-x-circle-fill text-danger"; return ``; diff --git a/apps/home/static/home/js/tabs/filters.js b/apps/home/static/home/js/tabs/filters.js index 8c66c52..553f3e0 100644 --- a/apps/home/static/home/js/tabs/filters.js +++ b/apps/home/static/home/js/tabs/filters.js @@ -10,7 +10,8 @@ function initFiltersModule() { [ { title: "Name", - data: "name" + data: "name", + render: renderEditColumn }, { title: "Match", @@ -79,3 +80,32 @@ $(filterTableId).on("click", ".edit-modal", async function() { const id = $(filterTableId).DataTable().row($(this).closest("tr")).data().id; await openDataModal(filterModalId, id, `/api/filters/${id}/`); }); + +$(filterModalId).on("submit", async function(event) { + event.preventDefault(); + await onModalSubmit( + $(filterModalId), + $(filterTableId), + "/api/filters/" + ); +}); + + +// region Load Modal Options + +$(document).ready(async function() { + await loadMatchingAlgorithms(); +}); + +async function loadMatchingAlgorithms() { + const data = await ajaxRequest("/api/filters/", "OPTIONS"); + data.actions.GET.matching_algorithm.choices.forEach(algorithm => { + $(filterModalId).find('[data-field="matching_algorithm"]').append($( + "", + { + text: algorithm.display_name, + value: algorithm.value > 0 ? algorithm.value : "" + } + )); + }); +} diff --git a/apps/home/static/home/js/tabs/styles.js b/apps/home/static/home/js/tabs/styles.js index 7345c44..6aa3fe4 100644 --- a/apps/home/static/home/js/tabs/styles.js +++ b/apps/home/static/home/js/tabs/styles.js @@ -11,10 +11,7 @@ function initMessageStylesModule() { { title: "Name", data: "name", - render: function(data) { - const name = sanitise(data); - return `${name}`; - } + render: renderEditColumn }, { title: "Is Embed", @@ -98,50 +95,11 @@ $(styleTableId).on("click", ".edit-modal", async function() { $(styleModalId).on("submit", async function(event) { event.preventDefault(); - - if (!selectedServer) { - throw new Error("Cannot submit form while no server is selected"); - } - - let data = { server: selectedServer.id }; - - $(this).find("[data-field]").each(function() { - const type = $(this).attr("type"); - const key = $(this).attr("data-field"); - if (!key) { - return; - } - - let value; - if (type === "checkbox") { - value = $(this).prop("checked"); - } - else { - value = $(this).val(); - } - - data[key] = value; - }); - - const formData = objectToFormData(data); - const id = $(this).data("primary-key"); - - if (parseInt(id) !== -1) { - ajaxRequest(`/api/message-styles/${id}/`, "PATCH", formData) - .then(response => { - $(this).modal("hide"); - $(styleTableId).trigger("doDataLoad"); - }) - .catch(error => logError(error)) - } - else { - ajaxRequest("/api/message-styles/", "POST", formData) - .then(response => { - $(this).modal("hide"); - $(styleTableId).trigger("doDataLoad"); - }) - .catch(error => logError(error)); - } + await onModalSubmit( + $(styleModalId), + $(styleTableId), + "/api/message-styles/" + ); }); diff --git a/apps/home/static/home/js/tabs/subs.js b/apps/home/static/home/js/tabs/subs.js index 713b81a..20a63b1 100644 --- a/apps/home/static/home/js/tabs/subs.js +++ b/apps/home/static/home/js/tabs/subs.js @@ -13,10 +13,7 @@ function initSubscriptionsModule() { title: "Name", data: "name", className: "text-truncate col-3", - render: function(data, type, row) { - const name = sanitise(data); - return `${name}`; - } + render: renderEditColumn }, { title: "URL", @@ -112,56 +109,17 @@ $(subTableId).closest('.js-tableBody').siblings('.js-tableFilters').on("click", }); $(subTableId).on("click", ".edit-modal", async function() { - let id = $(subTableId).DataTable().row($(this).closest("tr")).data().id; + const id = $(subTableId).DataTable().row($(this).closest("tr")).data().id; await openDataModal(subModalId, id, `/api/subscriptions/${id}/`); }) $(subModalId).on("submit", async function(event) { event.preventDefault(); - - if (!selectedServer) { - throw new Error("Cannot submit form while no server is selected"); - } - - let data = { server: selectedServer.id }; - - $(this).find("[data-field]").each(function() { - const type = $(this).attr("type"); - const key = $(this).attr("data-field"); - if (!key) { - return; - } - - let value; - if (type === "checkbox") { - value = $(this).prop("checked"); - } - else { - value = $(this).val(); - } - - data[key] = value; - }); - - const formData = objectToFormData(data); - const id = $(this).data("primary-key"); - - if (parseInt(id) !== -1) { - ajaxRequest(`/api/subscriptions/${id}/`, "PATCH", formData) - .then(response => { - $(this).modal("hide"); - $(subTableId).trigger("doDataLoad"); - }) - .catch(error => logError(error)) - } - else { - ajaxRequest("/api/subscriptions/", "POST", formData) - .then(response => { - $(this).modal("hide"); - $(subTableId).trigger("doDataLoad"); - }) - .catch(error => logError(error)); - } + await onModalSubmit( + $(subModalId), + $(subTableId), + "/api/subscriptions/" + ); }); diff --git a/apps/home/templates/home/index.html b/apps/home/templates/home/index.html index 247e8db..a1d7d02 100644 --- a/apps/home/templates/home/index.html +++ b/apps/home/templates/home/index.html @@ -80,31 +80,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -138,18 +113,18 @@ Content Filters - - - - Tracked Content - - Message Styles + + + + Tracked Content + + @@ -157,7 +132,10 @@ - -- todo -- + Delete Server Data + + + Exit Server View @@ -173,12 +151,12 @@ {% include "home/tabs/filters.html" %} - - {% include "home/tabs/content.html" %} - {% include "home/tabs/styles.html" %} + + {% include "home/tabs/content.html" %} + @@ -199,8 +177,8 @@ - - + + diff --git a/apps/home/templates/home/modals/editFilter.html b/apps/home/templates/home/modals/editFilter.html index 692bb83..eb1dd43 100644 --- a/apps/home/templates/home/modals/editFilter.html +++ b/apps/home/templates/home/modals/editFilter.html @@ -7,6 +7,7 @@ Add Edit + Content Filter @@ -14,38 +15,36 @@ Name - - + + Human-readable name for this entry. - - - ----- - - + Matching Algorithm + + The algorithm used to match against. Match - - + + The value to match against. - + Case-Insensitive - + Should case-sensitivity be ignored? - + Whitelist Mode - + Overrides the default blacklist behaviour. diff --git a/static/css/base.css b/static/css/base.css index 8046a8c..035073c 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -75,27 +75,3 @@ .w-xxl-100 { width: 100%; } .w-xxl-auto { width: auto; } } - -.table-search-buttons > div { - margin-left: 1rem; -} - -@media (max-width: 576px) { - .table-search-buttons > div { - margin-left: 0.25rem; - } -} - -.table-search-buttons > div:first-of-type { - margin-left: 0 !important; -} - -/* Table Border Colour */ - -table.dataTable > thead > tr > th, table.dataTable > thead > tr > td { - border-bottom: 1px solid var(--bs-border-color) !important; -} - -div.dt-container.dt-empty-footer tbody > tr:last-child > * { - border-bottom: 1px solid var(--bs-border-color) !important; -} \ No newline at end of file