Files
oslstats/internal/embedfs/web/js/admin.js

264 lines
8.0 KiB
JavaScript

// Admin dashboard utilities
// Format JSON for display in modals
function formatJSON(json) {
try {
const parsed = typeof json === "string" ? JSON.parse(json) : json;
return JSON.stringify(parsed, null, 2);
} catch (e) {
return json;
}
}
// Initialize flatpickr for all date inputs
function initFlatpickr() {
document.querySelectorAll(".flatpickr-date").forEach(function (input) {
if (!input._flatpickr) {
flatpickr(input, {
dateFormat: "d/m/Y",
allowInput: true,
});
}
});
}
// Submit the audit filter form with specific page/perPage/order params
function submitAuditFilter(page, perPage, order, orderBy) {
const form = document.getElementById("audit-filters-form");
if (!form) return;
// Create hidden inputs for pagination/sorting if they don't exist
let pageInput = form.querySelector('input[name="page"]');
if (!pageInput) {
pageInput = document.createElement("input");
pageInput.type = "hidden";
pageInput.name = "page";
form.appendChild(pageInput);
}
pageInput.value = page;
let perPageInput = form.querySelector('input[name="per_page"]');
if (!perPageInput) {
perPageInput = document.createElement("input");
perPageInput.type = "hidden";
perPageInput.name = "per_page";
form.appendChild(perPageInput);
}
perPageInput.value = perPage;
let orderInput = form.querySelector('input[name="order"]');
if (!orderInput) {
orderInput = document.createElement("input");
orderInput.type = "hidden";
orderInput.name = "order";
form.appendChild(orderInput);
}
orderInput.value = order;
let orderByInput = form.querySelector('input[name="order_by"]');
if (!orderByInput) {
orderByInput = document.createElement("input");
orderByInput.type = "hidden";
orderByInput.name = "order_by";
form.appendChild(orderByInput);
}
orderByInput.value = orderBy;
htmx.trigger(form, "submit");
}
// Sort by column - toggle direction if same column
function sortAuditColumn(field, currentOrder, currentOrderBy) {
const page = 1; // Reset to first page when sorting
const perPageSelect = document.getElementById("per-page-select");
const perPage = perPageSelect ? parseInt(perPageSelect.value) || 25 : 25;
let newOrder, newOrderBy;
if (currentOrderBy === field) {
// Toggle order
newOrder = currentOrder === "ASC" ? "DESC" : "ASC";
newOrderBy = field;
} else {
// New column, default to DESC
newOrder = "DESC";
newOrderBy = field;
}
submitAuditFilter(page, perPage, newOrder, newOrderBy);
}
// Clear all audit filters
function clearAuditFilters() {
const form = document.getElementById("audit-filters-form");
if (!form) return;
form.reset();
// Clear flatpickr instances
document.querySelectorAll(".flatpickr-date").forEach(function (input) {
var fp = input._flatpickr;
if (fp) fp.clear();
});
// Clear multi-select dropdowns
document.querySelectorAll(".multi-select-container").forEach(function (container) {
var hiddenInput = container.querySelector('input[type="hidden"]');
if (hiddenInput) hiddenInput.value = "";
var selectedDisplay = container.querySelector(".multi-select-selected");
if (selectedDisplay)
selectedDisplay.innerHTML = '<span class="text-subtext1">Select...</span>';
container.querySelectorAll(".multi-select-option").forEach(function (opt) {
opt.classList.remove("bg-blue", "text-mantle");
opt.classList.add("hover:bg-surface1");
});
});
// Trigger form submission with reset pagination
submitAuditFilter(1, 25, "DESC", "created_at");
}
// Toggle multi-select dropdown visibility
function toggleMultiSelect(containerId) {
var dropdown = document.getElementById(containerId + "-dropdown");
if (dropdown) {
dropdown.classList.toggle("hidden");
}
}
// Toggle multi-select option selection
function toggleMultiSelectOption(containerId, value, label) {
var container = document.getElementById(containerId);
var hiddenInput = container.querySelector('input[type="hidden"]');
var selectedDisplay = container.querySelector(".multi-select-selected");
var values = hiddenInput.value ? hiddenInput.value.split(",") : [];
var index = values.indexOf(value);
if (index > -1) {
values.splice(index, 1);
} else {
values.push(value);
}
hiddenInput.value = values.join(",");
var option = container.querySelector('[data-value="' + value + '"]');
if (option) {
if (index > -1) {
option.classList.remove("bg-blue", "text-mantle");
option.classList.add("hover:bg-surface1");
} else {
option.classList.add("bg-blue", "text-mantle");
option.classList.remove("hover:bg-surface1");
}
}
if (values.length === 0) {
selectedDisplay.innerHTML = '<span class="text-subtext1">Select...</span>';
} else if (values.length === 1) {
selectedDisplay.innerHTML = "<span>" + label + "</span>";
} else {
selectedDisplay.innerHTML = "<span>" + values.length + " selected</span>";
}
// Trigger form submission
document.getElementById("audit-filters-form").requestSubmit();
}
// Submit the users page with specific page/perPage/order params
function submitUsersPage(page, perPage, order, orderBy) {
const formData = new FormData();
formData.append("page", page);
formData.append("per_page", perPage);
formData.append("order", order);
formData.append("order_by", orderBy);
htmx.ajax("POST", "/admin/users", {
target: "#users-list-container",
swap: "outerHTML",
values: Object.fromEntries(formData),
});
}
// Sort users column - toggle direction if same column
function sortUsersColumn(field, currentOrder, currentOrderBy) {
const page = 1; // Reset to first page when sorting
const perPageSelect = document.getElementById("users-per-page-select");
const perPage = perPageSelect ? parseInt(perPageSelect.value) || 25 : 25;
let newOrder, newOrderBy;
if (currentOrderBy === field) {
// Toggle order
newOrder = currentOrder === "ASC" ? "DESC" : "ASC";
newOrderBy = field;
} else {
// New column, default to ASC
newOrder = "ASC";
newOrderBy = field;
}
submitUsersPage(page, perPage, newOrder, newOrderBy);
}
// Submit the roles page with specific page/perPage/order params
function submitRolesPage(page, perPage, order, orderBy) {
const formData = new FormData();
formData.append("page", page);
formData.append("per_page", perPage);
formData.append("order", order);
formData.append("order_by", orderBy);
htmx.ajax("POST", "/admin/roles", {
target: "#roles-list-container",
swap: "outerHTML",
values: Object.fromEntries(formData),
});
}
// Sort roles column - toggle direction if same column
function sortRolesColumn(field, currentOrder, currentOrderBy) {
const page = 1; // Reset to first page when sorting
const perPageSelect = document.getElementById("roles-per-page-select");
const perPage = perPageSelect ? parseInt(perPageSelect.value) || 25 : 25;
let newOrder, newOrderBy;
if (currentOrderBy === field) {
// Toggle order
newOrder = currentOrder === "ASC" ? "DESC" : "ASC";
newOrderBy = field;
} else {
// New column, default to ASC
newOrder = "ASC";
newOrderBy = field;
}
submitRolesPage(page, perPage, newOrder, newOrderBy);
}
// Handle HTMX navigation and initialization
// Tab navigation active state is handled by tabs.js (generic).
// This file only handles admin-specific concerns (flatpickr, multi-select).
document.addEventListener("DOMContentLoaded", function () {
// Initialize flatpickr on page load
initFlatpickr();
document.body.addEventListener("htmx:afterSwap", function (event) {
// Re-initialize flatpickr after admin content swap
if (
event.detail.target.id === "admin-content" ||
event.detail.target.id === "audit-results-container"
) {
initFlatpickr();
}
});
// Close multi-select dropdowns when clicking outside
document.addEventListener("click", function (evt) {
if (!evt.target.closest(".multi-select-container")) {
document.querySelectorAll(".multi-select-dropdown").forEach(function (d) {
d.classList.add("hidden");
});
}
});
});