var UI = { getToken: function (args) { if (args.options.body && typeof args.options.body !== 'string') args.options.body = JSON.stringify(args.options.body); fetch(args.url, args.options).then(response => response.json()).then(data => { console.log('fetchJson success'); console.log(data); js.json.data.user.token = data.access_token; js.callback({do:args.success}); }).catch((err) => { console.log('fetchJson error'); console.log(err); js.json.data.user.token = data.access_token; js.callback({do:args.error}); }) }, init: function () { }, // Function to generate a form as a JSON structure from a JSON schema schemaToForm: function (params) { /* alert(JSON.stringify(params)); */ if (!params.schema || !params.schema.properties) { return { html: [ { tag: 'p', text: 'schemaToForm Error: Invalid JSON schema provided.' } ] }; } const formElements = []; // Iterate through schema properties for (const [key, prop] of Object.entries(params.schema.properties)) { const label = prop.description || key; const required = params.schema.required && params.schema.required.includes(key) ? 'required' : ''; const inputId = `input-${key}`; // Unique ID for accessibility const hiddenId = (key == 'id' && jsonApp && jsonApp.json.data.settings && !jsonApp.json.data.settings.debug) ? ' hidden' : ''; // Create fieldset for each field const fieldsetChildren = [ { "tag": "label", "attr": { "class": "label text-primary" + hiddenId, "data-value": params.db + "/" + key, "for": key }, "html": [ { tag: 'span', text: label } ] } ]; // Handle different input types let inputElement; switch (prop.type) { case 'string': if (prop.format == 'dbid') { inputElement = { tag: "select", attr: { "data-value": params.db + "/" + key, "name": key, "type": 'text', "value": (params.fields && params.fields[key]) ? params.fields[key] : false, "placeholder": prop.description || ' ', "class": 'field select w-full select-primary' + hiddenId, ...(required && { required: '' }) } }; inputElement.html = []; let db = (js.json.data.db) ? js.json.data.db : {}; if (db[key]) { for (let item of db[key]) { let id = item.id; let name = item.name || ''; let attr = {"value": id, "class":"option", "data-value": params.db + "/" + key + "/" + id}; if (id == params.fields[key]) attr.selected = true; inputElement.html.push( { "tag": "option", "attr": attr, "text": name } ) } } else { //js.log('Can\'t load local db: ' + key, 'red'); console.log('%c' + 'Can\'t load local db ' + key, 'color: red'); } } else if (prop.format == 'date-time') { // https://unpkg.com/flatpickr@2.0.2/index_.html inputElement = { "tag": "input", "attr": { //"id": inputId, "data-value": params.db + "/" + key, "name": key, "type": "number", // datetime-local "value": (params.fields && params.fields[key]) ? new Date(Number(params.fields[key])) : false, "placeholder": new Date().toLocaleDateString("it-IT", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"}) || ' ', "data-enable-time": true, "data-enable-seconds": true, "data-time_24hr": true, "data-date-format":"Y-m-d H:i:S", class: "field input datepicker w-full input-primary" + hiddenId, ...(required && { required: '' }) }, "on": { "in": [ { "js": "flatpickr('.datepicker', {enableSeconds: true, time_24hr: true})" } ] } }; /* flatpickr("#date-time-flatpickr-demo", { defaultDate: new Date(), enableTime: true, }) */ } else if (prop.enum) { // enum () inputElement = { tag: "select", attr: { //"id": inputId, "data-value": params.db + "/" + key, "name": key, "type": 'text', "value": (params.fields && params.fields[key]) ? params.fields[key] : false, "placeholder": prop.description || ' ', "class": 'field select w-full select-primary' + hiddenId, ...(required && { required: '' }) } }; inputElement.html = []; for (let item of prop.enum) { let attr = {"value": item, "class":"option", "data-value": params.db + "/" + key + "/" + item}; if (params.fields && params.fields[key] && params.fields[key] == item) attr.selected = true; inputElement.html.push( { "tag": "option", "attr": attr, "text": String(item) } ) } } else { // string inputElement = { tag: 'input', attr: { //id: inputId, "data-value": params.db + "/" + key, "name": key, type: 'text', value: (params.fields && params.fields[key]) ? params.fields[key] : false, placeholder: prop.description || ' ', class: 'field input w-full input-primary' + hiddenId, ...(required && { required: '' }) } }; } break; case 'number': case 'integer': inputElement = { tag: 'input', attr: { //id: inputId, "data-value": params.db + "/" + key, "name": key, type: 'number', value: (params.fields && params.fields[key]) ? params.fields[key] : false, placeholder: prop.description || ' ', class: 'field input w-full input-primary', ...(required && { required: '' }) } }; break; case 'boolean': inputElement = { tag: 'input', attr: { //id: inputId, "data-value": params.db + "/" + key, "name": key, type: 'checkbox', class: 'field toggle toggle-info', ...(required && { required: '' }) } }; if (params.fields[key]) inputElement.attr.checked = true; break; case 'array': inputElement = { tag: 'textarea', attr: { //id: inputId, "data-value": params.db + "/" + key, "name": key, value: (params.fields && params.fields[key]) ? params.fields[key] : false, placeholder: prop.description || 'Enter values separated by commas', class: 'field textarea w-full input-primary', ...(required && { required: '' }) } }; break; case 'object': inputElement = { tag: 'textarea', attr: { //id: inputId, "data-value": params.db + "/" + key, "name": key, placeholder: prop.description || 'Enter JSON object', class: 'field textarea w-full input-primary', ...(required && { required: '' }) } }; break; default: inputElement = { tag: 'input', attr: { //id: inputId, "data-value": params.db + "/" + key, "name": key, type: 'text', value: (params.fields && params.fields[key]) ? params.fields[key] : false, placeholder: prop.description || ' ', class: 'field input w-full input-primary', ...(required && { required: '' }) } }; } // Add input element to fieldset fieldsetChildren.push(inputElement); // Add fieldset to form elements formElements.push({ tag: 'fieldset', attr: { "class": "fieldset text-center", "data-value": params.db }, html: fieldsetChildren }); /* console.log('fviewRow'); console.log(inputElement); */ } /* // Add buttons formElements.push({ tag: 'div', attr: { "class": "w-full mt-6 text-center px-[50px] flex flex-wrap items-center justify-between gap-2 " }, html: [ { "for": { "var": "button", "of": params.buttons, "do": [ { "tag": 'button', "attr": { "type": "{var button type}", "class": "btn {var button class}" }, "text": "{var button title}", "on": { "mousedown": "{var button actions}" } } ] } } ] }); */ // Return the full form structure return { html: formElements }; }, createForm: function (params) { let appForm = UI.schemaToForm(params); appForm.selector = params.selector; jsonApp.do(appForm); }, createTable: function (params) { /* console.log('createTable'); console.log(params); */ const tableData = jsonApp.json.data.db[params.db].map((data) => { return { ...data, //dateTime: new Date(Date.now()) // - 1000 * 60 * 60 * Math.floor(Math.random() * 24 * 100)), } }) const getTableData = () => { return [...tableData] //return [...tableData].sort(() => 0.5 - Math.random()) } const flexRender = (comp, props) => { if (typeof comp === "function") { return comp(props) } return comp } let data = getTableData() let version = 0 let columns = js.json.data.ui.pages[params.db].columns; const state = { columnPinning: { left: [], right: [] }, pagination: { pageSize: 10, pageIndex: 0, }, globalFilter: "", columnFilters: [], columnVisibility: {}, rowSelection: {}, } const table = TableCore.createTable({ state, data, columns, getCoreRowModel: TableCore.getCoreRowModel(), getPaginationRowModel: TableCore.getPaginationRowModel(), getFilteredRowModel: TableCore.getFilteredRowModel(), globalFilterFn: "auto", onStateChange: (updater) => { const newState = typeof updater === "function" ? updater(state) : updater Object.assign(state, newState) }, }); if (!window.table) window.table = {}; window.table[params.db] = { dbId: params.db, version, columns, pageSizes: [5, 10, 20, 50], flexRender, search: "", get table() { this.version return table }, get visibleRows() { this.version return this.table.getRowModel().rows }, get selectedCount() { return this.table.getSelectedRowModel().rows.length }, get totalCount() { return this.table.getPaginationRowModel().rows .length }, get isIndeterminateAllRowsSelected() { this.version return ( this.table.getIsSomePageRowsSelected() && !this.table.getIsAllPageRowsSelected() ) }, get allLeafColumns() { this.version return this.table.getAllLeafColumns() }, get pageSize() { this.version return this.table.getState().pagination.pageSize }, get pageIndex() { this.version return this.table.getState().pagination.pageIndex }, get rowCount() { this.version return data.length }, get start() { this.version return this.rowCount === 0 ? 0 : this.pageIndex * this.pageSize + 1 }, get end() { this.version return Math.min( this.start + this.pageSize - 1, this.rowCount ) }, /* updateInterval(duration) { console.log('updateInterval:'+this.dbId); clearInterval(this.interval); this.interval = setInterval(function (event) {console.log(event); this.dbId}, duration) }, */ updateData() { //console.log('updateData:'+this.dbId); let newData = jsonApp.json.data.db[this.dbId]; this.table.setOptions(prev => ({ ...prev, data: newData })) this.render() }, setPageIndex(n) { this.table.setPageIndex(n) this.render() }, nextPage() { this.version if (this.table.getCanNextPage()) { this.table.setPageIndex(this.pageIndex + 1) this.render() } }, prevPage() { this.version if (this.table.getCanPreviousPage()) { this.table.setPageIndex(this.pageIndex - 1) this.render() } }, changePageSize(newSize) { this.table.setPageSize(Number(newSize)) this.render() }, updateSearch() { table.setState({ ...table.getState(), globalFilter: this.search, }) this.render() }, getVisibleCells(row) { this.version return row.getVisibleCells() }, isColumnVisible(column) { this.version return column.getIsVisible() }, toggleColumn(column) { column.toggleVisibility() this.render() }, toggleSelectedRow(row) { row.toggleSelected() this.render() }, isRowSelected(row) { this.version return row.getIsSelected() }, toggleAllRowsSelected() { this.table.toggleAllPageRowsSelected() this.render() }, viewRow(row) { let fields = Alpine.raw(row.original); //let id = `${row.original.id}`; js.part({'do':'rl:openPost',arguments:{db: params.db, fields: fields}}); }, deleteRow(row) { let fields = Alpine.raw(row.original); //let id = `${row.original.id}`; js.part({'do':'removePost',arguments:{db: params.db, fields: fields}}); }, clearFilters() { this.search = "" this.updateSearch() }, render() { this.version++ } } return window.table[params.db] }, loadTemplate: function (params) { // add to html the parameters {url, to} var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", params.url, false); xmlhttp.send(); if (xmlhttp.responseText) { var responseText = xmlhttp.responseText; if (params.arguments) { responseText = js.replacePropertyWithPrefix(responseText, 'arguments', params.arguments); } if (params.to) js.element({ root: js.json, path: params.to, value: responseText }); if (params.selector) { if (params.prepend) document.querySelector(params.selector).innerHTML = responseText + document.querySelector(params.selector).innerHTML; else if (params.empty) document.querySelector(params.selector).innerHTML = responseText; else document.querySelector(params.selector).innerHTML += responseText; } } else console.log('Error loading '+ params.url); } } /* var getToken = function (args) { //UI.token(args); if (args.options.body && typeof args.options.body !== 'string') args.options.body = JSON.stringify(args.options.body); fetch(args.url, args.options).then(response => response.json()).then(data => {console.log('fetchJson success'); console.log(data); js.callback({do:args.success});}).catch((err) => {console.log('fetchJson error');console.log(err);js.callback({do:args.error});}) } */ /* let args = { "url": "https://192.168.1.3:10002/realms/API.Server.local/protocol/openid-connect/token", "options": { "method": "POST", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "body": "grant_type=client_credentials&client_id=Fastapi&client_secret=wojuoB7Z5xhlPFrF2lIxJSSdVHCApEgC" } }; */ //UI.getToken(args); //UI.loadTemplate({selector: 'content', url:'./assets/html/tracks.html'}); // components-interactions-form-validations /* empty css */ ;(function () { const t = document.createElement("link").relList if (t && t.supports && t.supports("modulepreload")) return for (const e of document.querySelectorAll('link[rel="modulepreload"]')) i(e) new MutationObserver((e) => { for (const r of e) if (r.type === "childList") for (const o of r.addedNodes) o.tagName === "LINK" && o.rel === "modulepreload" && i(o) }).observe(document, { childList: !0, subtree: !0 }) function s(e) { const r = {} return ( e.integrity && (r.integrity = e.integrity), e.referrerPolicy && (r.referrerPolicy = e.referrerPolicy), e.crossOrigin === "use-credentials" ? (r.credentials = "include") : e.crossOrigin === "anonymous" ? (r.credentials = "omit") : (r.credentials = "same-origin"), r ) } function i(e) { if (e.ep) return e.ep = !0 const r = s(e) fetch(e.href, r) } })()