/** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/components/paragraph.js **/ /** * rest/arunox/generators/components/paragraph.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Hooks.register( 'generator.components/paragraph->create.OLD', function( [ type, name, hook, config, data ] ) { type = 'htmltag'; name = 'p'; hook = `${type}.${name}`; ARUNOX.Theme.bindHooks( type, name, hook ); return [ type, name, hook, config, data ]; }, 0 ); ARUNOX.Registry.htmlTag.register( 'p', class RestTemplateDefault extends ARUNOX.Theme.Component { static htmlTag = 'p'; static hooks = { config( config, type, name, data, storage ) { config.textNode ??= config.text || null; return config; }, }; create( config, data ) { const className = 'paragraph'; const block = config.block ? `${className} ${config.block}__${className}` : className; this.element.classList.add( ...block.split(' ') ); if( config.icon ) this.elements.icon = this.render( 'components/icon', { name: config.icon, block: config.block } ); if( config.color ) this.apply( 'colorize', config.color, { target: 'icon' }, this.elements.icon ); } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/components/breadcrumbs.js **/ /** * rest/arunox/generators/components/breadcrumbs.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'components/breadcrumbs', class RestTemplateDefault extends ARUNOX.Theme.Component { static htmlTag = 'h1'; create( config, data ) { const wrapper = document.querySelector('#breadcrumbs'); if( !wrapper) return; if( location.pathname != config.path.cachekey || config.path.cachekey != config.path.history ) { window.history.pushState({}, "", config.path.history ); } const home = wrapper.querySelector( '.breadcrumbs__item--home'); const items = wrapper.querySelectorAll( ':not(.breadcrumbs__item--home) '); if( !wrapper ) return; wrapper.classList.add( 'breadcrumbs' ); items.forEach( element => element.remove() ); const segments = router.getBreadcrumbSegments( config.path.history ); for( const [ index, segment ] of segments.entries() ) { if( ( home && index === 0 ) || ( index <= segments.length - 1 ) ) { generator.generate( 'components/breadcrumbs/separator', {}, {}, wrapper ); } generator.generate( 'components/link', { name : 'item', block : 'breadcrumbs', path : index === segments.length - 1 ? false : segment.path, label : segment.label, active : index === segments.length - 1, }, {}, wrapper ); } } }); ARUNOX.Registry.generator.register( 'components/breadcrumbs/separator', class RestTemplateDefault extends ARUNOX.Theme.Component { static htmlTag = 'h1'; create( config, data ) { const separator = document.createElement('div'); separator.classList.add('breadcrumbs__separator'); container.append( separator ); } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/components/headline.js **/ /** * rest/arunox/generators/components/headline.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'components/headline', class extends ARUNOX.Theme.Component { static htmlTag = 'h1'; create( config, data ) { this.append( document.createTextNode( data || config.title ) ) } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/components/icon.js **/ /** * rest/arunox/generators/components/icon.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'components/icon', class RestTemplateDefault extends ARUNOX.Theme.Component { static htmlTag = 'i'; create( config, data ) { const className = 'icon'; const block = config.block ? `${className} ${config.block}__${className}` : className; this.element.classList.add( ...config.name.split(' ') ); this.element.classList.add( ...block.split(' ') ); // if( config.color ) this.classList.add(`text--${config.color}`); if( config.color ) this.apply( 'colorize', config.color, { target: 'text' }); this.parent.element?.classList.add( 'has--icon' ); } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/components/link.js **/ /** * rest/arunox/generators/components/link.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'components/link', class RestTemplateDefault extends ARUNOX.Theme.Component { static htmlTag = 'a'; create( config, data ) { const link = this.element; const label = document.createElement("span"); const name = config.name || 'link'; const block = config.block ? `${config.block}__${name}` : name; // Standardklasse setzen oder `block` nutzen (z. B. "menu") link.classList.add( block ); link.elements = {}; if( config.title ) link.title = config.title; if( config.active ) link.classList.add( `${block}--active` ); if( !config.path ) link.classList.add( `${block}--inactive` ); if( config.icon ) link.elements.icon = this.render("components/icon", { name: config.icon, block: config.block } ); if( config.label ) { label.innerHTML = config.label; label.classList.add( `${block}__label` ); link.append( label ); } if( config.path && config.path != '#' ) { link.addEventListener("click", (event) => { event.preventDefault(); ARUNOX.Router.handle( config.path, {}, {}, 'rest' ); }); } } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/hooks/menus.js **/ /** * rest/arunox/hooks/menus.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'menus/category', class RestTemplateDefault extends ARUNOX.Theme.Component { create( config, data ) { const label = this.render( 'menus/category/label', { textNode : data.route.label, classes : 'menu__label', }); this.element.classList.add( 'menu__category' ); this.apply( 'addSubmenu', data.route, data.routes ); if( !this.element.querySelectorAll('.menu__item').length ) { this.remove(); } } }); ARUNOX.Hooks.register( 'routes.OLD', function( routes, name ) { if( !routes ) return []; const arxNames = new Set( ( Array.isArray(name) ? name : (typeof name === 'string' && name.trim() && name !== 'undefined') ? [name] : (this.instance.element?.dataset?.arxMenu ? this.instance.element.dataset.arxMenu.split(',') : []) ) .map(s => { if (typeof s !== 'string') return null; const val = s.trim().toLowerCase(); return val && val !== 'undefined' ? val : null; }) .filter(Boolean) ); return routes .map( r => Object.assign( r, { menu: Array.isArray( r.menu ) ? r.menu : r.menu?.split(' ' )} )) .filter( item => item.menu && item.menu.some( x => arxNames.has( String(x).toLowerCase() ) ) ); }); ARUNOX.Hooks.register( 'addMenus.OLD', function( routes ) { const arxNames = new Set( this.instance.element.dataset.arxMenu.split(',').map( s => s.toLowerCase() ) ); const arxRoutes = this.instance.filter( 'routes', routes ); if( !arxRoutes.length ) return; for( const arxRoute of arxRoutes ) { if( !arxRoute.path ) this.instance.apply( 'addCategory', arxRoute, routes ); else this.instance.apply( 'addButton', arxRoute, routes ); } }); ARUNOX.Hooks.register( 'addSubmenu.OLD', function( route, routes ) { const arxRoutes = ARUNOX.Hooks.filter( 'routes', routes, route.name ); if( !arxRoutes.length ) return; const submenu = this.instance.render( 'div' ); submenu.element.classList.add( 'menu__sub' ); submenu.setData( { menu: route.name }); submenu.apply( 'addMenus', routes ); submenu.parent.element.classList.add( 'has-children' ); route.element = submenu; }); ARUNOX.Hooks.register( 'addCategory.OLD', function( route, routes ) { route.element = this.instance.render( 'menus/category', {}, { route, routes } ); }); ARUNOX.Hooks.register( 'addButton.OLD', function( route, routes ) { const current = window.location.pathname; const wrapper = this.instance.render( 'div' ); const button = wrapper.render( 'button', Object.assign( {}, route, { name : 'button', block : 'menu', action : route.path, })); const icon = button.element.querySelector( '.icon' ); route.element = wrapper; wrapper.element.classList.add( 'menu__item' ); button.element.classList.add( 'menu__link' ); wrapper.element.querySelectorAll( '.button' ).forEach( e => e.classList.remove( 'button' ) ); if( route.path != '/' && current.startsWith( route.path ) ) { if( route.path == current || routes.filter( item => item.path && item.path.startsWith( route.path ) ).length == 1 ) { wrapper.element.classList.add('is-expanded'); wrapper.element.classList.add('menu__item--active'); button.element.classList.add('menu__link--active'); this.instance.element.closest('.menu__item')?.classList.add('is-expanded'); this.instance.element.closest('.menu__item')?.classList.add('has-active'); } } button.element.addEventListener( 'click', () => { const hasPath = route.path && route.path != '#'; const isExpanded = wrapper.element.classList.contains('is-expanded'); const hasChildren = wrapper.element.classList.contains('has-children'); document.querySelectorAll('.has-active').forEach(el => el.classList.remove('has-active')); document.querySelectorAll('.is-expanded').forEach(el => el.classList.remove('is-expanded')); document.querySelectorAll('.menu__item').forEach(el => el.classList.remove('menu__item--active')); document.querySelectorAll('.menu__link--active').forEach(el => el.classList.remove('menu__link--active')); if( hasPath ) { button.element.classList.add("menu__link--active"); } if( isExpanded && hasChildren ) return; wrapper.element.classList.add("is-expanded"); wrapper.element.classList.add("menu__item--active"); this.instance.element.closest('.menu__item')?.classList.add('is-expanded'); this.instance.element.closest('.menu__item')?.classList.add('has-active'); }); if( route.color ) button.apply( 'colorize', route.color, { prefix: 'theme' }, icon ); else button.element.classList.add( 'behavior-default' ); this.instance.append( wrapper ); wrapper.apply( 'addSubmenu', route, routes ); }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/hooks/validation.js **/ /** * rest/arunox/hooks/validation.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Hooks.register( 'validation.OLD', function( config, data ) { if( config.validate === false ) return; this.instance.element.validate = config.validate; if( typeof config.validate === 'undefined' ) { config.validate = true; } if( typeof config.validate === 'string' ) { const validateType = config.validate; config.validate = {}; config.validate[ validateType ] = true; } if( typeof config.validate === 'boolean' ) { config.validate = {}; } this.instance.parent.element.querySelectorAll( '.form__info--feedback' ).forEach( element => element.remove() ); if( config.validate?.onCreate ?? false ) this.instance.validators.validateAll( config, data ); if( config.validate?.onChange ?? true ) this.instance.validators.on( 'change', config, data ); if( config.validate?.onBlur ?? false ) this.instance.validators.on( 'blur', config, data ); this.instance.validators.on( 'validate', config, data ); }); ARUNOX.Hooks.register( 'validation.invalid.OLD', function( config, data ) { this.instance.render( 'data/form/feedback', config, data ); }); ARUNOX.Hooks.register( 'validation.valid.OLD', function( config, data ) { this.instance.render( 'data/form/feedback', config, data ); }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/hooks/inputs/password.js **/ /** * rest/arunox/hooks/inputs/password.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Hooks.register('customize/input/password.OLD', function( config, data ) { if( config.validate?.confirm ) { this.validators.register( 'confirm' ); } if( config.confirm ) { config.confirm = Object.assign( {}, config, { key : config.key + '_confirm', label : config.confirm, confirm : false, }); this.instance.parent.parent.render( 'data/form/control', config.confirm, data ); } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/data/tabs.js **/ /** * rest/arunox/htmltags/tabs.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.htmlTag.register( 'tabs', class extends ARUNOX.Theme.Component { static htmlTag = 'div'; static rootName = 'tabs'; static hooks = { config( config, type, name, data, storage ) { config.tabs ??= {}; return config; }, }; create( config, data ) { const tableUUID = ''; //context.getUUID(); const storage = this.storage.config const elements = this.elements; storage.query = window.location.hash.match( /\?(.*)/ ); storage.hash = window.location.hash.substring(1).replace( /\?.*/, '' ); storage.filter = new URLSearchParams( storage.query ? storage.query[1] : '' ); storage.isNested = this.element.closest( '.dialog, .tabs__content' ) !== null; if( storage.isNested ) { let match = ARUNOX.Router.history.match( /.*(?:#([a-zA-Z0-9]+)).*/ ); storage.hash = this.element.dataset.activeTab || match ? match[1] : ''; storage.filter = new URLSearchParams(); } storage.search = []; elements.tabs = this; elements.buttons = this.render( 'tabs.buttons', { tabs : config.tabs, }); elements.contents = this.render( 'tabs.contents', { tabs : config.tabs, }, data ); this.element.classList.add( 'tabs' ); } }); ARUNOX.Registry.htmlTag.register( 'tabs.buttons', class extends ARUNOX.Theme.Component { static htmlTag = 'div'; static hooks = { config( config, type, name, data, storage ) { config.classes.push( 'tabs__list' ); return config; } }; create( config, data ) { for( const [ index, tabConfig ] of config.tabs.entries() ) { this.elements[ tabConfig.id ] = this.render( 'tabs.button', Object.assign( {}, tabConfig, { index } ) ); } } }); ARUNOX.Registry.htmlTag.register( 'tabs.button', class extends ARUNOX.Theme.Component { static extends = 'htmltag.button'; static hooks = { config( config, type, name, data, storage ) { return Object.assignRecursive( {}, config, { id : null, content : null, classes : [ 'tabs__item' ], arx : { tab : config.id, }, }); }, select() { const elements = this.instance.parent.parent.elements; const storage = this.instance.parent.parent.storage.config; const element = this.instance.element; const config = this.instance.storage.config; for( const button of Object.values( elements.buttons.elements ) ) { button.element.classList.remove('tabs__item--active' ); if( button.element.dataset.arxTab == config.arx.tab ) { element.classList.add( 'tabs__item--active' ); } } for( const content of Object.values( elements.contents.elements ) ) { if( content.element.dataset.arxTab == config.arx.tab ) { content.element.classList.add('tabs__content--active' ); content.element.style.display = ''; content.apply('show'); } else { content.element.classList.remove('tabs__content--active' ); content.element.style.display = 'none'; content.apply('hide'); } } if( storage.isNested ) return; if( element.dataset.tabFilter ) { history.pushState(null, null, `#${config.arx.tab}?${config.arx.filter}`); } else history.pushState(null, null, `#${config.arx.tab}`); }, afterRender() { const elements = this.instance.parent.parent.elements; const storage = this.instance.parent.parent.storage.config; const element = this.instance.element; const config = this.instance.storage.config; const data = this.instance.storage.data; if( config.action ) { element.classList.add('tabs__item--action'); element.addEventListener( 'click', () => ARUNOX.Router.handle( config.action, {}, data, 'rest' ) ); return; } if( config.type === 'submit' ) { element.classList.add('tabs__item--action'); return; } if( ( storage.hash && storage.hash === config.arx.tab ) || ( !storage.hash && ( config.active || ( config.index === 0 && !storage.tabs.some( t => t.active ) ) ) ) ) { element.classList.add( 'tabs__item--active'); // contentContainer.style.display = ''; config.active = true; queueMicrotask( () => this.instance.apply('select') ); } else config.active = false; if( storage.filter && storage.hash && storage.hash === config.arx.tab ) { this.instance.setData({filter: storage.filter.toString() }); } element.addEventListener( 'click', () => this.instance.apply('select') ); }, }; }); ARUNOX.Registry.htmlTag.register( 'tabs.contents', class extends ARUNOX.Theme.Component { static htmlTag = 'div'; static hooks = { config( config, type, name, data, storage ) { config.classes.push( 'tabs__content', 'scroll__viewport' ); return config; } }; create( config, data ) { for( const [ index, tabConfig ] of config.tabs.entries() ) { if( tabConfig.action || config.type === 'submit' ) continue; this.elements[ tabConfig.id ] = this.render( 'tabs.content', Object.assign( {}, tabConfig, { index } ) ); } } }); ARUNOX.Registry.htmlTag.register( 'tabs.content', class extends ARUNOX.Theme.Component { static htmlTag = 'div'; static rootName = 'tab'; static hooks = { config( config, type, name, data, storage ) { return Object.assignRecursive( {}, config, { id : null, style : { display : 'none', }, classes : [ 'tabs__content__item' ], arx : { tab : config.id, }, }); }, afterRender() { const elements = this.instance.parent.parent.elements; const storage = this.instance.parent.parent.storage.config; const element = this.instance.element; const config = this.instance.storage.config; const data = this.instance.storage.data; }, }; }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/data/table.js **/ /** * rest/arunox/htmltags/table.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.htmlTag.register( 'table', class extends ARUNOX.Theme.Component { static htmlTag = 'table'; static rootName = 'table'; static hooks = { config( config, type, name, data, storage ) { config.columns ??= {}; return config; }, search( searchValue ) { // console.log( 'SEARCH', searchValue ); const elements = this.instance.elements; const toolbar = elements.toolbar.elements; const tableRows = elements.tbody.element.querySelectorAll('tr'); searchValue = searchValue.toLowerCase(); let visibleRows = []; tableRows.forEach(row => { const searchData = row.dataset?.arxSearch || ''; const isVisible = searchData.includes( searchValue ); row.style.display = isVisible ? null : 'none'; if( isVisible ) { visibleRows.push( row ); } }); toolbar.resetBtn.element.style.display = visibleRows.length == tableRows.length ? 'none' : null; visibleRows.forEach( row => elements.tbody.append( row ) ); }, reset( config ) { // console.log( 'RESET' ); const elements = this.instance.elements; const toolbar = elements.toolbar.elements const tbody = elements.tbody; const tableRows = elements.tbody.element.querySelectorAll('tr'); tableRows.forEach(row => { row.style.display = null; }); const query = window.location.hash.match( /\?(.*)/ ); const hash = window.location.hash.substring(1).replace( /\?.*/, '' ); const filter = new URLSearchParams( query ? query[1] : '' ); if( config?.query ) { for( const [ index, value ] of config.query.entries() ) { if( filter.has( index ) && filter.get( index ) == value ) { filter.delete( index ); } } } if( filter?.size ) history.pushState(null, null, `#${hash}?${filter.toString()}`); else history.pushState(null, null, `#${hash}`); if( config?.button ) delete config.button.dataset.tabFilter; if( toolbar.resetBtn ) toolbar.resetBtn.element.style.display = 'none'; if( toolbar.searchInput ) toolbar.searchInput.element.value = ''; }, sort( column, order ) { // console.log( 'SORT', column, order ); const elements = this.instance.elements; const config = elements.table.storage.config; const tabelCell = elements.thead.element.querySelector( `[data-arx-column="${column}"]` ); const tableRows = Array.from( elements.tbody.element.querySelectorAll( 'tr' ) ); if( !tabelCell || !tableRows ) return; if( !order ) order = tabelCell.dataset.arxOrder === 'asc' ? 'desc' : 'asc'; const columns = config.columns || []; const rules = config.order.rules || {}; if( rules[ column ]?.replace ) { for( const [ oldCol, newCol ] of Object.entries( rules[ column ].replace ) ) { elements.table.querySelectorAll(`td[data-arx-column="${oldCol}"]`).forEach(td => { const rowData = td.closest('tr').rowData; td.innerHTML = rowData[ newCol ] || ''-''; // td.dataset.arxColumn = newCol; // Key anpassen }); } } if( rules[ column ]?.show ) { for( const showCol of rules[ column ].show ) { elements.table.querySelectorAll(`td[data-arx-column="${showCol}"], th[data-arx-column="${showCol}"]`).forEach(el => { el.style.display = ''; // Wieder anzeigen }); } } if( rules[ column ]?.hide ) { for( const hideCol of rules[ column ].hide ) { elements.table.querySelectorAll(`td[data-arx-column="${hideCol}"], th[data-arx-column="${hideCol}"]`).forEach(el => { el.style.display = 'none'; // Wieder anzeigen }); } } // Entferne vorherige Sortierklassen elements.table.element.querySelectorAll('.table__header__cell').forEach(cell => { cell.classList.remove('sorting--asc', 'sorting--desc', 'sorting--current'); }); // Setze neue Sortierklasse if( tabelCell ) { tabelCell.dataset.arxOrder = order; tabelCell.classList.add( `sorting--${order}`, 'sorting--current' ); } if( elements.container ) { elements.container.element.dataset.arxSortingColumn = column; elements.container.element.dataset.arxSortingOrder = order; } // Reihen sortieren tableRows.sort( (rowA, rowB) => { let a = rowA.ARX.storage.data[ column ]?.trim() || ''; let b = rowB.ARX.storage.data[ column ]?.trim() || ''; // Versuche als Zahl zu interpretieren, falls möglich if (!isNaN(a) && !isNaN(b)) { a = parseFloat(a); b = parseFloat(b); } return order === 'asc' ? String(a).localeCompare(String(b)) : String(b).localeCompare(String(a)); }); // Sortierte Reihen neu einfügen elements.tbody.innerHTML = ''; tableRows.forEach( row => elements.tbody.append( row ) ); }, }; create( config, data ) { const tableUUID = ''; //context.getUUID(); const storage = this.storage.config const elements = this.elements; storage.search = []; elements.table = this; elements.thead = this.render( 'table.thead', { columns : config.columns, elements : elements, }); elements.tbody = this.render( 'table.tbody', { columns : config.columns, elements : elements, }, data ); elements.container = this.render( 'div', { classes : 'table__container', elements : elements, }); elements.toolbar = this.addToolbar( config ); elements.container.wrap( this ); this.element.classList.add( 'table' ); if( config.columns ) { config.columns = config.columns.filter( item => Object.keys(item).length > 0 ); } if( !config.columns ) return; if( config.api ) { if( !config.api.resolved ) { config.api = ARUNOX.Router.parseRoute( config.api, data ); } ARUNOX.Router.fetch( config.api ).then( this.generateRows.bind( this ) ); } this.generateRows( data, true ); // Nach dem Generieren der Rows if( config.order && config.order.column ) { const headerCell = this.element.querySelector(`.table__header__cell[data-arx-column="${config.order.column}"]`); const container = this.element.closest( '.table__container' ); // sortTable( config.order.column, config.order.order, headerCell, this ); // Automatischer Sortieraufruf } elements.container.element.dispatchEvent( new Event('loaded', { bubbles: true }) ); } addToolbar( config ) { const table = this.elements.table; const container = this.elements.container; const wrapper = container.render( 'div', { classes : 'table__toolbar', }); if( config.search || config.filter ) { wrapper.elements.searchContainer = wrapper.render( 'div', { classes : 'table__search', }); wrapper.elements.resetBtn = wrapper.elements.searchContainer.render( 'button', { color : 'danger', type : 'button', block : 'table__search', title : 'Filter zurücksetzen', icon : 'bi bi-funnel', style : { display : 'none' }, onClick : () => table.apply( 'reset', config.filter ), }); if( config.search ) { wrapper.elements.searchInput = wrapper.elements.searchContainer.render( 'input', { type : 'text', classes : 'table__search__input', placeholder : 'Suchen...', onInput : () => table.apply( 'search', wrapper.elements.searchInput.element.value ), }); } // if( config.order.buttons ) { // for( const btnConfig of config.order.buttons ) { // const button = this.elements.searchContainer.render( btnConfig.generator, btnConfig.config ); // // button.addEventListener( 'click', () => { // console.log( this.element ); // const table = tableContainer.querySelector('table'); // button.dataset.order = btnConfig.config.order.order == 'asc' ? 'desc' : 'asc'; // sortTable( btnConfig.config.order.column, null, button, table ); // }); // } // } if( config.filter ) { wrapper.addEventListener( 'loaded', () => table.apply( 'filter', config.filter ) ); } } if( config.buttons ) { wrapper.elements.buttonContainer = wrapper.render( 'components/buttons', { buttons : config.buttons, classes : 'table__buttons', }); } return wrapper; } async generateRows( data, loading = false ) { const elements = this.elements; const config = this.storage.config elements.tbody.element.innerHTML = ''; if( !loading && data && data.length ) { for( const rowData of data ) { elements.tbody.render('table.tbody.tr', { columns : config.columns, elements : this.elements, }, rowData ); } return; } elements.tbody.render( 'table.tbody.tr', { elements : this.elements, columns : [ { key : 'hint', colSpan : config.columns.length, textNode : loading ? 'Daten werden geladen ...' : 'Keine Datensätze gefunden', } ], }); } }); ARUNOX.Registry.htmlTag.register( 'table.thead', class extends ARUNOX.Theme.Component { static htmlTag = 'thead'; static hooks = {}; create( config, data ) { const headerRow = this.render('table.thead.tr', { columns : config.columns, elements : this.elements, }); } }); ARUNOX.Registry.htmlTag.register( 'table.thead.tr', class extends ARUNOX.Theme.Component { static htmlTag = 'tr'; static hooks = { config( config, type, name, data, storage ) { config.classes.push( 'table_row' ); config.classes.push( 'table__header__row' ); return config; } }; create( config, data ) { for( const column of config.columns ) { let cellConfig = Object.assign( {}, column, { elements : this.elements, }); let tableCell = this.render( 'table.th', cellConfig ); } } }); ARUNOX.Registry.htmlTag.register( 'table.th', class extends ARUNOX.Theme.Component { static htmlTag = 'th'; static hooks = { config( config, type, name, data, storage ) { config.type ??= 'text'; config.textNode ??= config?.label || null; config.arx.column ??= config?.key || null; config.classes.push( 'table__cell' ); config.classes.push( 'table__header__cell' ); config.classes.push( `table__cell--type-${config.type}` ); config.classes.push( `table__header__cell--type-${config.type}` ); return config; }, sort( order ) { const elements = this.instance.elements; const column = this.instance.element.dataset?.arxColumn || null; elements.table.apply( 'sort', column, order ); }, }; create( config, data ) { if( config.icon ) this.renderFirst( 'components/icon', { name: config.icon } ); if( config.sortable ) { this.element.classList.add( 'sortable' ); this.setData({ column : config.key, order : config.order?.order || 'asc', }); this.element.addEventListener( 'click', () => this.apply( 'sort', null ) ); } if( !config.visible ) { this.element.style.display = 'none'; } } }); ARUNOX.Registry.htmlTag.register( 'table.tbody', class extends ARUNOX.Theme.Component { static htmlTag = 'tbody'; static hooks = {}; create( config, data ) { for( const rowData of Object.entries( data || {} ) ) { this.render('table.tbody.tr', { columns : config.columns, elements : this.elements, }, rowData ); } } }); ARUNOX.Registry.htmlTag.register( 'table.tbody.tr', class extends ARUNOX.Theme.Component { static htmlTag = 'tr'; static hooks = { config( config, type, name, data, storage ) { config.classes.push( 'table_row' ); config.classes.push( 'table__body__row' ); return config; }, update( newData, status ) { const updatedRow = this.instance.replace('table.tbody.tr', { columns : this.instance.storage.config.columns, elements : this.instance.elements, classes : status ? 'table__body__row--updated' : 'table__body__row--failed', }, newData ); setTimeout(() => updatedRow.element.classList.remove( 'table__body__row--updated', 'table__body__row--failed' ), 200 ); } }; create( config, data = {} ) { const searchContent = []; const elements = this.elements; const storage = elements.table.storage.config for( const column of config.columns ) { this.render( 'table.td', Object.assign( {}, column, { elements : this.elements, searchContent : searchContent, }), data ); } if( storage.action && !this.element.classList.contains( 'js--click-bound' ) ) { this.element.classList.add( 'cursor--pointer' ); // if( this && this.RESTconfig.api.route && config.action.route ) { // let rowSearchParams = this.RESTconfig.api.route.match( /\?(.*)/); // let cellSearchParams = config.action.route.match( /\?(.*)/); // // if( rowSearchParams ) rowSearchParams = new URLSearchParams( rowSearchParams[1] ); // if( cellSearchParams ) cellSearchParams = new URLSearchParams( cellSearchParams[1] ); // // // if( rowSearchParams ) { // if( rowSearchParams.has('columns') && ( !cellSearchParams || !cellSearchParams.has('columns') ) ) { // if( cellSearchParams ) rowSearchParams = '&columns=' + rowSearchParams.get('columns'); // else rowSearchParams = '?columns=' + rowSearchParams.get('columns'); // // config.action.route += rowSearchParams; // // } // } // } // this.element.addEventListener( 'click', async ( event ) => { if( ['a'].includes( event.target.tagName.toLowerCase() ) || event.target.classList.contains('js--click-unbound') || event.target.classList.contains('js--click-ownbound') ) return false; await ARUNOX.Router.handle( storage.action, {}, data, 'rest' ); }); this.element.classList.add( 'js--click-bound' ); } this.setData( { 'search' : searchContent.join( ' ' ).toLowerCase() }); } }); ARUNOX.Registry.htmlTag.register( 'table.td', class extends ARUNOX.Theme.Component { static htmlTag = 'td'; static hooks = { config( config, type, name, data, storage ) { config.type ??= 'text'; config.textNode ??= data || '-'; config.visible ??= true; config.arx.column ??= config?.key || null; config.classes.push( 'table__cell' ); config.classes.push( 'table__body__cell' ); config.classes.push( `table__cell--type-${config.type}` ); config.classes.push( `table__body__cell--type-${config.type}` ); return config; }, data( data, config, type, name, storage ) { let value = '-'; if( data[ config.key ] !== undefined ) { value = data[ config.key ]; } else if( config.key.indexOf('.') > -1 ) { let current = data; for( const key of config.key.split('.') ) { current = current[ key ]; } if( current !== undefined ) { value = current; } } return value; } }; create( config, data ) { const tableRow = this.parent; if( data !== null ) tableRow.setData({ [`filter-${config.key}`] : data.toString().toLowerCase() }); if( config.searchable ) config.searchContent.push( this.element.textContent.trim() ); if( !config.visible ) this.style.display = 'none'; this.apply( `type.${config.type}` ); // console.log( config ); } }); ARUNOX.Hooks.register( 'htmltag.table.td->type.OLD.email', function() { const data = this.instance.storage.data; const config = this.instance.storage.config; const element = this.instance.origin || this.instance.element; if( !data ) { element.textContent = '-'; return; } this.instance.element.classList.add( 'js--click-ownbound' ); this.instance.element.addEventListener( 'click', event => { event.preventDefault(); window.location.href = `mailto:${data}`; }); }); ARUNOX.Hooks.register( 'htmltag.table.td->type.icon.OLD', function() { const data = this.instance.storage.data; const config = this.instance.storage.config; const element = this.instance.origin || this.instance.element; const option = config.options[ data ] || {}; element.textContent = null; const icon = this.instance.render( 'components/icon', { name : option?.icon || 'bi bi-question-diamond', color : option?.color || 'default', title : option?.label || `${config.title} nicht definiert`, }); }); ARUNOX.Hooks.register( 'htmltag.table.td->type.status.OLD', function() { this.instance.apply( 'type.icon' ); const rowData = this.instance.parent.storage.data; const tabelCnf = this.instance.elements.table.storage.config; const config = this.instance.storage.config; const element = this.instance.origin || this.instance.element; const action = Object.assign( {}, { query : tabelCnf.api?.query || {}, }, config.action ); this.instance.element.classList.add( 'js--click-ownbound' ); this.instance.element.addEventListener( 'click', async event => { event.preventDefault(); event.stopPropagation(); await ARUNOX.Router.handle( action, {}, rowData, 'rest' ); }); }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/data/form/input.js **/ /** * rest/arunox/generators/data/form/input.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'data/form/input', class extends ARUNOX.Theme.Component { static htmlTag = 'input'; create( config, data ) { this.element.type = config.type; this.element.name = config.key; this.element.value = data?.[ config.key ] || config.value || ''; this.element.readOnly = config.readonly || false; if( config.type != 'hidden' ) { this.element.id = 'control_' + config.key; if( this.element.hasAttribute( 'readonly' ) ) this.element.readonly = true; if( this.element.hasAttribute( 'type' ) ) this.element.type = config.type; if( this.element.hasAttribute( 'name' ) ) this.element.name = config.key; this.element.classList.add( 'form__control' ); if( config.required ) { this.element.required = true; this.validators.register( 'required' ); } if( this.validators.exists( config.type ) ) { this.validators.register( config.type ); } if( config.validate?.request ) { this.validators.register( 'request' ); } if( config.readonly ) { this.parent.element.classList.add( 'is-readonly' ); } if( config.required ) { this.parent.element.classList.add( 'is-required' ); const required = document.createElement( 'span' ); required.classList.add( 'form__info', 'form__info--required' ); required.innerHTML = typeof config.required === 'string' ? config.required : 'required'; this.parent.append( required ); } this.element.addEventListener( 'focus', () => { this.parent.element.classList.add( 'has-focus' ); }); this.element.addEventListener( 'blur', () => { this.parent.element.classList.remove( 'has-focus' ); }); this.apply( 'validation', config, data ); } this.apply( `customize/input/${config.type}`, config, data ); } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/data/form/feedback.js **/ /** * rest/arunox/generators/data/form/control.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'data/form/feedback', class extends ARUNOX.Theme.Component { static htmlTag = 'span'; create( config, type ) { const wrapper = this.parent.parent; const textField = type === null ? 'waiting' : 'message'; wrapper.element.classList.removeRexEx( /^(is)-(valid|invalid)/ ); wrapper.element.classList.removeRexEx( /^(on|validate)-/ ); if( type === null ) wrapper.element.classList.add( 'on-validate' ); else if( type === true ) wrapper.element.classList.add( 'is-valid' ); else if( type === false ) wrapper.element.classList.add( 'is-invalid' ); else wrapper.element.classList.add( `validate-${type}` ); wrapper.element.querySelector('.form__info--feedback')?.remove(); wrapper.append( this ); this.element.classList.add( 'form__info', 'form__info--feedback' ); this.element.innerHTML = ''; if( !config.validate ) return; if( typeof config.validate[ type ] === 'undefined' ) return; if( typeof config.validate[ type ] === 'string' ) { this.element.innerHTML = config.validate[ type ]; return; } if( typeof config.validate[ type ][ textField ] === 'string' ) { this.element.innerHTML = config.validate[ type ][ textField ]; return; } } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/data/table/row.js **/ /** * rest/arunox/generators/data/table/row.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ // updater.extend( 'data/table/row', async ( element, config, rowData ) => { // // if( !element || !rowData ) { // console.error('updateRow Fehler: Fehlende Daten', { element, rowData, config }); // return; // } // // if( !config.columns ) { // console.error('updateRow Fehler: `config.columns` nicht vorhanden', { config }); // return; // } // // element.classList.add( 'table__row--updated' ); // setTimeout(() => element.classList.remove('table__row--updated' ), 200 ); // // // console.log( 'UPDATER', 'data/table/row', config, rowData, element ); // // const newRow = await generator.generate( 'data/table/row', config, rowData, element ); // // const container = element.closest( '.table__container' ); // if( container ) { // const table = container.querySelector('table'); // const column = container.dataset.sortingColumn; // const order = container.dataset.sortingOrder; // // if( column && order && table ) { // sortTable( column, order, null, table ); // } // } // }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/data/table/table.js **/ /** * rest/arunox/generators/data/table/table.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Hooks.register( 'generator.data/table->create.OLD', function( [ type, name, hook, config, data ] ) { type = 'htmltag'; name = 'table'; hook = `${type}.${name}`; ARUNOX.Theme.bindHooks( type, name, hook ); return [ type, name, hook, config, data ]; }, 0 ); function filterTable( filter, elements ) { const tbody = elements.tableContainer.querySelector('tbody'); const rows = elements.tableContainer.querySelectorAll('.table__row'); let visibleRows = []; rows.forEach(row => { let isVisible = true; for( const [ column, value ] of filter.query.entries() ) { const filterable = row.hasAttribute(`data-filter-${column}`); if( !filterable ) { filter.query.delete( column ); continue; } const filterData = row.getAttribute(`data-filter-${column}`) || ''; const filterValue = value.toLowerCase(); if( isVisible ) isVisible = filterData == filterValue; } row.style.display = isVisible ? null : 'none'; if( isVisible ) visibleRows.push( row ); }); if( visibleRows.length != rows.length ) elements.resetBtn.style.display = null; visibleRows.forEach( row => tbody.appendChild( row ) ); } /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/data/table/column.js **/ /** * rest/arunox/generators/data/table/column.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'data/table/column', class RestTemplateDefault extends ARUNOX.Theme.Component { static htmlTag = 'td'; create( config, data ) { const cell = this; const tableRow = this.parent; cell.classList.add('table__cell', 'table__body__column', `table__cell--type-${config.column.type || 'text'}`); cell.RESTconfig = config.column; if( cell.RESTconfig.title ) { cell.title = cell.RESTconfig.title; } if( cell.RESTconfig.action ) { cell.style.cursor = 'pointer'; if( tableRow && tableRow.RESTconfig.api.route && cell.RESTconfig.action.route ) { let rowSearchParams = tableRow.RESTconfig.api.route.match( /\?(.*)/); let cellSearchParams = cell.RESTconfig.action.route.match( /\?(.*)/); if( rowSearchParams ) rowSearchParams = new URLSearchParams( rowSearchParams[1] ); if( cellSearchParams ) cellSearchParams = new URLSearchParams( cellSearchParams[1] ); if( rowSearchParams ) { if( rowSearchParams.has('columns') && ( !cellSearchParams || !cellSearchParams.has('columns') ) ) { if( cellSearchParams ) rowSearchParams = '&columns=' + rowSearchParams.get('columns'); else rowSearchParams = '?columns=' + rowSearchParams.get('columns'); cell.RESTconfig.action.route += rowSearchParams; } // else console.log( cell.RESTconfig.action.route ); } // else console.log( tableRow.RESTconfig.api.route ); } cell.addEventListener('click', async (event) => { event.preventDefault(); event.stopPropagation(); ARUNOX.Router.handle( cell.RESTconfig.action, {}, data, 'rest' ); }); } // Korrekte Datei basierend auf dem Typ laden if( !this.hooks.exists( `customize/columns/${config.column.type || 'text'}` ) ) { config.column.type = 'text'; } this.apply( `customize/columns/${config.column.type || 'text'}`, config, data ); // generator.generate(`data/table/column/${cell.RESTconfig.type || 'text'}`, config, data, cell ); if( config.column.buttons ) { const children = cell.childNodes; const wrapper = document.createElement('div'); wrapper.classList.add( 'table__cell__inner' ); if( children.length ) { for( const child of children ) { if( child.nodeName === '#text' ) { const text = document.createElement('div'); text.classList.add( 'table__cell__inner__text' ); text.append( child ); wrapper.append( text ); } else wrapper.append( child ); } } for( const buttonConfig of config.column.buttons.values() ) { if( buttonConfig.config.visibility ) { let visible = true; for( let [ key, validValues ] of Object.entries( buttonConfig.config.visibility ) ) { if( !validValues.includes( data[ key ] ) ) { visible = false; break; } } if( !visible ) continue; } // await generator.generate( buttonConfig.generator, buttonConfig.config, data, wrapper ); } cell.append( wrapper ); } } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/templates/default.js **/ /** * rest/arunox/templates/default.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Templates.register( 'default', class extends ARUNOX.Theme.Component { create( config, data ) { const breadcrumbs = document.createElement('div'); const homeLink = document.createElement('a'); const header = this.createHeader( config, data ); const sidebar = this.render( 'part/sidebar', config, data ); const navbar = this.createNavbar( config, data ); const logo = this.createLogo( config, data, sidebar ); const main = this.render('main', { name : 'main', classes : 'template__content', arx : { component: 'content' }, }); homeLink.href = '/'; homeLink.classList.add( 'breadcrumbs__item', 'breadcrumbs__item--home', 'bi', 'bi-house-door-fill' ); breadcrumbs.id = 'breadcrumbs'; breadcrumbs.append( homeLink ); header.append( breadcrumbs, navbar.element ); this.append( header, sidebar, main ); this.parent.element.classList.removeRexEx( /template--.*/ ); this.parent.element.classList.add( 'theme', 'template--default' ); this.element.classList.add( 'template__wrapper', 'template--default' ); this.content = main; sidebar.prepend( logo ); generateMenus(); } createNavbar( config, data ) { const wrapper = this.render('nav'); wrapper.element.id = 'navbar'; wrapper.element.classList.add( 'template__navbar', 'menu' ); wrapper.setData({ menu: 'navbar' }); return wrapper; } createHeader( config, data ) { const wrapper = document.createElement('div'); wrapper.id = 'header'; wrapper.classList.add( 'template__header' ); return wrapper; } createLogo( config, data ) { const wrapper = document.createElement('img'); wrapper.src = API_PREFIX + '/logo'; wrapper.classList.add( 'template__logo' ); return wrapper; } }); ARUNOX.Registry.generator.register( 'part/sidebar', class extends ARUNOX.Theme.Component { static htmlTag = 'aside'; create( config, data ) { const inner = this.render('div'); this.element.id = 'sidebar'; this.element.classList.add( 'template__sidebar', 'menu' ); inner.setData({ menu: 'sidebar' }); inner.element.classList.add( 'menu' ); this.append( inner ); } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/layouts/tabs.js **/ /** * rest/arunox/generators/layouts/tabs.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Hooks.register( 'generator.layouts/tabs->create.OLD', function( [ type, name, hook, config, data ] ) { type = 'htmltag'; name = 'tabs'; hook = `${type}.${name}`; ARUNOX.Theme.bindHooks( type, name, hook ); return [ type, name, hook, config, data ]; }, 0 ); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/wrapper/dialog.js **/ /** * rest/arunox/generators/wrapper/dialog.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.wrapper.register( 'dialog', class extends ARUNOX.Theme.Component { static htmlTag = 'div'; static rootName = 'dialog'; static hooks = { config( config, type, name, data, storage ) { config.classes.push( 'dialog' ); config.classes.push( `dialog--${config.size || 'md'}` ); config.classes.push( `dialog--${config.width || 'md'}` ); return config; }, }; create( config, data ) { const wrapper = this.render( 'div', { classes : [ 'dialog__wrapper' ], arx : { component: 'wrapper' }, }); const header = wrapper.render( 'div', { classes : [ 'dialog__header' ], arx : { component: 'header' }, }); const content = wrapper.render( 'div', { classes : [ 'dialog__content' ], arx : { component: 'content' }, }); this.elements.dialog = this; if( config.id ) this.element.dataset.id = config.id; if( config.title ) { header.render( 'components/headline', { size : 2, block : 'template', title : config.title, icon : config?.icon, color : config?.color, }); } if( config.close ) { const closeButton = header.render( 'button', { icon : 'bi-x-lg', classes : [ 'dialog__close' ], elements : this.elements, onClick : ( event ) => this.onClose( event ), arx : { component: 'close' }, }); if( config.backdrop ) { this.element.addEventListener( 'click', ( event ) => { if( event.target === this.element ) { this.onClose( event ); } }); } const cancelButtons = wrapper.element.querySelectorAll( '[type=cancel]' ); if( cancelButtons ) { cancelButtons.forEach( button => button.addEventListener('click', this.close ) ); } } this.element.addEventListener( 'close', this.onClose ); this.element.addEventListener( 'cancel', this._onCancel ); // this.element.show(); queueMicrotask( () => this.calcHeight( this, content ) ); } calcHeight( dialog, content ) { dialog.element.classList.add( 'is-open' ); let height = 0; content.element.querySelectorAll('.tabs__content__item').forEach( element => { const hidden = element.style.display === 'none'; if( hidden ) element.style.display = ''; if( height < element.clientHeight ) height = element.clientHeight; if( hidden ) element.style.display = 'none'; }); height += 10; const buttons = content.element.querySelector( '.form__buttons' ); const viewport = content.element.querySelector( '.scroll__viewport' ); if( viewport ) { const maxHeight = viewport.offsetTop + ( buttons ? buttons.clientHeight + 15 : 0 ); dialog.element.style.setProperty('--height', height + 'px' ); dialog.element.style.setProperty('--maxHeight', maxHeight + 'px' ); } } onClose( event ) { if( event ) event.preventDefault(); console.log( event.target ); event.target.ARX.elements.dialog.element.classList.add('is-closing'); // event.target.ARX.elements.backdrop.element.style.opacity = '0'; setTimeout(() => { event.target.ARX.elements.dialog.remove(); // event.target.ARX.elements.backdrop.remove(); }, 300 ); } _onCancel( event ) { if( !event.target.ARX.storage.config.close || !event.target.ARX.storage.config.backdrop ) { event.preventDefault(); } else event.target.ARX.onClose( event ); } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/header/link.js **/ /** * rest/arunox/generators/header/link.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Registry.generator.register( 'header/link', class extends ARUNOX.Theme.Component { static htmlTag = 'link'; create( route, response) { const config = response.config ?? {}; const data = response.list ?? response.data ?? {}; this.element.rel = data.rel; this.element.href = data.href; this.appendTo( document.head ); } }); /** Datei: plugins/rest/assets.OLD/js/arunox/_OLD/validators/required.js **/ /** * rest/arunox/validators/required.js * * Some Javascript codes without further description * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ ARUNOX.Validator.register( 'required', ( instance, value ) => { if( !instance.element.value || instance.element.value === '' ) { return 'required'; } return true; });