605 lines
60 KiB
JavaScript
605 lines
60 KiB
JavaScript
|
|
var __defProp = Object.defineProperty;
|
||
|
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||
|
|
|
||
|
|
// wwwroot/ts/modules/sidebar.ts
|
||
|
|
var _SidebarController = class _SidebarController {
|
||
|
|
constructor() {
|
||
|
|
this.menuToggle = null;
|
||
|
|
this.appLayout = null;
|
||
|
|
this.menuTooltip = null;
|
||
|
|
this.menuToggle = document.getElementById("menuToggle");
|
||
|
|
this.appLayout = document.querySelector("swp-app-layout");
|
||
|
|
this.menuTooltip = document.getElementById("menuTooltip");
|
||
|
|
this.setupListeners();
|
||
|
|
this.setupTooltips();
|
||
|
|
this.restoreState();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Check if sidebar is collapsed
|
||
|
|
*/
|
||
|
|
get isCollapsed() {
|
||
|
|
return this.appLayout?.classList.contains("menu-collapsed") ?? false;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Toggle sidebar collapsed state
|
||
|
|
*/
|
||
|
|
toggle() {
|
||
|
|
if (!this.appLayout)
|
||
|
|
return;
|
||
|
|
this.appLayout.classList.toggle("menu-collapsed");
|
||
|
|
localStorage.setItem("sidebar-collapsed", String(this.isCollapsed));
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Collapse the sidebar
|
||
|
|
*/
|
||
|
|
collapse() {
|
||
|
|
this.appLayout?.classList.add("menu-collapsed");
|
||
|
|
localStorage.setItem("sidebar-collapsed", "true");
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Expand the sidebar
|
||
|
|
*/
|
||
|
|
expand() {
|
||
|
|
this.appLayout?.classList.remove("menu-collapsed");
|
||
|
|
localStorage.setItem("sidebar-collapsed", "false");
|
||
|
|
}
|
||
|
|
setupListeners() {
|
||
|
|
this.menuToggle?.addEventListener("click", () => this.toggle());
|
||
|
|
}
|
||
|
|
setupTooltips() {
|
||
|
|
if (!this.menuTooltip)
|
||
|
|
return;
|
||
|
|
const menuItems = document.querySelectorAll("swp-side-menu-item[data-tooltip]");
|
||
|
|
menuItems.forEach((item) => {
|
||
|
|
item.addEventListener("mouseenter", () => this.showTooltip(item));
|
||
|
|
item.addEventListener("mouseleave", () => this.hideTooltip());
|
||
|
|
});
|
||
|
|
}
|
||
|
|
showTooltip(item) {
|
||
|
|
if (!this.isCollapsed || !this.menuTooltip)
|
||
|
|
return;
|
||
|
|
const rect = item.getBoundingClientRect();
|
||
|
|
const tooltipText = item.dataset.tooltip;
|
||
|
|
if (!tooltipText)
|
||
|
|
return;
|
||
|
|
this.menuTooltip.textContent = tooltipText;
|
||
|
|
this.menuTooltip.style.left = `${rect.right + 8}px`;
|
||
|
|
this.menuTooltip.style.top = `${rect.top + rect.height / 2}px`;
|
||
|
|
this.menuTooltip.style.transform = "translateY(-50%)";
|
||
|
|
this.menuTooltip.showPopover();
|
||
|
|
}
|
||
|
|
hideTooltip() {
|
||
|
|
this.menuTooltip?.hidePopover();
|
||
|
|
}
|
||
|
|
restoreState() {
|
||
|
|
if (!this.appLayout)
|
||
|
|
return;
|
||
|
|
if (localStorage.getItem("sidebar-collapsed") === "true") {
|
||
|
|
this.appLayout.classList.add("menu-collapsed");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
__name(_SidebarController, "SidebarController");
|
||
|
|
var SidebarController = _SidebarController;
|
||
|
|
|
||
|
|
// wwwroot/ts/modules/drawers.ts
|
||
|
|
var _DrawerController = class _DrawerController {
|
||
|
|
constructor() {
|
||
|
|
this.profileDrawer = null;
|
||
|
|
this.notificationDrawer = null;
|
||
|
|
this.todoDrawer = null;
|
||
|
|
this.newTodoDrawer = null;
|
||
|
|
this.overlay = null;
|
||
|
|
this.activeDrawer = null;
|
||
|
|
this.profileDrawer = document.getElementById("profileDrawer");
|
||
|
|
this.notificationDrawer = document.getElementById("notificationDrawer");
|
||
|
|
this.todoDrawer = document.getElementById("todoDrawer");
|
||
|
|
this.newTodoDrawer = document.getElementById("newTodoDrawer");
|
||
|
|
this.overlay = document.getElementById("drawerOverlay");
|
||
|
|
this.setupListeners();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get currently active drawer name
|
||
|
|
*/
|
||
|
|
get active() {
|
||
|
|
return this.activeDrawer;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Open a drawer by name
|
||
|
|
*/
|
||
|
|
open(name) {
|
||
|
|
this.closeAll();
|
||
|
|
const drawer = this.getDrawer(name);
|
||
|
|
if (drawer && this.overlay) {
|
||
|
|
drawer.classList.add("active");
|
||
|
|
this.overlay.classList.add("active");
|
||
|
|
document.body.style.overflow = "hidden";
|
||
|
|
this.activeDrawer = name;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Close a specific drawer
|
||
|
|
*/
|
||
|
|
close(name) {
|
||
|
|
const drawer = this.getDrawer(name);
|
||
|
|
drawer?.classList.remove("active");
|
||
|
|
if (this.overlay && !document.querySelector('.active[class*="drawer"]')) {
|
||
|
|
this.overlay.classList.remove("active");
|
||
|
|
document.body.style.overflow = "";
|
||
|
|
}
|
||
|
|
if (this.activeDrawer === name) {
|
||
|
|
this.activeDrawer = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Close all drawers
|
||
|
|
*/
|
||
|
|
closeAll() {
|
||
|
|
[this.profileDrawer, this.notificationDrawer, this.todoDrawer, this.newTodoDrawer].forEach((drawer) => drawer?.classList.remove("active"));
|
||
|
|
this.overlay?.classList.remove("active");
|
||
|
|
document.body.style.overflow = "";
|
||
|
|
this.activeDrawer = null;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Open profile drawer
|
||
|
|
*/
|
||
|
|
openProfile() {
|
||
|
|
this.open("profile");
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Open notification drawer
|
||
|
|
*/
|
||
|
|
openNotification() {
|
||
|
|
this.open("notification");
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Open todo drawer (slides on top of profile)
|
||
|
|
*/
|
||
|
|
openTodo() {
|
||
|
|
this.todoDrawer?.classList.add("active");
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Close todo drawer
|
||
|
|
*/
|
||
|
|
closeTodo() {
|
||
|
|
this.todoDrawer?.classList.remove("active");
|
||
|
|
this.closeNewTodo();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Open new todo drawer
|
||
|
|
*/
|
||
|
|
openNewTodo() {
|
||
|
|
this.newTodoDrawer?.classList.add("active");
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Close new todo drawer
|
||
|
|
*/
|
||
|
|
closeNewTodo() {
|
||
|
|
this.newTodoDrawer?.classList.remove("active");
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Mark all notifications as read
|
||
|
|
*/
|
||
|
|
markAllNotificationsRead() {
|
||
|
|
if (!this.notificationDrawer)
|
||
|
|
return;
|
||
|
|
const unreadItems = this.notificationDrawer.querySelectorAll(
|
||
|
|
'swp-notification-item[data-unread="true"]'
|
||
|
|
);
|
||
|
|
unreadItems.forEach((item) => item.removeAttribute("data-unread"));
|
||
|
|
const badge = document.querySelector("swp-notification-badge");
|
||
|
|
if (badge) {
|
||
|
|
badge.style.display = "none";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
getDrawer(name) {
|
||
|
|
switch (name) {
|
||
|
|
case "profile":
|
||
|
|
return this.profileDrawer;
|
||
|
|
case "notification":
|
||
|
|
return this.notificationDrawer;
|
||
|
|
case "todo":
|
||
|
|
return this.todoDrawer;
|
||
|
|
case "newTodo":
|
||
|
|
return this.newTodoDrawer;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
setupListeners() {
|
||
|
|
document.getElementById("profileTrigger")?.addEventListener("click", () => this.openProfile());
|
||
|
|
document.getElementById("drawerClose")?.addEventListener("click", () => this.close("profile"));
|
||
|
|
document.getElementById("notificationsBtn")?.addEventListener("click", () => this.openNotification());
|
||
|
|
document.getElementById("notificationDrawerClose")?.addEventListener("click", () => this.close("notification"));
|
||
|
|
document.getElementById("markAllRead")?.addEventListener("click", () => this.markAllNotificationsRead());
|
||
|
|
document.getElementById("openTodoDrawer")?.addEventListener("click", () => this.openTodo());
|
||
|
|
document.getElementById("todoDrawerBack")?.addEventListener("click", () => this.closeTodo());
|
||
|
|
document.getElementById("addTodoBtn")?.addEventListener("click", () => this.openNewTodo());
|
||
|
|
document.getElementById("newTodoDrawerBack")?.addEventListener("click", () => this.closeNewTodo());
|
||
|
|
document.getElementById("cancelNewTodo")?.addEventListener("click", () => this.closeNewTodo());
|
||
|
|
document.getElementById("saveNewTodo")?.addEventListener("click", () => this.closeNewTodo());
|
||
|
|
this.overlay?.addEventListener("click", () => this.closeAll());
|
||
|
|
document.addEventListener("keydown", (e) => {
|
||
|
|
if (e.key === "Escape")
|
||
|
|
this.closeAll();
|
||
|
|
});
|
||
|
|
this.todoDrawer?.addEventListener("click", (e) => this.handleTodoClick(e));
|
||
|
|
document.addEventListener("click", (e) => this.handleVisibilityClick(e));
|
||
|
|
}
|
||
|
|
handleTodoClick(e) {
|
||
|
|
const target = e.target;
|
||
|
|
const todoItem = target.closest("swp-todo-item");
|
||
|
|
const checkbox = target.closest("swp-todo-checkbox");
|
||
|
|
if (checkbox && todoItem) {
|
||
|
|
const isCompleted = todoItem.dataset.completed === "true";
|
||
|
|
if (isCompleted) {
|
||
|
|
todoItem.removeAttribute("data-completed");
|
||
|
|
} else {
|
||
|
|
todoItem.dataset.completed = "true";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const sectionHeader = target.closest("swp-todo-section-header");
|
||
|
|
if (sectionHeader) {
|
||
|
|
const section = sectionHeader.closest("swp-todo-section");
|
||
|
|
section?.classList.toggle("collapsed");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
handleVisibilityClick(e) {
|
||
|
|
const target = e.target;
|
||
|
|
const option = target.closest("swp-visibility-option");
|
||
|
|
if (option) {
|
||
|
|
document.querySelectorAll("swp-visibility-option").forEach((o) => o.classList.remove("active"));
|
||
|
|
option.classList.add("active");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
__name(_DrawerController, "DrawerController");
|
||
|
|
var DrawerController = _DrawerController;
|
||
|
|
|
||
|
|
// wwwroot/ts/modules/theme.ts
|
||
|
|
var _ThemeController = class _ThemeController {
|
||
|
|
constructor() {
|
||
|
|
this.root = document.documentElement;
|
||
|
|
this.themeOptions = document.querySelectorAll("swp-theme-option");
|
||
|
|
this.applyTheme(this.current);
|
||
|
|
this.updateUI();
|
||
|
|
this.setupListeners();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get the current theme setting
|
||
|
|
*/
|
||
|
|
get current() {
|
||
|
|
const stored = localStorage.getItem(_ThemeController.STORAGE_KEY);
|
||
|
|
if (stored === "dark" || stored === "light" || stored === "system") {
|
||
|
|
return stored;
|
||
|
|
}
|
||
|
|
return "system";
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Check if dark mode is currently active
|
||
|
|
*/
|
||
|
|
get isDark() {
|
||
|
|
return this.root.classList.contains(_ThemeController.DARK_CLASS) || this.systemPrefersDark && !this.root.classList.contains(_ThemeController.LIGHT_CLASS);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Check if system prefers dark mode
|
||
|
|
*/
|
||
|
|
get systemPrefersDark() {
|
||
|
|
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Set theme and persist preference
|
||
|
|
*/
|
||
|
|
set(theme) {
|
||
|
|
localStorage.setItem(_ThemeController.STORAGE_KEY, theme);
|
||
|
|
this.applyTheme(theme);
|
||
|
|
this.updateUI();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Toggle between light and dark themes
|
||
|
|
*/
|
||
|
|
toggle() {
|
||
|
|
this.set(this.isDark ? "light" : "dark");
|
||
|
|
}
|
||
|
|
applyTheme(theme) {
|
||
|
|
this.root.classList.remove(_ThemeController.DARK_CLASS, _ThemeController.LIGHT_CLASS);
|
||
|
|
if (theme === "dark") {
|
||
|
|
this.root.classList.add(_ThemeController.DARK_CLASS);
|
||
|
|
} else if (theme === "light") {
|
||
|
|
this.root.classList.add(_ThemeController.LIGHT_CLASS);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
updateUI() {
|
||
|
|
if (!this.themeOptions)
|
||
|
|
return;
|
||
|
|
const darkActive = this.isDark;
|
||
|
|
this.themeOptions.forEach((option) => {
|
||
|
|
const theme = option.dataset.theme;
|
||
|
|
const isActive = theme === "dark" && darkActive || theme === "light" && !darkActive;
|
||
|
|
option.classList.toggle("active", isActive);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
setupListeners() {
|
||
|
|
this.themeOptions.forEach((option) => {
|
||
|
|
option.addEventListener("click", (e) => this.handleOptionClick(e));
|
||
|
|
});
|
||
|
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => this.handleSystemChange());
|
||
|
|
}
|
||
|
|
handleOptionClick(e) {
|
||
|
|
const target = e.target;
|
||
|
|
const option = target.closest("swp-theme-option");
|
||
|
|
if (option) {
|
||
|
|
const theme = option.dataset.theme;
|
||
|
|
if (theme) {
|
||
|
|
this.set(theme);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
handleSystemChange() {
|
||
|
|
if (this.current === "system") {
|
||
|
|
this.updateUI();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
__name(_ThemeController, "ThemeController");
|
||
|
|
_ThemeController.STORAGE_KEY = "theme-preference";
|
||
|
|
_ThemeController.DARK_CLASS = "dark-mode";
|
||
|
|
_ThemeController.LIGHT_CLASS = "light-mode";
|
||
|
|
var ThemeController = _ThemeController;
|
||
|
|
|
||
|
|
// wwwroot/ts/modules/search.ts
|
||
|
|
var _SearchController = class _SearchController {
|
||
|
|
constructor() {
|
||
|
|
this.input = null;
|
||
|
|
this.container = null;
|
||
|
|
this.input = document.getElementById("globalSearch");
|
||
|
|
this.container = document.querySelector("swp-topbar-search");
|
||
|
|
this.setupListeners();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get current search value
|
||
|
|
*/
|
||
|
|
get value() {
|
||
|
|
return this.input?.value ?? "";
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Set search value
|
||
|
|
*/
|
||
|
|
set value(val) {
|
||
|
|
if (this.input) {
|
||
|
|
this.input.value = val;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Focus the search input
|
||
|
|
*/
|
||
|
|
focus() {
|
||
|
|
this.input?.focus();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Blur the search input
|
||
|
|
*/
|
||
|
|
blur() {
|
||
|
|
this.input?.blur();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Clear the search input
|
||
|
|
*/
|
||
|
|
clear() {
|
||
|
|
this.value = "";
|
||
|
|
}
|
||
|
|
setupListeners() {
|
||
|
|
document.addEventListener("keydown", (e) => this.handleKeyboard(e));
|
||
|
|
if (this.input) {
|
||
|
|
this.input.addEventListener("input", (e) => this.handleInput(e));
|
||
|
|
const form = this.input.closest("form");
|
||
|
|
form?.addEventListener("submit", (e) => this.handleSubmit(e));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
handleKeyboard(e) {
|
||
|
|
if ((e.metaKey || e.ctrlKey) && e.key === "k") {
|
||
|
|
e.preventDefault();
|
||
|
|
this.focus();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (e.key === "Escape" && document.activeElement === this.input) {
|
||
|
|
this.blur();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
handleInput(e) {
|
||
|
|
const target = e.target;
|
||
|
|
const query = target.value.trim();
|
||
|
|
document.dispatchEvent(new CustomEvent("app:search", {
|
||
|
|
detail: { query },
|
||
|
|
bubbles: true
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
handleSubmit(e) {
|
||
|
|
e.preventDefault();
|
||
|
|
const query = this.value.trim();
|
||
|
|
if (!query)
|
||
|
|
return;
|
||
|
|
document.dispatchEvent(new CustomEvent("app:search-submit", {
|
||
|
|
detail: { query },
|
||
|
|
bubbles: true
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
};
|
||
|
|
__name(_SearchController, "SearchController");
|
||
|
|
var SearchController = _SearchController;
|
||
|
|
|
||
|
|
// wwwroot/ts/modules/lockscreen.ts
|
||
|
|
var _LockScreenController = class _LockScreenController {
|
||
|
|
constructor(drawers) {
|
||
|
|
// Demo PIN
|
||
|
|
this.lockScreen = null;
|
||
|
|
this.pinInput = null;
|
||
|
|
this.pinKeypad = null;
|
||
|
|
this.lockTimeEl = null;
|
||
|
|
this.pinDigits = null;
|
||
|
|
this.currentPin = "";
|
||
|
|
this.drawers = null;
|
||
|
|
this.drawers = drawers ?? null;
|
||
|
|
this.lockScreen = document.getElementById("lockScreen");
|
||
|
|
this.pinInput = document.getElementById("pinInput");
|
||
|
|
this.pinKeypad = document.getElementById("pinKeypad");
|
||
|
|
this.lockTimeEl = document.getElementById("lockTime");
|
||
|
|
this.pinDigits = this.pinInput?.querySelectorAll("swp-pin-digit") ?? null;
|
||
|
|
this.setupListeners();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Check if lock screen is active
|
||
|
|
*/
|
||
|
|
get isActive() {
|
||
|
|
return this.lockScreen?.classList.contains("active") ?? false;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Show the lock screen
|
||
|
|
*/
|
||
|
|
show() {
|
||
|
|
this.drawers?.closeAll();
|
||
|
|
if (this.lockScreen) {
|
||
|
|
this.lockScreen.classList.add("active");
|
||
|
|
document.body.style.overflow = "hidden";
|
||
|
|
}
|
||
|
|
this.currentPin = "";
|
||
|
|
this.updateDisplay();
|
||
|
|
if (this.lockTimeEl) {
|
||
|
|
this.lockTimeEl.textContent = `L\xE5st kl. ${this.formatTime()}`;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Hide the lock screen
|
||
|
|
*/
|
||
|
|
hide() {
|
||
|
|
if (this.lockScreen) {
|
||
|
|
this.lockScreen.classList.remove("active");
|
||
|
|
document.body.style.overflow = "";
|
||
|
|
}
|
||
|
|
this.currentPin = "";
|
||
|
|
this.updateDisplay();
|
||
|
|
}
|
||
|
|
formatTime() {
|
||
|
|
const now = /* @__PURE__ */ new Date();
|
||
|
|
const hours = now.getHours().toString().padStart(2, "0");
|
||
|
|
const minutes = now.getMinutes().toString().padStart(2, "0");
|
||
|
|
return `${hours}:${minutes}`;
|
||
|
|
}
|
||
|
|
updateDisplay() {
|
||
|
|
if (!this.pinDigits)
|
||
|
|
return;
|
||
|
|
this.pinDigits.forEach((digit, index) => {
|
||
|
|
digit.classList.remove("filled", "error");
|
||
|
|
if (index < this.currentPin.length) {
|
||
|
|
digit.textContent = "\u2022";
|
||
|
|
digit.classList.add("filled");
|
||
|
|
} else {
|
||
|
|
digit.textContent = "";
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
showError() {
|
||
|
|
if (!this.pinDigits)
|
||
|
|
return;
|
||
|
|
this.pinDigits.forEach((digit) => digit.classList.add("error"));
|
||
|
|
this.pinInput?.classList.add("shake");
|
||
|
|
setTimeout(() => {
|
||
|
|
this.currentPin = "";
|
||
|
|
this.updateDisplay();
|
||
|
|
this.pinInput?.classList.remove("shake");
|
||
|
|
}, 500);
|
||
|
|
}
|
||
|
|
verify() {
|
||
|
|
if (this.currentPin === _LockScreenController.CORRECT_PIN) {
|
||
|
|
this.hide();
|
||
|
|
} else {
|
||
|
|
this.showError();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
addDigit(digit) {
|
||
|
|
if (this.currentPin.length >= 4)
|
||
|
|
return;
|
||
|
|
this.currentPin += digit;
|
||
|
|
this.updateDisplay();
|
||
|
|
if (this.currentPin.length === 4) {
|
||
|
|
setTimeout(() => this.verify(), 200);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
removeDigit() {
|
||
|
|
if (this.currentPin.length === 0)
|
||
|
|
return;
|
||
|
|
this.currentPin = this.currentPin.slice(0, -1);
|
||
|
|
this.updateDisplay();
|
||
|
|
}
|
||
|
|
clearPin() {
|
||
|
|
this.currentPin = "";
|
||
|
|
this.updateDisplay();
|
||
|
|
}
|
||
|
|
setupListeners() {
|
||
|
|
this.pinKeypad?.addEventListener("click", (e) => this.handleKeypadClick(e));
|
||
|
|
document.addEventListener("keydown", (e) => this.handleKeyboard(e));
|
||
|
|
document.querySelector("swp-side-menu-action.lock")?.addEventListener("click", () => this.show());
|
||
|
|
}
|
||
|
|
handleKeypadClick(e) {
|
||
|
|
const target = e.target;
|
||
|
|
const key = target.closest("swp-pin-key");
|
||
|
|
if (!key)
|
||
|
|
return;
|
||
|
|
const digit = key.dataset.digit;
|
||
|
|
const action = key.dataset.action;
|
||
|
|
if (digit) {
|
||
|
|
this.addDigit(digit);
|
||
|
|
} else if (action === "backspace") {
|
||
|
|
this.removeDigit();
|
||
|
|
} else if (action === "clear") {
|
||
|
|
this.clearPin();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
handleKeyboard(e) {
|
||
|
|
if (!this.isActive)
|
||
|
|
return;
|
||
|
|
e.preventDefault();
|
||
|
|
if (e.key >= "0" && e.key <= "9") {
|
||
|
|
this.addDigit(e.key);
|
||
|
|
} else if (e.key === "Backspace") {
|
||
|
|
this.removeDigit();
|
||
|
|
} else if (e.key === "Escape") {
|
||
|
|
this.clearPin();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
__name(_LockScreenController, "LockScreenController");
|
||
|
|
_LockScreenController.CORRECT_PIN = "1234";
|
||
|
|
var LockScreenController = _LockScreenController;
|
||
|
|
|
||
|
|
// wwwroot/ts/app.ts
|
||
|
|
var _App = class _App {
|
||
|
|
constructor() {
|
||
|
|
this.sidebar = new SidebarController();
|
||
|
|
this.drawers = new DrawerController();
|
||
|
|
this.theme = new ThemeController();
|
||
|
|
this.search = new SearchController();
|
||
|
|
this.lockScreen = new LockScreenController(this.drawers);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
__name(_App, "App");
|
||
|
|
var App = _App;
|
||
|
|
var app;
|
||
|
|
function init() {
|
||
|
|
app = new App();
|
||
|
|
if (typeof window !== "undefined") {
|
||
|
|
window.app = app;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
__name(init, "init");
|
||
|
|
if (document.readyState === "loading") {
|
||
|
|
document.addEventListener("DOMContentLoaded", init);
|
||
|
|
} else {
|
||
|
|
init();
|
||
|
|
}
|
||
|
|
var app_default = App;
|
||
|
|
export {
|
||
|
|
App,
|
||
|
|
app,
|
||
|
|
app_default as default
|
||
|
|
};
|
||
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vdHMvbW9kdWxlcy9zaWRlYmFyLnRzIiwgIi4uL3RzL21vZHVsZXMvZHJhd2Vycy50cyIsICIuLi90cy9tb2R1bGVzL3RoZW1lLnRzIiwgIi4uL3RzL21vZHVsZXMvc2VhcmNoLnRzIiwgIi4uL3RzL21vZHVsZXMvbG9ja3NjcmVlbi50cyIsICIuLi90cy9hcHAudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogU2lkZWJhciBDb250cm9sbGVyXG4gKlxuICogSGFuZGxlcyBzaWRlYmFyIGNvbGxhcHNlL2V4cGFuZCBhbmQgdG9vbHRpcCBmdW5jdGlvbmFsaXR5XG4gKi9cblxuZXhwb3J0IGNsYXNzIFNpZGViYXJDb250cm9sbGVyIHtcbiAgcHJpdmF0ZSBtZW51VG9nZ2xlOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGFwcExheW91dDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBtZW51VG9vbHRpcDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLm1lbnVUb2dnbGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWVudVRvZ2dsZScpO1xuICAgIHRoaXMuYXBwTGF5b3V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLWFwcC1sYXlvdXQnKTtcbiAgICB0aGlzLm1lbnVUb29sdGlwID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21lbnVUb29sdGlwJyk7XG5cbiAgICB0aGlzLnNldHVwTGlzdGVuZXJzKCk7XG4gICAgdGhpcy5zZXR1cFRvb2x0aXBzKCk7XG4gICAgdGhpcy5yZXN0b3JlU3RhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBzaWRlYmFyIGlzIGNvbGxhcHNlZFxuICAgKi9cbiAgZ2V0IGlzQ29sbGFwc2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmFwcExheW91dD8uY2xhc3NMaXN0LmNvbnRhaW5zKCdtZW51LWNvbGxhcHNlZCcpID8/IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSBzaWRlYmFyIGNvbGxhcHNlZCBzdGF0ZVxuICAgKi9cbiAgdG9nZ2xlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5hcHBMYXlvdXQpIHJldHVybjtcblxuICAgIHRoaXMuYXBwTGF5b3V0LmNsYXNzTGlzdC50b2dnbGUoJ21lbnUtY29sbGFwc2VkJyk7XG4gICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ3NpZGViYXItY29sbGFwc2VkJywgU3RyaW5nKHRoaXMuaXNDb2xsYXBzZWQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb2xsYXBzZSB0aGUgc2lkZWJhclxuICAgKi9cbiAgY29sbGFwc2UoKTogdm9pZCB7XG4gICAgdGhpcy5hcHBMYXlvdXQ/LmNsYXNzTGlzdC5hZGQoJ21lbnUtY29sbGFwc2VkJyk7XG4gICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ3NpZGViYXItY29sbGFwc2VkJywgJ3RydWUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBhbmQgdGhlIHNpZGViYXJcbiAgICovXG4gIGV4cGFuZCgpOiB2b2lkIHtcbiAgICB0aGlzLmFwcExheW91dD8uY2xhc3NMaXN0LnJlbW92ZSgnbWVudS1jb2xsYXBzZWQnKTtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnc2lkZWJhci1jb2xsYXBzZWQnLCAnZmFsc2UnKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBMaXN0ZW5lcnMoKTogdm9pZCB7XG4gICAgdGhpcy5tZW51VG9nZ2xlPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMudG9nZ2xlKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cFRvb2x0aXBzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5tZW51VG9vbHRpcCkgcmV0dXJuO1xuXG4gICAgY29uc3QgbWVudUl0ZW1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oJ3N3cC1zaWRlLW1lbnUtaXRlbVtkYXRhLXRvb2x0aXBdJyk7XG5cbiAgICBtZW51SXRlbXMuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGl0ZW0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsICgpID0+IHRoaXMuc2hvd1Rvb2x0aXAoaXRlbSkpO1xuICAgICAgaXRlbS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgKCkgPT4gdGhpcy5oaWRlVG9vbHRpcCgpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1Rvb2x0aXAoaXRlbTogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNDb2xsYXBzZWQgfHwgIXRoaXMubWVudVRvb2x0aXApIHJldHVybjtcblxuICAgIGNvbnN0IHJlY3QgPSBpdGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHRvb2x0aXBUZXh0ID0gaXRlbS5kYXRhc2V0LnRvb2x0aXA7XG5cbiAgICBpZiAoIXRvb2x0aXBUZXh0KSByZXR1cm47XG5cbiAgICB0aGlzLm1lbnVUb29sdGlwLnRleHRDb250ZW50ID0gdG9vbHRpcFRleHQ7XG4gICAgdGhpcy5tZW51VG9vbHRpcC5zdHlsZS5sZWZ0ID0gYCR7cmVjdC5yaWdodCArIDh9cHhgO1xuICAgIHRoaXMubWVudVRvb2x0aXAuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyByZWN0LmhlaWdodCAvIDJ9cHhgO1xuICAgIHRoaXMubWVudVRvb2x0aXAuc3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZVkoLTUwJSknO1xuICAgIHRoaXMubWVudVRvb2x0aXAuc2hvd1BvcG92ZXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgaGlkZVRvb2x0aXAoKTogdm9pZCB7XG4gICAgdGhpcy5tZW51VG9vbHRpcD8uaGlkZVBvcG92ZXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzdG9yZVN0YXRlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5hcHBMYXlvdXQpIHJldHVybjtcblxuICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc2lkZWJhci1jb2xsYXBzZWQnKSA9PT0gJ3RydWUnKSB7XG4gICAgICB0aGlzLmFwcExheW91dC5jbGFzc0xpc3QuYWRkKCdtZW51LWNvbGxhcHNlZCcpO1xuICAgIH1cbiAgfVxufVxuIiwgIi8qKlxuICogRHJhd2VyIENvbnRyb2xsZXJcbiAqXG4gKiBIYW5kbGVzIGFsbCBkcmF3ZXIgZnVuY3Rpb25hbGl0eSBpbmNsdWRpbmcgcHJvZmlsZSwgbm90aWZpY2F0aW9ucywgYW5kIHRvZG8gZHJhd2Vyc1xuICovXG5cbmV4cG9ydCB0eXBlIERyYXdlck5hbWUgPSAncHJvZmlsZScgfCAnbm90aWZpY2F0aW9uJyB8ICd0b
|