diff --git a/src/client/src/ts/guild/feeds.ts b/src/client/src/ts/guild/feeds.ts index 9e19586..562399b 100644 --- a/src/client/src/ts/guild/feeds.ts +++ b/src/client/src/ts/guild/feeds.ts @@ -1,12 +1,12 @@ import { formatTimestamp, verifyChannels } from "../main"; import HSDropdown from "preline/dist/dropdown"; -import HSDataTable, { IDataTableOptions } from "preline/dist/datatable"; import HSSelect, { ISelectOptions } from "preline/dist/select"; import HSOverlay, { IOverlayOptions } from "preline/dist/overlay"; +import HSDataTable, { IDataTableOptions } from "preline/dist/datatable"; import { Api, AjaxSettings, ConfigColumnDefs } from "datatables.net-dt"; +import { TextChannel } from "discord.js"; import "datatables.net-select-dt" import prisma from "../../../../../generated/prisma"; -import { TextChannel } from "discord.js"; declare let guildId: string; declare let channels: Array; diff --git a/src/client/src/ts/guild/filters.ts b/src/client/src/ts/guild/filters.ts index f95449a..a9ea1d6 100644 --- a/src/client/src/ts/guild/filters.ts +++ b/src/client/src/ts/guild/filters.ts @@ -1,12 +1,10 @@ -import $ from "jquery"; -import "datatables.net-select-dt"; -import HSDropdown from "@preline/dropdown"; -import HSOverlay, { IOverlayOptions } from "@preline/overlay"; -import HSSelect, { ISelectOptions, ISingleOption } from "@preline/select"; -import HSDataTable, { IDataTableOptions } from "@preline/datatable"; -import DataTable, { Api, ConfigColumnDefs, AjaxSettings } from "datatables.net-dt"; -import { autoUpdate, computePosition, offset } from "@floating-ui/dom"; import { formatTimestamp } from "../main"; +import HSDropdown from "preline/dist/dropdown"; +import HSSelect, { ISelectOptions } from "preline/dist/select"; +import HSOverlay, { IOverlayOptions } from "preline/dist/overlay"; +import HSDataTable, { IDataTableOptions } from "preline/dist/datatable"; +import { Api, AjaxSettings, ConfigColumnDefs } from "datatables.net-dt"; +import "datatables.net-select-dt" import prisma from "../../../../../generated/prisma"; declare let guildId: string; @@ -14,9 +12,6 @@ declare const matchingAlgorithms: { [key: string]: string }; // #region DataTable -(window as any).DataTable = DataTable; -(window as any).$hsDataTableCollection = []; - const emptyTableHtml: string = `
@@ -43,8 +38,7 @@ const emptyTableHtml: string = ` `; const columnDefs: ConfigColumnDefs[] = [ - // Select checkbox column - { + { // Select checkbox column target: 0, orderable: false, searchable: false, @@ -197,10 +191,20 @@ const tableOptions: IDataTableOptions = { } }; -const table = new HSDataTable( - $("#table").get(0) as HTMLElement, - tableOptions -) +let table: HSDataTable; + +window.addEventListener("preline:ready", () => { + const tableEl = $("#table").get(0); + + if (HSDataTable.getInstance(tableEl, true)) return; + + table = new HSDataTable(tableEl, tableOptions); + + (table as any).dataTable + .on("select", onTableSelectChange) + .on("deselect", onTableSelectChange) + .on("draw", onTableSelectChange); +}); const onTableSelectChange = () => { const selectedRowsCount = (table as any).dataTable.rows({ selected: true }).count(); @@ -211,15 +215,11 @@ const onTableSelectChange = () => { selectedRowsCount === 0 ? $elem.hide() : $elem.show(); }; -(table as any).dataTable - .on("select", onTableSelectChange) - .on("deselect", onTableSelectChange) - .on("draw", onTableSelectChange); - $("#selectAllBox").on("change", function() { + const dt: Api = (table as any).dataTable; (this as HTMLInputElement).checked - ? (table as any).dataTable.rows().select() - : (table as any).dataTable.rows().deselect(); + ? dt.rows().select() + : dt.rows().deselect(); }); $("#deleteRowsBtn").on("click", async () => { @@ -244,20 +244,7 @@ $("#deleteRowsBtn").on("click", async () => { // #endregion -// #region Page Size Select - -(window as any).$hsSelectCollection = []; -(window as any)["FloatingUIDOM"] = { - computePosition: computePosition, - autoUpdate: autoUpdate, - offset: offset -}; - -// Close on click. -window.addEventListener('click', (evt) => { - const evtTarget = evt.target; - HSSelect.closeCurrentlyOpened(evtTarget as HTMLElement); -}); +// #region Table Paging Select const pageSelectOptions: ISelectOptions = { toggleTag: '', @@ -270,35 +257,52 @@ const pageSelectOptions: ISelectOptions = {
`, toggleClasses: "cj-table-paging-select-toggle", optionClasses: "cj-table-paging-select-option", - dropdownClasses: `cj-table-paging-select-dropdown`, + dropdownClasses: "cj-table-paging-select-dropdown", dropdownSpace: 10, dropdownScope: "parent", dropdownPlacement: "top", dropdownVerticalFixedPlacement: null }; -const pageSizeSelect: HSSelect = new HSSelect( - $("#selectPageSize-js").get(0) as HTMLElement, - pageSelectOptions -); - -// #endregion +window.addEventListener("preline:ready", () => { + const selectEl = $("#selectPageSize-js").get(0); + if (!HSSelect.getInstance(selectEl, true)) { + new HSSelect(selectEl, pageSelectOptions); + } +}); // #region Edit Modal -(window as any).$hsOverlayCollection = []; +const closeEditModal = () => { editModal.close() }; -const editModalOptions: IOverlayOptions = {}; +const openEditModal = async (id: number | undefined) => { + $("#editForm").removeClass("submitted"); + editModal.open(); -const editModal: HSOverlay = new HSOverlay( - $("#editModal").get(0) as HTMLElement, - editModalOptions -); + id === undefined + ? clearEditModalData() + : loadEditModalData(id); +}; $(document).on("click", ".open-edit-modal-js", async event => { await openEditModal($(event.target).data("id")); }); +const editModalOptions: IOverlayOptions = {}; + +let editModal: HSOverlay; + +window.addEventListener("preline:ready", () => { + const modalEl = $("#editModal").get(0); + if (!HSOverlay.getInstance(modalEl, true)) { + editModal = new HSOverlay(modalEl, editModalOptions); + } +}); + +// #endregion + +// #region + const clearEditModalData = () => { $(editModal.el).removeData("id"); @@ -323,23 +327,45 @@ const loadEditModalData = async (id: number) => { $("#formInsensitive").prop("checked", filter.is_insensitive); $("#formWhitelist").prop("checked", filter.is_whitelist); - // BUG: - // Breaks the appearance & functionality of the select algorithmSelect.setValue(filter.matching_algorithm); -} - -const openEditModal = async (id: number | undefined) => { - $("#editForm").removeClass("submitted"); - editModal.open(); - - id === undefined - ? clearEditModalData() - : loadEditModalData(id); }; -const closeEditModal = () => { - editModal.close(); -}; +$("#editForm").on("submit", async event => { + event.preventDefault(); + + const form = $(event.target).get(0) as HTMLFormElement; + $(form).addClass("submitted"); + + const validity = form.checkValidity(); + if (!validity) { + console.debug(`Submit form invalid: ${validity}`); + return; + }; + + let method = "post"; + const data = $(event.target).serializeArray(); + + // If 'id' has a value, we are patching an existing entry + const id: number | undefined = $(editModal.el).data("id"); + if (id !== undefined) { + data.push({ name: "id", value: `${id}` }); + method = "patch"; + } + + await $.ajax({ + url: `/guild/${guildId}/filters/api`, + dataType: "json", + method: method, + data: data, + success: () => { + (table as any).dataTable.draw(); + closeEditModal(); + }, + error: error => { + alert(JSON.stringify(error, null, 4)); + } + }); +}); const algorithmSelectOptions: ISelectOptions = { toggleTag: '', @@ -360,52 +386,200 @@ const algorithmSelectOptions: ISelectOptions = { dropdownVerticalFixedPlacement: null }; -const algorithmSelect = new HSSelect( - $("#formAlgorithm").get(0), - algorithmSelectOptions -); +let algorithmSelect: HSSelect; -// Add options to algorithm select -Object.entries(matchingAlgorithms).forEach(([key, description]) => { - algorithmSelect.addOption({ - title: description, - val: key - } as ISingleOption) -}) +window.addEventListener("preline:ready", () => { + const algorithmEl = $("#formAlgorithm").get(0) -$("#editForm").on("submit", async event => { - event.preventDefault(); + if (HSSelect.getInstance(algorithmEl, true)) return; - const form = $(event.target).get(0) as HTMLFormElement; - $(form).addClass("submitted"); + algorithmSelect = new HSSelect(algorithmEl, algorithmSelectOptions); - if (!form.checkValidity()) return; - - let method = "post"; - const data = $(event.target).serializeArray(); - const id: number | undefined = $(editModal.el).data("id"); - - if (id !== undefined) { - data.push({ - name: "id", - value: `${id}` - }) - method = "patch"; - } - - await $.ajax({ - url: `/guild/${guildId}/filters/api`, - dataType: "json", - method: method, - data: data, - success: () => { - (table as any).dataTable.draw(); - closeEditModal(); - }, - error: error => { - alert(JSON.stringify(error, null, 4)); - } + Object.entries(matchingAlgorithms).forEach(([key, description]) => { + algorithmSelect.addOption({ + title: description, + val: key + }); }); }); -// #endregion \ No newline at end of file +// #endregion + + + +// import $ from "jquery"; +// import "datatables.net-select-dt"; +// import HSDropdown from "@preline/dropdown"; +// import HSOverlay, { IOverlayOptions } from "@preline/overlay"; +// import HSSelect, { ISelectOptions, ISingleOption } from "@preline/select"; +// import HSDataTable, { IDataTableOptions } from "@preline/datatable"; +// import DataTable, { Api, ConfigColumnDefs, AjaxSettings } from "datatables.net-dt"; +// import { autoUpdate, computePosition, offset } from "@floating-ui/dom"; +// import { formatTimestamp } from "../main"; +// import prisma from "../../../../../generated/prisma"; + +// // #region Page Size Select + +// (window as any).$hsSelectCollection = []; +// (window as any)["FloatingUIDOM"] = { +// computePosition: computePosition, +// autoUpdate: autoUpdate, +// offset: offset +// }; + +// // Close on click. +// window.addEventListener('click', (evt) => { +// const evtTarget = evt.target; +// HSSelect.closeCurrentlyOpened(evtTarget as HTMLElement); +// }); + +// const pageSelectOptions: ISelectOptions = { +// toggleTag: '', +// optionTemplate: ` +//
+// +// +//
`, +// toggleClasses: "cj-table-paging-select-toggle", +// optionClasses: "cj-table-paging-select-option", +// dropdownClasses: `cj-table-paging-select-dropdown`, +// dropdownSpace: 10, +// dropdownScope: "parent", +// dropdownPlacement: "top", +// dropdownVerticalFixedPlacement: null +// }; + +// const pageSizeSelect: HSSelect = new HSSelect( +// $("#selectPageSize-js").get(0) as HTMLElement, +// pageSelectOptions +// ); + +// // #endregion + +// // #region Edit Modal + +// (window as any).$hsOverlayCollection = []; + +// const editModalOptions: IOverlayOptions = {}; + +// const editModal: HSOverlay = new HSOverlay( +// $("#editModal").get(0) as HTMLElement, +// editModalOptions +// ); + +// $(document).on("click", ".open-edit-modal-js", async event => { +// await openEditModal($(event.target).data("id")); +// }); + +// const clearEditModalData = () => { +// $(editModal.el).removeData("id"); + +// $("#formName").val(""); +// $("#formValue").val(""); +// $("#formInsensitive").prop("checked", false); +// $("#formWhitelist").prop("checked", false); + +// algorithmSelect.setValue(""); +// }; + +// const loadEditModalData = async (id: number) => { +// const filter: prisma.Filter = await $.ajax({ +// url: `/guild/${guildId}/filters/api?id=${id}`, +// method: "get" +// }); + +// $(editModal.el).data("id", filter.id); + +// $("#formName").val(filter.name); +// $("#formValue").val(filter.value); +// $("#formInsensitive").prop("checked", filter.is_insensitive); +// $("#formWhitelist").prop("checked", filter.is_whitelist); + +// // BUG: +// // Breaks the appearance & functionality of the select +// algorithmSelect.setValue(filter.matching_algorithm); +// } + +// const openEditModal = async (id: number | undefined) => { +// $("#editForm").removeClass("submitted"); +// editModal.open(); + +// id === undefined +// ? clearEditModalData() +// : loadEditModalData(id); +// }; + +// const closeEditModal = () => { +// editModal.close(); +// }; + +// const algorithmSelectOptions: ISelectOptions = { +// toggleTag: '', +// optionTemplate: ` +//
+// +// +//
`, +// toggleClasses: "cj-select-toggle select-input", +// optionClasses: "cj-select-option", +// dropdownClasses: "cj-select-dropdown", +// wrapperClasses: "peer", +// dropdownSpace: 10, +// dropdownScope: "parent", +// dropdownPlacement: "top", +// dropdownVerticalFixedPlacement: null +// }; + +// const algorithmSelect = new HSSelect( +// $("#formAlgorithm").get(0), +// algorithmSelectOptions +// ); + +// // Add options to algorithm select +// Object.entries(matchingAlgorithms).forEach(([key, description]) => { +// algorithmSelect.addOption({ +// title: description, +// val: key +// } as ISingleOption) +// }) + +// $("#editForm").on("submit", async event => { +// event.preventDefault(); + +// const form = $(event.target).get(0) as HTMLFormElement; +// $(form).addClass("submitted"); + +// if (!form.checkValidity()) return; + +// let method = "post"; +// const data = $(event.target).serializeArray(); +// const id: number | undefined = $(editModal.el).data("id"); + +// if (id !== undefined) { +// data.push({ +// name: "id", +// value: `${id}` +// }) +// method = "patch"; +// } + +// await $.ajax({ +// url: `/guild/${guildId}/filters/api`, +// dataType: "json", +// method: method, +// data: data, +// success: () => { +// (table as any).dataTable.draw(); +// closeEditModal(); +// }, +// error: error => { +// alert(JSON.stringify(error, null, 4)); +// } +// }); +// }); + +// // #endregion \ No newline at end of file diff --git a/src/client/views/guild/filters.ejs b/src/client/views/guild/filters.ejs index d01e81c..094f919 100644 --- a/src/client/views/guild/filters.ejs +++ b/src/client/views/guild/filters.ejs @@ -142,7 +142,7 @@
-