manage-your-printer/static/js/core-utilities-optimized.min.js
2025-06-04 10:03:22 +02:00

1 line
8.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function(window){'use strict';const MYPCore ={version:'1.0.0',csrf:{_token:null,getToken(){if(!this._token){this._token = document.querySelector('meta[name="csrf-token"]')?.content || document.querySelector('input[name="csrf_token"]')?.value || this._getFromCookie('csrf_token')|| '';}return this._token;},_getFromCookie(name){const match = document.cookie.match(new RegExp('(^|)' + name + '=([^;]+)'));return match ? match[2]:null;},clearCache(){this._token = null;}},dom:{_cache:new Map(),get(selector,parent = document){const key = `${parent === document ? 'doc':'el'}_${selector}`;if(!this._cache.has(key)){this._cache.set(key,parent.querySelector(selector));}return this._cache.get(key);},getAll(selector,parent = document){return parent.querySelectorAll(selector);},escapeHtml(text){const div = this._escapeDiv ||(this._escapeDiv = document.createElement('div'));div.textContent = text;return div.innerHTML;},clearCache(){this._cache.clear();},create(tag,attrs ={},children = []){const el = document.createElement(tag);Object.entries(attrs).forEach(([key,value])=>{if(key === 'class'){el.className = value;}else if(key === 'style' && typeof value === 'object'){Object.assign(el.style,value);}else if(key.startsWith('data-')){el.dataset[key.slice(5)] = value;}else{el.setAttribute(key,value);}});children.forEach(child =>{if(typeof child === 'string'){el.appendChild(document.createTextNode(child));}else{el.appendChild(child);}});return el;}},notify:{_container:null,_queue:[],_activeToasts:new Map(),_toastId:0,show(message,type = 'info',duration = 5000,options ={}){if(window.dndManager?.isEnabled && !options.force){console.log(`[DND] Suppressed ${type}notification:`,message);return null;}const id = `toast-${++this._toastId}`;const toast = this._createToast(id,message,type,duration,options);this._ensureContainer();this._container.appendChild(toast);requestAnimationFrame(()=>{toast.classList.add('show');});if(duration > 0 && !options.persistent){const timeout = setTimeout(()=> this.close(id),duration);this._activeToasts.set(id,{element:toast,timeout});}return id;},_createToast(id,message,type,duration,options){const toast = MYPCore.dom.create('div',{id,class:`myp-toast myp-toast-${type}`,role:'alert','aria-live':'polite'});const icon = this._getIcon(type);const content = MYPCore.dom.create('div',{class:'toast-content'},[ MYPCore.dom.create('span',{class:'toast-icon'},[icon]),MYPCore.dom.create('span',{class:'toast-message'},[message])]);const closeBtn = MYPCore.dom.create('button',{class:'toast-close','aria-label':'Close notification',onclick:()=> this.close(id)},['×']);toast.appendChild(content);toast.appendChild(closeBtn);if(duration > 0 && !options.persistent){const progress = MYPCore.dom.create('div',{class:'toast-progress'});const bar = MYPCore.dom.create('div',{class:'toast-progress-bar',style:{animationDuration:`${duration}ms`}});progress.appendChild(bar);toast.appendChild(progress);}return toast;},_getIcon(type){const icons ={success:'✓',error:'✗',warning:'⚠',info:''};return icons[type] || icons.info;},_ensureContainer(){if(!this._container){this._container = MYPCore.dom.get('#myp-toast-container')|| MYPCore.dom.create('div',{id:'myp-toast-container',class:'myp-toast-container'});if(!this._container.parentNode){document.body.appendChild(this._container);}}},close(id){const toast = this._activeToasts.get(id);if(toast){clearTimeout(toast.timeout);toast.element.classList.remove('show');setTimeout(()=>{toast.element.remove();this._activeToasts.delete(id);},300);}},closeAll(){this._activeToasts.forEach((_,id)=> this.close(id));}},api:{_cache:new Map(),_pendingRequests:new Map(),async request(url,options ={}){const config ={...options,headers:{'Content-Type':'application/json','X-CSRFToken':MYPCore.csrf.getToken(),...options.headers}};if(options.method === 'GET' || !options.method){const cacheKey = this._getCacheKey(url,options);const cached = this._cache.get(cacheKey);if(cached && !options.noCache){const age = Date.now()- cached.timestamp;const maxAge = options.cacheTime || 300000;if(age < maxAge){return cached.data;}}if(this._pendingRequests.has(cacheKey)){return this._pendingRequests.get(cacheKey);}}const requestPromise = fetch(url,config).then(async response =>{if(!response.ok){throw new Error(`HTTP ${response.status}:${response.statusText}`);}const data = await response.json();if(config.method === 'GET' || !config.method){const cacheKey = this._getCacheKey(url,options);this._cache.set(cacheKey,{data,timestamp:Date.now()});this._pendingRequests.delete(cacheKey);}return data;}).catch(error =>{if(config.method === 'GET' || !config.method){this._pendingRequests.delete(this._getCacheKey(url,options));}throw error;});if(config.method === 'GET' || !config.method){this._pendingRequests.set(this._getCacheKey(url,options),requestPromise);}return requestPromise;},_getCacheKey(url,options){return `${url}_${JSON.stringify(options.params ||{})}`;},clearCache(pattern){if(pattern){for(const [key] of this._cache){if(key.includes(pattern)){this._cache.delete(key);}}}else{this._cache.clear();}}},time:{formatAgo(timestamp){const date = timestamp instanceof Date ? timestamp:new Date(timestamp);const now = new Date();const seconds = Math.floor((now - date)/ 1000);const intervals = [{label:'Jahr',seconds:31536000,plural:'Jahre'},{label:'Monat',seconds:2592000,plural:'Monate'},{label:'Woche',seconds:604800,plural:'Wochen'},{label:'Tag',seconds:86400,plural:'Tage'},{label:'Stunde',seconds:3600,plural:'Stunden'},{label:'Minute',seconds:60,plural:'Minuten'}];for(const interval of intervals){const count = Math.floor(seconds / interval.seconds);if(count >= 1){const label = count === 1 ? interval.label:interval.plural;return `vor ${count}${label}`;}}return 'Gerade eben';},formatDuration(seconds){const hours = Math.floor(seconds / 3600);const minutes = Math.floor((seconds % 3600)/ 60);const secs = seconds % 60;const parts = [];if(hours > 0)parts.push(`${hours}h`);if(minutes > 0)parts.push(`${minutes}m`);if(secs > 0 || parts.length === 0)parts.push(`${secs}s`);return parts.join(' ');}},perf:{debounce(func,wait){let timeout;return function debounced(...args){const context = this;clearTimeout(timeout);timeout = setTimeout(()=> func.apply(context,args),wait);};},throttle(func,limit){let inThrottle;return function throttled(...args){const context = this;if(!inThrottle){func.apply(context,args);inThrottle = true;setTimeout(()=> inThrottle = false,limit);}};},memoize(func,resolver){const cache = new Map();return function memoized(...args){const key = resolver ? resolver(...args):args[0];if(cache.has(key)){return cache.get(key);}const result = func.apply(this,args);cache.set(key,result);return result;};}},events:{_listeners:new Map(),on(element,event,handler,options ={}){const key = `${element}_${event}`;if(!this._listeners.has(key)){this._listeners.set(key,new Set());}this._listeners.get(key).add(handler);element.addEventListener(event,handler,options);return()=> this.off(element,event,handler);},off(element,event,handler){const key = `${element}_${event}`;const handlers = this._listeners.get(key);if(handlers){handlers.delete(handler);if(handlers.size === 0){this._listeners.delete(key);}}element.removeEventListener(event,handler);},once(element,event,handler,options ={}){const wrappedHandler =(e)=>{handler(e);this.off(element,event,wrappedHandler);};return this.on(element,event,wrappedHandler,options);}},storage:{get(key,defaultValue = null){try{const item = localStorage.getItem(`myp_${key}`);return item ? JSON.parse(item):defaultValue;}catch(e){console.error('Storage get error:',e);return defaultValue;}},set(key,value){try{localStorage.setItem(`myp_${key}`,JSON.stringify(value));return true;}catch(e){console.error('Storage set error:',e);return false;}},remove(key){localStorage.removeItem(`myp_${key}`);},clear(prefix = 'myp_'){const keys = Object.keys(localStorage);keys.forEach(key =>{if(key.startsWith(prefix)){localStorage.removeItem(key);}});}}};window.MYPCore = MYPCore;window.showToast =(msg,type,duration)=> MYPCore.notify.show(msg,type,duration);window.showNotification = window.showToast;window.showFlashMessage = window.showToast;window.showSuccessMessage =(msg)=> MYPCore.notify.show(msg,'success');window.showErrorMessage =(msg)=> MYPCore.notify.show(msg,'error');window.showWarningMessage =(msg)=> MYPCore.notify.show(msg,'warning');window.showInfoMessage =(msg)=> MYPCore.notify.show(msg,'info');if(document.readyState === 'loading'){document.addEventListener('DOMContentLoaded',()=>{console.log('✅ MYP Core Utilities initialized');});}else{console.log('✅ MYP Core Utilities initialized');}})(window);