From 5bc36960bfe6dc8cb0169a2e5e6fd8a458fa6c45 Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Tue, 16 Dec 2025 16:57:04 -0500 Subject: [PATCH 1/4] Removed unused grid variable declaration in oncontextmenu method. --- dist/data-grid.js | 1 - dist/data-grid.js.map | 4 +- dist/data-grid.min.js | 8 +- dist/data-grid.min.js.map | 4 +- src/plugins/context-menu.js | 201 ++++++++++++++++++------------------ 5 files changed, 108 insertions(+), 110 deletions(-) diff --git a/dist/data-grid.js b/dist/data-grid.js index 5fee78b..1823be3 100644 --- a/dist/data-grid.js +++ b/dist/data-grid.js @@ -2014,7 +2014,6 @@ var ContextMenu = class extends base_plugin_default { } oncontextmenu(e) { e.preventDefault(); - const grid = this.grid; const target = getParentElement(e.target, "THEAD"); const menu = this.menu; const rect = target.getBoundingClientRect(); diff --git a/dist/data-grid.js.map b/dist/data-grid.js.map index cea7f0b..0b5f42a 100644 --- a/dist/data-grid.js.map +++ b/dist/data-grid.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/utils/camelize.js", "../src/utils/normalizeData.js", "../src/utils/shortcuts.js", "../src/core/base-element.js", "../src/utils/addSelectOption.js", "../src/utils/appendParamsToUrl.js", "../src/utils/convertArray.js", "../src/utils/elementOffset.js", "../src/utils/interpolate.js", "../src/utils/getTextWidth.js", "../src/utils/randstr.js", "../src/utils/debounce.js", "../src/data-grid.js", "../src/core/base-plugin.js", "../src/plugins/column-resizer.js", "../src/utils/getParentElement.js", "../src/plugins/context-menu.js", "../src/plugins/draggable-headers.js", "../src/plugins/touch-support.js", "../src/plugins/selectable-rows.js", "../src/plugins/fixed-height.js", "../src/plugins/autosize-column.js", "../src/plugins/responsive-grid.js", "../src/plugins/row-actions.js", "../src/plugins/editable-column.js", "../src/plugins/spinner-support.js", "../src/plugins/save-state.js", "../data-grid.js"], - "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const grid = this.grid;\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], - "mappings": ";;;AAIe,SAAR,SAA0B,KAAK;AAClC,SAAO,IAAI,YAAY,EAAE,QAAQ,qBAAqB,CAAC,GAAG,QAAQ,IAAI,YAAY,CAAC;AACvF;;;ACDe,SAAR,cAA+B,GAAG;AAErC,MAAI,MAAM,QAAQ;AACd,WAAO;AAAA,EACX;AACA,MAAI,MAAM,SAAS;AACf,WAAO;AAAA,EACX;AAEA,MAAI,MAAM,MAAM,MAAM,QAAQ;AAC1B,WAAO;AAAA,EACX;AAEA,MAAI,MAAM,OAAO,CAAC,EAAE,SAAS,GAAG;AAC5B,WAAO,OAAO,CAAC;AAAA,EACnB;AAEA,MAAI,KAAK,OAAO,EAAE,cAAc,cAAc,CAAC,KAAK,GAAG,EAAE,SAAS,EAAE,UAAU,GAAG,CAAC,CAAC,GAAG;AAClF,QAAI;AAEA,UAAI,MAAM;AACV,UAAI,IAAI,QAAQ,GAAG,MAAM,IAAI;AACzB,cAAM,IAAI,QAAQ,MAAM,GAAG;AAAA,MAC/B;AACA,aAAO,KAAK,MAAM,mBAAmB,GAAG,CAAC;AAAA,IAC7C,QAAQ;AACJ,cAAQ,MAAM,mBAAmB,CAAC,EAAE;AACpC,aAAO,CAAC;AAAA,IACZ;AAAA,EACJ;AACA,SAAO;AACX;;;ACSA,IAAM,wBAAwB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAOA,SAAS,YAAY,MAAM;AACvB,MAAI,sBAAsB,SAAS,IAAI,GAAG;AACtC,WAAO,EAAE,SAAS,KAAK;AAAA,EAC3B;AACA,SAAO,CAAC;AACZ;AAOO,SAAS,aAAa,IAAI,MAAM;AACnC,SAAO,GAAG,aAAa,IAAI;AAC/B;AAOO,SAAS,aAAa,IAAI,MAAM;AACnC,SAAO,GAAG,aAAa,IAAI;AAC/B;AAQO,SAAS,aAAa,IAAI,MAAM,IAAI,IAAI,QAAQ,OAAO;AAC1D,MAAI,SAAS,aAAa,IAAI,IAAI,EAAG;AACrC,KAAG,aAAa,MAAM,GAAG,CAAC,EAAE;AAChC;AAMO,SAAS,gBAAgB,IAAI,MAAM;AACtC,MAAI,aAAa,IAAI,IAAI,GAAG;AACxB,OAAG,gBAAgB,IAAI;AAAA,EAC3B;AACJ;AAOO,SAAS,GAAG,IAAI,MAAM,UAAU;AACnC,KAAG,iBAAiB,MAAM,UAAU,YAAY,IAAI,CAAC;AACzD;AAOO,SAAS,IAAI,IAAI,MAAM,UAAU;AACpC,KAAG,oBAAoB,MAAM,UAAU,YAAY,IAAI,CAAC;AAC5D;AAmBO,SAAS,SAAS,IAAI,MAAM,OAAO,CAAC,GAAG,UAAU,OAAO;AAC3D,QAAM,OAAO,CAAC;AACd,MAAI,SAAS;AACT,SAAK,UAAU;AAAA,EACnB;AACA,MAAI,MAAM;AACN,SAAK,SAAS;AAAA,EAClB;AACA,KAAG,cAAc,IAAI,YAAY,MAAM,IAAI,CAAC;AAChD;AAOO,SAAS,SAAS,IAAI,MAAM;AAC/B,SAAO,GAAG,UAAU,SAAS,IAAI;AACrC;AAMO,SAAS,SAAS,IAAI,MAAM;AAC/B,KAAG,UAAU,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC;AACvC;AAMO,SAAS,YAAY,IAAI,MAAM;AAClC,KAAG,UAAU,OAAO,GAAG,KAAK,MAAM,GAAG,CAAC;AAC1C;AAMO,SAAS,YAAY,IAAI,MAAM;AAClC,KAAG,UAAU,OAAO,IAAI;AAC5B;AAOO,SAAS,EAAE,UAAU,OAAO,UAAU;AACzC,MAAI,oBAAoB,aAAa;AACjC,WAAO;AAAA,EACX;AACA,SAAO,KAAK,cAAc,QAAQ;AACtC;AAOO,SAAS,GAAG,UAAU,OAAO,UAAU;AAC1C,SAAO,MAAM,KAAK,KAAK,iBAAiB,QAAQ,CAAC;AACrD;AASO,SAAS,KAAK,IAAI,UAAU;AAC/B,SAAO,EAAE,UAAU,EAAE;AACzB;AASO,SAAS,QAAQ,IAAI,UAAU;AAClC,SAAO,GAAG,UAAU,EAAE;AAC1B;AAgBO,SAAS,GAAG,SAAS,SAAS,MAAM;AACvC,QAAM,KAAK,SAAS,cAAc,OAAO;AACzC,MAAI,QAAQ;AACR,WAAO,YAAY,EAAE;AAAA,EACzB;AACA,SAAO;AACX;AAMO,SAAS,YAAY,SAAS,cAAc;AAC/C,eAAa,WAAW,aAAa,SAAS,aAAa,WAAW;AAC1E;;;AC9PA,IAAM,cAAN,cAA0B,YAAY;AAAA;AAAA;AAAA;AAAA,EAIlC,YAAY,UAAU,CAAC,GAAG;AACtB,UAAM;AAGN,SAAK,UAAU,OAAO,OAAO,CAAC,GAAG,KAAK,gBAAgB,KAAK,mBAAmB,OAAO;AAErF,SAAK,IAAI,aAAa;AAEtB,SAAK,QAAQ;AACb,SAAK,aAAa;AAClB,SAAK,OAAO;AAEZ,SAAK,IAAI,OAAO;AAAA,EACpB;AAAA,EAEA,IAAI,iBAAiB;AACjB,WAAO,CAAC;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,KAAK;AACX,WAAO,KAAK,QAAQ,GAAG;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,KAAK,GAAG;AACd,iBAAa,MAAM,QAAQ,GAAG,IAAI,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,KAAK;AACd,iBAAa,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,UAAU,GAAG,CAAC;AAAA,EAC1D;AAAA,EAEA,IAAI,oBAAoB;AACpB,UAAM,aAAa,KAAK,QAAQ,SAAS,KAAK,MAAM,KAAK,QAAQ,MAAM,IAAI,CAAC;AAC5E,UAAM,OAAO,EAAE,GAAG,KAAK,QAAQ;AAC/B,eAAW,OAAO,MAAM;AACpB,UAAI,QAAQ,YAAY,CAAC,KAAK,eAAe,GAAG,KAAK,OAAO,KAAK,GAAG,MAAM,YAAY;AAClF;AAAA,MACJ;AACA,WAAK,GAAG,IAAI,cAAc,KAAK,GAAG,CAAC;AAAA,IACvC;AAEA,WAAO,OAAO,MAAM,UAAU;AAC9B,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAAW;AACd,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA,EAKV,OAAO,MAAM;AACT,QAAI,KAAK,QAAQ,OAAO;AACpB,cAAQ,IAAI,IAAI,aAAa,MAAM,IAAI,CAAC,MAAM,GAAG,IAAI;AAAA,IACzD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,OAAO;AACf,QAAI,KAAK,KAAK,MAAM,IAAI,EAAE,GAAG;AACzB,WAAK,KAAK,MAAM,IAAI,EAAE,EAAE,KAAK;AAAA,IACjC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AAAA,EAAC;AAAA,EAEd,oBAAoB;AAEhB,QAAI,KAAK,OAAO;AACZ;AAAA,IACJ;AACA,SAAK,QAAQ;AAEb,eAAW,YAAY;AACnB,WAAK,IAAI,mBAAmB;AAI5B,YAAM,WAAW,SAAS,cAAc,UAAU;AAElD,eAAS,YAAY,KAAK,YAAY,SAAS;AAC/C,WAAK,YAAY,SAAS,QAAQ,UAAU,IAAI,CAAC;AAEjD,YAAM,KAAK,WAAW;AAGtB,eAAS,MAAM,WAAW;AAAA,IAC9B,GAAG,CAAC;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA,EAKjB,uBAAuB;AACnB,eAAW,MAAM;AACb,UAAI,CAAC,KAAK,eAAe,KAAK,OAAO;AACjC,aAAK,IAAI,sBAAsB;AAC/B,aAAK,cAAc;AAEnB,iBAAS,MAAM,cAAc;AAC7B,aAAK,QAAQ;AAAA,MACjB;AAAA,IACJ,GAAG,CAAC;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,sBAAsB;AACtB,WAAO,CAAC;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,yBAAyB,eAAe,UAAU,UAAU;AAExD,QAAI,aAAa,UAAU;AACvB;AAAA,IACJ;AAEA,SAAK,IAAI,6BAA6B,aAAa,EAAE;AAErD,QAAI,WAAW;AACf,UAAM,cAAc,KAAK,oBAAoB,aAAa,KAAK;AAE/D,QAAI,OAAO;AAEX,QAAI,KAAK,QAAQ,OAAO,MAAM,GAAG;AAC7B,aAAO,KAAK,MAAM,CAAC;AACnB,iBAAW;AAAA,IACf;AACA,WAAO,SAAS,IAAI;AACpB,QAAI,UAAU;AACV,WAAK,QAAQ,IAAI,IAAI,YAAY,QAAQ;AAAA,IAC7C,OAAO;AACH,WAAK,IAAI,IAAI,YAAY,QAAQ;AAAA,IACrC;AAGA,QAAI,KAAK,cAAc,KAAK,GAAG,IAAI,SAAS,GAAG;AAC3C,WAAK,GAAG,IAAI,SAAS,EAAE;AAAA,IAC3B;AAAA,EACJ;AACJ;AAEA,IAAO,uBAAQ;;;AChMA,SAAR,gBAAiC,IAAI,OAAO,OAAO,UAAU,OAAO;AACvE,QAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,MAAI,QAAQ,GAAG,KAAK;AACpB,MAAI,SAAS;AACT,QAAI,WAAW;AAAA,EACnB;AACA,MAAI,QAAQ;AACZ,KAAG,YAAY,GAAG;AACtB;;;ACVe,SAAR,kBAAmC,KAAK,SAAS,CAAC,GAAG;AACxD,aAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACnC,QAAI,MAAM,QAAQ,OAAO,GAAG,CAAC,GAAG;AAC5B,iBAAW,KAAK,OAAO,KAAK,OAAO,GAAG,CAAC,GAAG;AAEtC,YAAI,aAAa,OAAO,MAAM,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,KAAK,OAAO,GAAG,EAAE,CAAC,CAAC;AAAA,MAC3E;AAAA,IACJ,OAAO;AACH,UAAI,aAAa,OAAO,KAAK,OAAO,GAAG,CAAC;AAAA,IAC5C;AAAA,EACJ;AACJ;;;ACVe,SAAR,aAA8B,GAAG;AACpC,MAAI,OAAO,MAAM,UAAU;AACvB,QAAI,EAAE,CAAC,MAAM,KAAK;AAEd,UAAI,KAAK;AACT,UAAI,GAAG,QAAQ,GAAG,MAAM,IAAI;AACxB,aAAK,GAAG,QAAQ,MAAM,GAAG;AAAA,MAC7B;AACA,aAAO,KAAK,MAAM,EAAE;AAAA,IACxB;AAEA,WAAO,EAAE,MAAM,GAAG;AAAA,EACtB;AACA,MAAI,CAAC,MAAM,QAAQ,CAAC,GAAG;AACnB,YAAQ,MAAM,iBAAiB,CAAC;AAChC,WAAO,CAAC;AAAA,EACZ;AACA,SAAO;AACX;;;ACnBe,SAAR,cAA+B,IAAI;AACtC,QAAM,OAAO,GAAG,sBAAsB;AACtC,QAAM,aAAa,OAAO,eAAe,SAAS,gBAAgB;AAClE,QAAM,YAAY,OAAO,eAAe,SAAS,gBAAgB;AACjE,SAAO,EAAE,KAAK,KAAK,MAAM,WAAW,MAAM,KAAK,OAAO,WAAW;AACrE;;;ACHe,SAAR,YAA6B,KAAK,MAAM;AAC3C,SAAO,IAAI,QAAQ,iBAAiB,CAAC,IAAI,OAAO,KAAK,EAAE,CAAC;AAC5D;;;ACRA,IAAI;AAWW,SAAR,aAA8B,MAAM,KAAK,SAAS,MAAM,cAAc,OAAO;AAChF,QAAM,SAAS,OAAO,iBAAiB,MAAM,SAAS,cAAc,KAAK,CAAC;AAC1E,QAAM,aAAa,OAAO,iBAAiB,aAAa,KAAK;AAC7D,QAAM,WAAW,OAAO,iBAAiB,WAAW,KAAK;AACzD,QAAM,aAAa,OAAO,iBAAiB,aAAa,KAAK;AAE7D,MAAI,UAAU;AACd,MAAI,aAAa;AACb,UAAM,cAAc,OAAO,iBAAiB,cAAc,KAAK;AAC/D,UAAM,eAAe,OAAO,iBAAiB,eAAe,KAAK;AACjE,cAAU,OAAO,SAAS,WAAW,IAAI,OAAO,SAAS,YAAY;AAAA,EACzE;AAGA,MAAI,CAAC,QAAQ;AACT,aAAS,SAAS,cAAc,QAAQ;AAAA,EAC5C;AACA,QAAM,UAAU,OAAO,WAAW,IAAI;AACtC,UAAQ,OAAO,GAAG,UAAU,IAAI,QAAQ,IAAI,UAAU;AACtD,QAAM,UAAU,QAAQ,YAAY,IAAI;AACxC,SAAO,OAAO,SAAS,QAAQ,KAAK,IAAI;AAC5C;;;AC5Be,SAAR,QAAyB,QAAQ;AACpC,SAAO,KAAK,OAAO,EACd,SAAS,EAAE,EACX,QAAQ,MAAM,UAAU,EAAE;AACnC;;;ACEe,SAAR,SAA0B,SAAS,UAAU,KAAK;AACrD,MAAI,QAAQ;AACZ,SAAO,IAAI,SAAS;AAChB,iBAAa,KAAK;AAClB,YAAQ,WAAW,MAAM;AACrB,cAAQ;AACR,cAAQ,GAAG,IAAI;AAAA,IACnB,GAAG,OAAO;AAAA,EACd;AACJ;;;AC2JA,IAAI,UAAU,CAAC;AAKf,IAAI,SAAS;AAAA,EACT,cAAc;AAAA,EACd,UAAU;AAAA,EACV,eAAe;AAAA,EACf,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc;AAClB;AAOA,SAAS,sBAAsB,IAAI,QAAQ;AACvC,MAAI,OAAO,OAAO;AACd,iBAAa,IAAI,SAAS,OAAO,KAAK;AAAA,EAC1C;AACA,MAAI,OAAO,OAAO;AACd,aAAS,IAAI,OAAO,KAAK;AAAA,EAC7B;AACA,MAAI,OAAO,QAAQ;AACf,iBAAa,IAAI,UAAU,EAAE;AAC7B,QAAI,OAAO,kBAAkB;AACzB,eAAS,IAAI,sBAAsB;AAAA,IACvC;AAAA,EACJ;AACJ;AAIA,IAAM,WAAN,MAAM,kBAAiB,qBAAY;AAAA,EAC/B,kBAAkB;AAAA,EAClB,8BAA8B;AAAA,EAC9B,gBAAgB;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EAEA,SAAS;AACL,iBAAa,MAAM,MAAM,KAAK,QAAQ,MAAM,QAAQ,KAAK,GAAG,IAAI;AAMhE,SAAK,OAAO,CAAC;AAKb,SAAK;AAML,SAAK,UAAU,KAAK,WAAW,KAAK;AACpC,QAAI,KAAK,QAAQ,aAAc,MAAK,QAAQ,aAAa;AAGzD,SAAK,aAAa;AAClB,SAAK,OAAO,KAAK,QAAQ,eAAe;AACxC,SAAK,QAAQ;AACb,SAAK;AAIL,SAAK,UAAU,CAAC;AAEhB,eAAW,CAAC,YAAY,WAAW,KAAK,OAAO,QAAQ,OAAO,GAAG;AAE7D,WAAK,QAAQ,UAAU,IAAI,IAAI,YAAY,IAAI;AAAA,IACnD;AAIA,eAAW,QAAQ,UAAS,oBAAoB;AAC5C,UAAI,KAAK,QAAQ,OAAO,MAAM,GAAG;AAC7B,qBAAa,MAAM,MAAM,KAAK,QAAQ,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;AAAA,MAClE;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,OAAO,WAAW;AACd,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAM0B,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mEAMa,OAAO,YAAY;AAAA;AAAA;AAAA,gFAGN,OAAO,aAAa,iBAAiB,OAAO,aAAa;AAAA;AAAA;AAAA,+EAG1D,OAAO,YAAY,iBAAiB,OAAO,YAAY;AAAA;AAAA;AAAA,sGAGhC,OAAO,QAAQ;AAAA,qEAChD,OAAO,YAAY,iBAAiB,OAAO,YAAY;AAAA;AAAA;AAAA,qEAGvD,OAAO,YAAY,iBAAiB,OAAO,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,mFAKzC,OAAO,EAAE,oCAAoC,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASxI;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAS;AACT,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,YAAY;AACf,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAAU,GAAG;AAChB,aAAS,OAAO,OAAO,QAAQ,CAAC;AAAA,EACpC;AAAA;AAAA,EAGA,IAAI,SAAS;AACT,WAAO,KAAK,QAAQ,UAAU,KAAK,OAAO;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAO;AACd,QAAI,CAAC,KAAK,gBAAgB,MAAM,aAAa,YAAY,MAAM,KAAK,QAAQ;AACxE,YAAM,aAAa,cAAc,KAAK,MAAM;AAAA,IAChD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,gBAAgB;AAChB,WAAO;AAAA,MACH,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,mBAAmB,EAAE,OAAO,IAAI,MAAM,GAAG;AAAA,IAC7C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,iBAAiB;AACjB,WAAO;AAAA,MACH,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,cAAc;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,SAAS;AAAA,QACT,cAAc;AAAA,QACd,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,WAAW;AAAA,MACf;AAAA,MACA,aAAa;AAAA,MACb,SAAS;AAAA,MACT,KAAK;AAAA,MACL,eAAe,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG;AAAA,MACpC,aAAa;AAAA,MACb,SAAS,CAAC;AAAA,MACV,SAAS,CAAC;AAAA,MACV,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,aAAa;AAAA,MACb,WAAW;AAAA,MACX,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,cAAc;AAAA,MACd,WAAW;AAAA,MACX,cAAc;AAAA,MACd,QAAQ;AAAA,IACZ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,SAAS;AACT,WAAO,KAAK,UAAU,SAAS,gBAAgB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,eAAe;AACf,WAAO,KAAK,UAAU,SAAS,kBAAkB;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,gBAAgB,MAAM;AACzB,cAAU;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,kBAAkB,SAAS,MAAM;AACpC,QAAI,WAAW,MAAM;AACjB,gBAAU,CAAC;AAAA,IACf,OAAO;AACH,aAAO,QAAQ,MAAM;AAAA,IACzB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,oBAAoB;AACvB,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe,SAAS;AACpB,UAAM,OAAO,CAAC;AAEd,QAAI,OAAO,YAAY,YAAY,CAAC,MAAM,QAAQ,OAAO,GAAG;AACxD,iBAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACpC,cAAM,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,aAAa;AAChD,YAAI,QAAQ,QAAQ,GAAG;AACvB,YAAI,QAAQ;AACZ,aAAK,KAAK,GAAG;AAAA,MACjB;AAAA,IACJ,OAAO;AACH,iBAAW,QAAQ,SAAS;AACxB,YAAI,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,aAAa;AAC9C,YAAI,OAAO,SAAS,UAAU;AAC1B,cAAI,QAAQ;AACZ,cAAI,QAAQ;AAAA,QAChB,WAAW,OAAO,SAAS,UAAU;AACjC,gBAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,cAAI,CAAC,IAAI,OAAO;AACZ,oBAAQ,MAAM,6BAA6B,IAAI;AAAA,UACnD;AACA,cAAI,CAAC,IAAI,OAAO;AACZ,gBAAI,QAAQ,IAAI;AAAA,UACpB;AAAA,QACJ,OAAO;AACH,kBAAQ,MAAM,iDAAiD;AAAA,QACnE;AACA,aAAK,KAAK,GAAG;AAAA,MACjB;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,qBAAqB;AAC5B,WAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,IAAI,sBAAsB;AACtB,WAAO;AAAA,MACH,SAAS,CAAC,MAAM,KAAK,eAAe,aAAa,CAAC,CAAC;AAAA,MACnD,SAAS,CAAC,MAAM,aAAa,CAAC;AAAA,MAC9B,aAAa,CAAC,MAAM,OAAO,SAAS,CAAC;AAAA,MACrC,SAAS,CAAC,MAAM,OAAO,SAAS,CAAC;AAAA,IACrC;AAAA,EACJ;AAAA;AAAA,EAGA,IAAI,QAAQ;AAER,WAAO,EAAE,SAAS,IAAI;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAI,QAAQ;AAER,WAAO,EAAE,SAAS,IAAI;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAI,QAAQ;AAER,WAAO,EAAE,SAAS,IAAI;AAAA,EAC1B;AAAA,EAEA,IAAI,OAAO;AACP,WAAO,OAAO,SAAS,KAAK,aAAa,MAAM,CAAC;AAAA,EACpD;AAAA,EAEA,IAAI,KAAK,KAAK;AACV,iBAAa,MAAM,QAAQ,KAAK,mBAAmB,GAAG,CAAC;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,WAAW,OAAO;AACzB,QAAI,YAAY,CAAC,KAAK,OAAQ,QAAO;AACrC,SAAK,SAAS;AACd,WAAO,KAAK,SAAS,EAAE,KAAK,MAAM,KAAK,YAAY,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW;AACP,UAAM,OAAO,KAAK,QAAQ;AAC1B,SAAK,QAAQ,UAAU,CAAC;AACxB,SAAK,YAAY;AACjB,WAAO,KAAK,QAAQ,UAAU,MAAM;AAAA,EACxC;AAAA,EAEA,mBAAmB,GAAG;AAClB,QAAI,KAAK;AACT,QAAI,KAAK,QAAQ,IAAI;AACjB,WAAK,KAAK;AAAA,IACd;AACA,QAAI,KAAK,KAAK,CAAC,IAAI;AACf,WAAK;AAAA,IACT;AACA,WAAO;AAAA,EACX;AAAA,EAEA,UAAU;AACN,QAAI,CAAC,KAAK,UAAW,QAAO;AAC5B,SAAK,QAAQ,KAAK,WAAW;AAC7B,SAAK,OAAO,KAAK,mBAAmB,KAAK,IAAI;AAG7C,iBAAa,KAAK,WAAW,OAAO,KAAK,KAAK;AAC9C,SAAK,UAAU,QAAQ,GAAG,KAAK,IAAI;AACnC,WAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,GAAG;AAAA,EACrD;AAAA,EAEA,cAAc;AACV,SAAK,OAAO;AAAA,EAChB;AAAA,EAEA,oBAAoB;AAChB,QAAI,CAAC,KAAK,QAAQ,gBAAgB;AAC9B;AAAA,IACJ;AACA,QAAI,KAAK,QAAQ,YAAY;AACzB,WAAK,QAAQ,eAAe,QAAQ;AAAA,IACxC,OAAO;AACH,WAAK,QAAQ,eAAe,UAAU;AAAA,IAC1C;AAAA,EACJ;AAAA,EAEA,cAAc;AACV,SAAK,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB;AACZ,SAAK,QAAQ,UAAU,OAAO,SAAS,KAAK,cAAc,QAAQ,KAAK,cAAc,aAAa,EAAE,KAAK;AACzG,SAAK,eAAe;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB;AAEb,QACI,KAAK,QAAQ,YAAY,OAAO,SAAS,KAAK,cAAc,QAAQ,KAAK,cAAc,aAAa,EAAE,KAAK,GAC7G;AACE,WAAK,qBAAqB;AAAA,IAC9B;AAEA,QAAI,aAAa,KAAK;AACtB,WAAO,aAAa,KAAK,KAAK,OAAO,KAAK,QAAQ,UAAU,KAAK,aAAa,GAAG;AAC7E;AAAA,IACJ;AACA,QAAI,eAAe,KAAK,MAAM;AAE1B,WAAK,OAAO;AAAA,IAChB,OAAO;AAEH,WAAK,OAAO,MAAM;AAEd,YAAI,CAAC,KAAK,QAAQ,eAAe,CAAC,KAAK,QAAQ,YAAY,gBAAgB;AACvE,eAAK,cAAc,eAAe;AAAA,QACtC;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EAEA,aAAa;AACT,iBAAa,MAAM,OAAO,KAAK,QAAQ,GAAG;AAAA,EAC9C;AAAA,EAEA,qBAAqB;AACjB,SAAK,YAAY;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB;AACnB,QAAI,CAAC,KAAK,eAAe;AACrB;AAAA,IACJ;AACA,WAAO,KAAK,cAAc,WAAW;AACjC,WAAK,cAAc,YAAY,KAAK,cAAc,SAAS;AAAA,IAC/D;AACA,eAAW,KAAK,KAAK,QAAQ,eAAe;AACxC,sBAAgB,KAAK,eAAe,GAAG,GAAG,MAAM,KAAK,QAAQ,OAAO;AAAA,IACxE;AAAA,EACJ;AAAA,EAEA,MAAM,aAAa;AAIf,SAAK,QAAQ,KAAK,cAAc,OAAO;AAIvC,SAAK,WAAW,KAAK,cAAc,eAAe;AAIlD,SAAK,UAAU,KAAK,cAAc,cAAc;AAIhD,SAAK,UAAU,KAAK,cAAc,cAAc;AAIhD,SAAK,UAAU,KAAK,cAAc,cAAc;AAIhD,SAAK,gBAAgB,KAAK,cAAc,qBAAqB;AAI7D,SAAK,YAAY,KAAK,cAAc,gBAAgB;AAEpD,SAAK,WAAW,KAAK,SAAS,KAAK,IAAI;AACvC,SAAK,UAAU,KAAK,QAAQ,KAAK,IAAI;AACrC,SAAK,UAAU,KAAK,QAAQ,KAAK,IAAI;AACrC,SAAK,UAAU,KAAK,QAAQ,KAAK,IAAI;AACrC,SAAK,gBAAgB,KAAK,cAAc,KAAK,IAAI;AACjD,SAAK,WAAW,KAAK,SAAS,KAAK,IAAI;AAEvC,SAAK,SAAS,iBAAiB,SAAS,KAAK,QAAQ;AACrD,SAAK,QAAQ,iBAAiB,SAAS,KAAK,OAAO;AACnD,SAAK,QAAQ,iBAAiB,SAAS,KAAK,OAAO;AACnD,SAAK,QAAQ,iBAAiB,SAAS,KAAK,OAAO;AACnD,SAAK,cAAc,iBAAiB,UAAU,KAAK,aAAa;AAChE,SAAK,cAAc,gBAAgB,UAAU,KAAK,QAAQ,WAAW;AACrE,SAAK,UAAU,iBAAiB,SAAS,KAAK,QAAQ;AAEtD,eAAW,UAAU,OAAO,OAAO,KAAK,OAAO,GAAG;AAC9C,YAAM,OAAO,UAAU;AAAA,IAC3B;AAGA,SAAK,WAAW;AAChB,SAAK,qBAAqB;AAE1B,UAAM,KAAK,KAAK;AAAA,EACpB;AAAA,EAEA,gBAAgB;AACZ,SAAK,UAAU,oBAAoB,SAAS,KAAK,QAAQ;AACzD,SAAK,SAAS,oBAAoB,SAAS,KAAK,OAAO;AACvD,SAAK,SAAS,oBAAoB,SAAS,KAAK,OAAO;AACvD,SAAK,SAAS,oBAAoB,SAAS,KAAK,OAAO;AACvD,SAAK,eAAe,oBAAoB,UAAU,KAAK,aAAa;AACpE,SAAK,WAAW,oBAAoB,SAAS,KAAK,QAAQ;AAE1D,eAAW,UAAU,OAAO,OAAO,KAAK,OAAO,GAAG;AAC9C,aAAO,aAAa;AAAA,IACxB;AAAA,EACJ;AAAA,EAEA,OAAO;AACH,WAAO,KAAK,SAAS,EAAE,QAAQ,MAAM;AACjC,WAAK,YAAY;AAEjB,WAAK,YAAY;AACjB,WAAK,UAAU,IAAI,gBAAgB;AAEnC,WAAK,cAAc;AACnB,WAAK,eAAe;AAEpB,WAAK,WAAW;AAChB,WAAK,qBAAqB;AAC1B,WAAK,YAAY;AAEjB,WAAK,aAAa;AAElB,WAAK,IAAI,aAAa;AAAA,IAC1B,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,OAAO;AACV,QAAI,QAAQ;AAEZ,eAAW,OAAO,KAAK,QAAQ,SAAS;AACpC,UAAI,IAAI,UAAU,OAAO;AACrB,gBAAQ;AAAA,MACZ;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,WAAW,OAAO,MAAM;AACpB,UAAM,IAAI,KAAK,OAAO,KAAK;AAC3B,WAAO,IAAI,EAAE,IAAI,IAAI;AAAA,EACzB;AAAA,EAEA,WAAW,OAAO,MAAM,KAAK;AACzB,UAAM,IAAI,KAAK,OAAO,KAAK;AAC3B,QAAI,GAAG;AACH,QAAE,IAAI,IAAI;AAAA,IACd;AAAA,EACJ;AAAA,EAEA,iBAAiB;AACb,WAAO,KAAK,QAAQ,QAAQ,OAAO,CAAC,QAAQ;AACxC,aAAO,CAAC,IAAI;AAAA,IAChB,CAAC;AAAA,EACL;AAAA,EAEA,gBAAgB;AACZ,WAAO,KAAK,QAAQ,QAAQ,OAAO,CAAC,QAAQ;AACxC,aAAO,IAAI,WAAW;AAAA,IAC1B,CAAC;AAAA,EACL;AAAA,EAEA,WAAW,OAAO,SAAS,MAAM;AAC7B,SAAK,WAAW,OAAO,UAAU,KAAK;AAGtC,QAAI,OAAQ,MAAK,YAAY;AAE7B,aAAS,MAAM,oBAAoB;AAAA,MAC/B,KAAK;AAAA,MACL,YAAY;AAAA,IAChB,CAAC;AAAA,EACL;AAAA,EAEA,WAAW,OAAO,SAAS,MAAM;AAC7B,SAAK,WAAW,OAAO,UAAU,IAAI;AAGrC,QAAI,OAAQ,MAAK,YAAY;AAE7B,aAAS,MAAM,oBAAoB;AAAA,MAC/B,KAAK;AAAA,MACL,YAAY;AAAA,IAChB,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB;AACZ,QAAI,QAAQ;AACZ,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB;AACxD;AAAA,IACJ;AACA,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,kBAAkB,KAAK,QAAQ,eAAe,iBAAiB,GAAG;AAC1G;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW;AACP,WAAO,KAAK,aAAa,QAAQ;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,cAAc,OAAO;AAC/B,QAAI,MAAM;AAEV,eAAW,OAAO,KAAK,QAAQ,SAAS;AACpC,UAAI,eAAe,IAAI,QAAQ;AAC3B;AAAA,MACJ;AACA,UAAI,CAAC,IAAI,MAAM;AACX;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB;AACxD;AAAA,IACJ;AAEA,QAAI,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,YAAY;AACxD;AAAA,IACJ;AAEA,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,kBAAkB,KAAK,QAAQ,eAAe,iBAAiB,GAAG;AAC1G;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc;AACV,QAAI,CAAC,KAAK,MAAO,QAAO;AACxB,SAAK,MAAM,MAAM,aAAa;AAC9B,SAAK,YAAY;AACjB,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB;AAAA,IAE5D,OAAO;AACH,WAAK,MAAM,MAAM,aAAa;AAAA,IAClC;AAGA,QAAI,CAAC,KAAK,WAAW;AACjB,YAAM,KAAK,KAAK,MAAM,UAAU,KAAK,KAAK,MAAM,UAAU;AAC1D,UAAI,IAAI;AACJ,aAAK,YAAY,GAAG;AAAA,MACxB;AAAA,IACJ;AACA,SAAK,WAAW,KAAK,KAAK;AAC1B,WAAO,KAAK,QAAQ;AAAA,EACxB;AAAA,EAEA,gBAAgB;AACZ,UAAM,MAAM,KAAK,cAAc,0BAA0B;AACzD,QAAI,KAAK,QAAQ,QAAQ;AACrB,sBAAgB,KAAK,QAAQ;AAAA,IACjC,OAAO;AACH,WAAK,aAAa;AAClB,mBAAa,KAAK,UAAU,EAAE;AAAA,IAClC;AAAA,EACJ;AAAA,EAEA,iBAAiB;AACb,UAAM,UAAU,QAAQ,MAAM,6BAA6B;AAC3D,eAAW,MAAM,SAAS;AACtB,UAAI,GAAG,UAAU,SAAS,eAAe,KAAK,GAAG,UAAU,SAAS,YAAY,GAAG;AAC/E;AAAA,MACJ;AACA,UAAI,KAAK,QAAQ,WAAW,KAAK,QAAQ,kBAAkB;AACvD,WAAG,YAAY;AAAA,MACnB,OAAO;AACH,WAAG,gBAAgB,WAAW;AAAA,MAClC;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,cAAc;AACV,SAAK,IAAI,aAAa;AAEtB,UAAM,UAAU,QAAQ,MAAM,6BAA6B;AAC3D,eAAW,MAAM,SAAS;AACtB,YAAM,YAAY,GAAG,aAAa,OAAO;AACzC,UACI,GAAG,UAAU,SAAS,iBAAiB,KACtC,CAAC,KAAK,cAAc,cAAc,KAAK,QAAQ,aAClD;AACE;AAAA,MACJ;AACA,UAAI,KAAK,QAAQ,QAAQ,CAAC,KAAK,WAAW,WAAW,QAAQ,GAAG;AAC5D,qBAAa,IAAI,aAAa,MAAM;AAAA,MACxC,OAAO;AACH,wBAAgB,IAAI,WAAW;AAAA,MACnC;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,oBAAoB;AAChB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,OAAO,KAAK;AACR,QAAI,CAAC,MAAM,QAAQ,KAAK,YAAY,GAAG;AACnC;AAAA,IACJ;AACA,SAAK,IAAI,SAAS;AAClB,SAAK,aAAa,KAAK,GAAG;AAC1B,SAAK,OAAO,KAAK,aAAa,MAAM;AACpC,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,QAAQ,MAAM,MAAM,MAAM;AAChC,QAAI,CAAC,MAAM,QAAQ,KAAK,YAAY,GAAG;AACnC;AAAA,IACJ;AAEA,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,MAAM,MAAM;AACZ,UAAI,KAAK,QAAQ,QAAQ,CAAC,EAAE;AAAA,IAChC;AACA,QAAI,MAAM,MAAM;AACZ,UAAI,KAAK,aAAa,KAAK,aAAa,SAAS,CAAC,EAAE,CAAC;AAAA,IACzD;AACA,SAAK,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE;AAC/B,aAAS,IAAI,GAAG,IAAI,KAAK,aAAa,QAAQ,KAAK;AAC/C,UAAI,KAAK,aAAa,CAAC,EAAE,CAAC,MAAM,GAAG;AAC/B,aAAK,aAAa,OAAO,GAAG,CAAC;AAC7B;AAAA,MACJ;AAAA,IACJ;AACA,SAAK,OAAO,KAAK,aAAa,MAAM;AACpC,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,gBAAgB,MAAM;AAClB,QAAI,CAAC,KAAK,QAAQ,gBAAgB;AAC9B,aAAO,CAAC;AAAA,IACZ;AACA,WAAO,KAAK,QAAQ,eAAe,aAAa,GAAG,IAAI;AAAA,EAC3D;AAAA,EAEA,UAAU;AACN,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAAU,QAAQ,OAAO;AAErB,QAAI,CAAC,SAAS,KAAK,KAAK,WAAW,GAAG;AAClC;AAAA,IACJ;AACA,SAAK,UAAU,OAAO,YAAY,kBAAkB;AACpD,SAAK,OAAO,aAAa,cAAc,KAAK,MAAM;AAClD,SAAK,OAAO,KAAK,eAAe,CAAC;AACjC,SAAK,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,MAAM;AACV,UAAM,UAAU,KAAK,QAAQ,aAAa;AAC1C,UAAM,UAAU,KAAK,QAAQ,aAAa;AAC1C,QAAI,OAAO,OAAO,GAAG;AACjB,WAAK,OAAO,KAAK,OAAO;AAAA,IAC5B;AACA,QAAI,OAAO,OAAO,GAAG;AACjB,WAAK,OAAO,KAAK,eAAe,KAAK,OAAO;AAAA,IAChD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,gBAAgB,MAAM;AAC1B,SAAK,OAAO,KAAK,eAAe,CAAC;AACjC,WAAO,KAAK,OAAO,aAAa;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,gBAAgB,MAAM;AACzB,SAAK,IAAI,QAAQ;AACjB,QAAI,OAAO,kBAAkB,UAAU;AACnC,WAAK,QAAQ,MAAM;AAAA,IACvB;AAEA,UAAM,aAAa,CAAC,KAAK,cAAc;AACvC,SAAK,QAAQ;AAEb,WAAO,KAAK,SAAS,EAAE,QAAQ,MAAM;AACjC,UAAI,KAAK,aAAc;AAGvB,WAAK,QAAQ,UAAU,aAAa,KAAK,WAAW,IAAI,KAAK,SAAS;AACtE,UAAI,OAAO,kBAAkB,YAAY;AACrC,sBAAc;AAAA,MAClB;AAAA,IACJ,CAAC,EAAE,KAAK,MAAM,IAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW;AACP,UAAM,YAAY,MAAM,CAAC,KAAK,KAAK,UAAU,KAAK,UAAU,IAAI,UAAU;AAC1E,UAAM,QAAQ,KAAK;AAGnB,QAAI,KAAK,QAAQ,KAAK,gBAAgB,KAAK,QAAQ;AAE/C,UAAI,CAAC,KAAK,QAAQ,UAAW,KAAK,QAAQ,UAAU,CAAC,KAAK,YAAa;AACnE,aAAK,IAAI,eAAe;AACxB,kBAAU;AACV,eAAO,IAAI,QAAQ,CAAC,YAAY;AAC5B,kBAAQ;AAAA,QACZ,CAAC;AAAA,MACL;AAAA,IACJ;AACA,SAAK,IAAI,UAAU;AACnB,SAAK,UAAU;AACf,SAAK,UAAU,IAAI,YAAY;AAC/B,SAAK,UAAU,OAAO,YAAY,kBAAkB;AACpD,WACI,KAAK,UAAU,EACV,KAAK,CAAC,aAAa;AAEhB,UAAI,MAAM,QAAQ,QAAQ,GAAG;AACzB,aAAK,OAAO;AAAA,MAChB,OAAO;AAEH,YAAI,CAAC,SAAS,KAAK,QAAQ,aAAa,OAAO,GAAG;AAC9C,kBAAQ;AAAA,YACJ;AAAA,YACA;AAAA,UACJ;AACA,eAAK,QAAQ,MAAM;AACnB;AAAA,QACJ;AAGA,aAAK,UAAU,OAAO;AAAA,UAClB,KAAK;AAAA,UACL,SAAS,KAAK,QAAQ,aAAa,UAAU,KAAK,CAAC;AAAA,QACvD;AAEA,aAAK,OAAO,SAAS,KAAK,QAAQ,aAAa,OAAO,KAAK,CAAC;AAC5D,aAAK,OAAO,SAAS,KAAK,QAAQ,aAAa,OAAO;AAAA,MAC1D;AACA,WAAK,eAAe,KAAK,KAAK,MAAM;AACpC,WAAK,QAAQ;AAGb,UAAI,KAAK,QAAQ,QAAQ,WAAW,KAAK,KAAK,aAAa,QAAQ;AAC/D,aAAK,QAAQ,UAAU,KAAK,eAAe,OAAO,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC;AAAA,MAChF,OAAO;AACH,aAAK,QAAQ,UAAU,KAAK,eAAe,KAAK,QAAQ,OAAO;AAAA,MACnE;AAAA,IACJ,CAAC,EACA,MAAM,CAAC,QAAQ;AACZ,WAAK,IAAI,GAAG;AACZ,YAAM;AAAA,QACF;AAAA,QACA,KAAK,QAAQ,gBACT,IAAI,SAAS,QAAQ,qBAAqB,EAAE,KAC5C,OAAO;AAAA,MACf;AACA,WAAK,UAAU,IAAI,YAAY,kBAAkB;AACjD,eAAS,MAAM,kBAAkB,GAAG;AAAA,IACxC,CAAC,EAEA,QAAQ,MAAM;AACX,gBAAU;AACV,WAAK,WAAW,KAAK;AACrB,WAAK,UAAU,OAAO,YAAY;AAClC,mBAAa,KAAK,OAAO,iBAAiB,KAAK,KAAK,MAAM;AAC1D,WAAK,UAAU;AAAA,IACnB,CAAC;AAAA,EAEb;AAAA,EAEA,WAAW;AACP,QAAI,KAAK,SAAS;AACd;AAAA,IACJ;AACA,SAAK,OAAO;AAAA,EAChB;AAAA,EAEA,UAAU;AACN,QAAI,KAAK,SAAS;AACd;AAAA,IACJ;AACA,SAAK,OAAO,KAAK;AAAA,EACrB;AAAA,EAEA,UAAU;AACN,QAAI,KAAK,SAAS;AACd;AAAA,IACJ;AACA,SAAK,OAAO,KAAK,OAAO;AAAA,EAC5B;AAAA,EAEA,UAAU;AACN,QAAI,KAAK,SAAS;AACd;AAAA,IACJ;AACA,SAAK,OAAO,KAAK,OAAO;AAAA,EAC5B;AAAA,EAEA,SAAS,OAAO;AACZ,QAAI,MAAM,SAAS,YAAY;AAC3B,YAAM,MAAM,MAAM,WAAW,MAAM;AACnC,UAAI,QAAQ,MAAM,QAAQ,SAAS;AAC/B,cAAM,eAAe;AAAA,MACzB,OAAO;AACH;AAAA,MACJ;AAAA,IACJ;AACA,SAAK,OAAO,OAAO,SAAS,KAAK,UAAU,KAAK;AAAA,EACpD;AAAA,EAEA,UAAU;AACN,UAAM,MAAM,KAAK,cAAc,oDAAoD;AACnF,QAAI,KAAK;AACL,aAAO,IAAI,aAAa,OAAO;AAAA,IACnC;AACA,WAAO,KAAK,QAAQ;AAAA,EACxB;AAAA,EAEA,aAAa;AACT,UAAM,MAAM,KAAK,cAAc,oDAAoD;AACnF,QAAI,KAAK;AACL,aAAO,IAAI,aAAa,WAAW,KAAK;AAAA,IAC5C;AACA,WAAO;AAAA,EACX;AAAA,EAEA,aAAa;AACT,UAAM,UAAU,CAAC;AACjB,UAAM,SAAS,QAAQ,MAAM,KAAK,eAAe;AACjD,eAAW,SAAS,QAAQ;AACxB,cAAQ,MAAM,QAAQ,IAAI,IAAI,MAAM;AAAA,IACxC;AACA,WAAO;AAAA,EACX;AAAA,EAEA,eAAe;AACX,UAAM,SAAS,QAAQ,MAAM,KAAK,eAAe;AACjD,eAAW,SAAS,QAAQ;AACxB,YAAM,QAAQ;AAAA,IAClB;AACA,SAAK,WAAW;AAAA,EACpB;AAAA,EAEA,aAAa;AACT,SAAK,IAAI,aAAa;AAEtB,SAAK,OAAO;AAEZ,QAAI,KAAK,QAAQ,QAAQ;AACrB,WAAK,OAAO;AAAA,IAChB,OAAO;AACH,WAAK,OAAO,KAAK,cAAc,MAAM,KAAK,CAAC;AAG3C,YAAM,SAAS,QAAQ,MAAM,KAAK,eAAe;AACjD,iBAAW,SAAS,QAAQ;AACxB,cAAM,QAAQ,MAAM;AACpB,YAAI,OAAO;AACP,gBAAM,OAAO,MAAM,QAAQ;AAC3B,eAAK,OAAO,KAAK,KAAK,OAAO,CAAC,SAAS;AACnC,kBAAM,MAAM,GAAG,KAAK,IAAI,CAAC;AACzB,mBAAO,IAAI,YAAY,EAAE,QAAQ,MAAM,YAAY,CAAC,MAAM;AAAA,UAC9D,CAAC;AAAA,QACL;AAAA,MACJ;AACA,WAAK,YAAY;AAEjB,YAAM,MAAM,KAAK,cAAc,oDAAoD;AACnF,UAAI,KAAK,QAAQ,QAAQ,KAAK;AAC1B,aAAK,SAAS;AAAA,MAClB,OAAO;AACH,aAAK,WAAW;AAAA,MACpB;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,UAAU,MAAM;AACrB,SAAK,IAAI,WAAW;AAEpB,QAAI,MAAM;AAGV,QAAI,OAAO,KAAK,WAAW,IAAI,aAAa,OAAO,GAAG,QAAQ,GAAG;AAC7D,WAAK,IAAI,kDAAkD;AAC3D;AAAA,IACJ;AACA,QAAI,KAAK,QAAQ,eAAe,YAAY;AACxC,WAAK,IAAI,oCAAoC;AAC7C;AAAA,IACJ;AACA,QAAI,KAAK,SAAS;AACd,WAAK,IAAI,mCAAmC;AAC5C;AAAA,IACJ;AAGA,QAAI,QAAQ,MAAM;AAEd,YAAM,cAAc,CAAC,MAAM,CAAC,iBAAiB,cAAc,sBAAsB,EAAE,SAAS,CAAC;AAE7F,YAAM,UAAU,QAAQ,MAAM,yBAAyB;AACvD,iBAAW,MAAM,SAAS;AAEtB,YAAI,CAAC,GAAG,GAAG,SAAS,EAAE,KAAK,WAAW,KAAK,CAAC,GAAG,aAAa,WAAW,GAAG;AACtE;AAAA,QACJ;AACA,YAAI,OAAO,KAAK;AACZ,aAAG,aAAa,aAAa,MAAM;AAAA,QACvC;AAAA,MACJ;AAGA,UAAI,CAAC,IAAI,aAAa,WAAW,KAAK,IAAI,aAAa,WAAW,MAAM,QAAQ;AAC5E,YAAI,aAAa,aAAa,WAAW;AAAA,MAC7C,WAAW,IAAI,aAAa,WAAW,MAAM,aAAa;AACtD,YAAI,aAAa,aAAa,YAAY;AAAA,MAC9C,WAAW,IAAI,aAAa,WAAW,MAAM,cAAc;AACvD,YAAI,aAAa,aAAa,MAAM;AAAA,MACxC;AAAA,IACJ,OAAO;AAEH,YAAM,KAAK,cAAc,oDAAoD;AAAA,IACjF;AAEA,QAAI,KAAK,QAAQ,QAAQ;AAErB,WAAK,SAAS,EAAE,QAAQ,MAAM;AAC1B,aAAK,WAAW;AAAA,MACpB,CAAC;AAAA,IACL,OAAO;AACH,YAAM,OAAO,MAAM,IAAI,aAAa,WAAW,IAAI;AACnD,UAAI,SAAS,QAAQ;AACjB,cAAM,QAAQ,CAAC;AAGf,aAAK,cAAc,KAAK,CAAC,UAAU;AAC/B,eAAK,KAAK,KAAK,CAAC,UAAU;AACtB,gBAAI,KAAK,UAAU,KAAK,MAAM,KAAK,UAAU,KAAK,GAAG;AACjD,oBAAM,KAAK,KAAK;AAChB,qBAAO;AAAA,YACX;AACA,mBAAO;AAAA,UACX,CAAC;AACD,iBAAO,MAAM,WAAW,KAAK,KAAK;AAAA,QACtC,CAAC;AAED,aAAK,OAAO;AAAA,MAChB,OAAO;AACH,cAAM,QAAQ,IAAI,aAAa,OAAO;AACtC,aAAK,KAAK,KAAK,CAAC,GAAG,MAAM;AACrB,cAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG;AACtC,mBAAO,SAAS,cAAc,EAAE,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,KAAK;AAAA,UAC1E;AACA,gBAAM,OAAO,SAAS,cAAc,EAAE,KAAK,EAAE,YAAY,IAAI,EAAE,KAAK,EAAE,YAAY;AAClF,gBAAM,OAAO,SAAS,cAAc,EAAE,KAAK,EAAE,YAAY,IAAI,EAAE,KAAK,EAAE,YAAY;AAElF,kBAAQ,MAAM;AAAA,YACV,KAAK,OAAO;AACR,qBAAO;AAAA,YACX,KAAK,OAAO;AACR,qBAAO;AAAA,YACX,KAAK,SAAS;AACV,qBAAO;AAAA,UACf;AAAA,QACJ,CAAC;AAAA,MACL;AACA,WAAK,WAAW;AAAA,IACpB;AAAA,EACJ;AAAA,EAEA,MAAM,YAAY,SAAS;AACvB,UAAM,MAAM,KAAK,cAAc,6BAA6B,UAAU,GAAG;AACzE,UAAM,MAAM,YAAY,cAAc,SAAS,YAAY,eAAe,cAAc;AACxF,SAAK,aAAa,aAAa,GAAG;AAClC,SAAK,SAAS,GAAG;AAAA,EACrB;AAAA,EAEA,UAAU,CAAC,eAAe,KAAK,MAAM,YAAY,WAAW;AAAA,EAC5D,WAAW,CAAC,eAAe,KAAK,MAAM,YAAY,YAAY;AAAA,EAC9D,WAAW,CAAC,eAAe,KAAK,MAAM,YAAY,MAAM;AAAA,EAExD,YAAY;AACR,QAAI,CAAC,KAAK,QAAQ,KAAK;AACnB,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW,OAAO,YAAY,CAAC;AAAA,IAChE;AAEA,QAAI,OAAO,OAAO,SAAS;AAE3B,QAAI,CAAC,KAAK,MAAM,GAAG,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG;AACtC,cAAQ,KAAK,SAAS,GAAG,IAAI,KAAK;AAAA,IACtC;AACA,UAAM,MAAM,IAAI,IAAI,KAAK,QAAQ,KAAK,IAAI;AAC1C,QAAI,SAAS;AAAA,MACT,GAAG,KAAK,IAAI;AAAA,IAChB;AACA,QAAI,KAAK,QAAQ,QAAQ;AAErB,aAAO,KAAK,QAAQ,aAAa,KAAK,IAAI,KAAK,OAAO;AACtD,aAAO,KAAK,QAAQ,aAAa,MAAM,IAAI,KAAK,QAAQ;AACxD,UAAI,KAAK,QAAQ,OAAQ,QAAO,KAAK,QAAQ,aAAa,MAAM,IAAI,KAAK,WAAW;AACpF,aAAO,KAAK,QAAQ,aAAa,IAAI,IAAI,KAAK,QAAQ,KAAK;AAC3D,aAAO,KAAK,QAAQ,aAAa,OAAO,IAAI,KAAK,WAAW;AAG5D,UAAI,KAAK,OAAO,KAAK,QAAQ,aAAa,SAAS,GAAG;AAClD,iBAAS,OAAO,OAAO,QAAQ,KAAK,KAAK,KAAK,QAAQ,aAAa,SAAS,CAAC;AAAA,MACjF;AAAA,IACJ;AAEA,sBAAkB,KAAK,MAAM;AAE7B,WAAO,MAAM,GAAG,EAAE,KAAK,CAAC,aAAa;AACjC,YAAM,WAAW,IAAI,MAAM,SAAS,cAAc,OAAO,YAAY;AACrE,UAAI,CAAC,SAAS,IAAI;AAEd,iBAAS,WAAW;AACpB,cAAM;AAAA,MACV;AACA,aAAO,SACF,MAAM,EACN,KAAK,EACL,MAAM,CAAC,QAAQ;AACZ,YAAI,QAAQ;AACZ,YAAI,CAAC,KAAK,QAAQ,OAAO;AACrB,kBAAQ;AAAA,QACZ;AACA,cAAM,WAAW;AACjB,cAAM;AAAA,MACV,CAAC;AAAA,IACT,CAAC;AAAA,EACL;AAAA,EAEA,cAAc;AACV,SAAK,IAAI,cAAc;AAEvB,QAAI,KAAK,QAAQ,QAAQ,KAAK,QAAQ,aAAa;AAC/C,WAAK,QAAQ,YAAY,WAAW;AAAA,IACxC;AAEA,QAAI;AAEJ,SAAK,aAAa;AAClB,QAAI,KAAK,QAAQ,aAAa;AAE1B,qBAAe,KAAK,cAAc,sCAAsC,KAAK,QAAQ,WAAW,IAAI;AAAA,IACxG;AAEA,QAAI,cAAc;AACd,WAAK,SAAS,YAAY;AAAA,IAC9B,OAAO;AACH,WAAK,WAAW;AAAA,IACpB;AAEA,SAAK,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe;AACX,SAAK,IAAI,eAAe;AAExB,UAAM,QAAQ,KAAK;AACnB,SAAK,oBAAoB,KAAK;AAC9B,SAAK,oBAAoB,KAAK;AAE9B,QAAI,KAAK,QAAQ,aAAa,KAAK,QAAQ,eAAe;AACtD,WAAK,QAAQ,cAAc,cAAc,OAAO,YAAY;AAAA,IAChE;AAEA,aAAS,MAAM,gBAAgB;AAAA,EACnC;AAAA,EAEA,eAAe;AACX,SAAK,IAAI,eAAe;AAExB,UAAM,QAAQ,KAAK;AACnB,QAAI,CAAC,MAAO;AACZ,UAAM,KAAK,MAAM,cAAc,IAAI;AACnC,UAAM,gBAAgB,QAAQ;AAC9B,iBAAa,IAAI,WAAW,KAAK,cAAc,IAAI,CAAC;AACpD,UAAM,MAAM,UAAU;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oBAAoB,OAAO;AAEvB,UAAM,iBAAiB,KAAK;AAC5B,UAAM,cAAc,KAAK,MAAO,iBAAiB,KAAK,cAAc,IAAI,IAAK,CAAC;AAE9E,QAAI,MAAM;AACV,QAAI;AAGJ,SAAK,GAAG,IAAI;AACZ,SAAK,YAAY;AACjB,OAAG,aAAa,QAAQ,KAAK;AAC7B,OAAG,aAAa,iBAAiB,GAAG;AACpC,OAAG,aAAa,SAAS,iBAAiB;AAG1C,QAAI,WAAW,OAAO,cAAc,uBAAuB;AAC3D,SAAK,IAAI,kCAAkC,QAAQ;AACnD,QAAI,CAAC,UAAU;AACX,iBAAW,GAAG,IAAI;AAClB,aAAO,cAAc,IAAI,EAAE,YAAY,QAAQ;AAAA,IACnD;AAEA,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB;AACxD,WAAK,QAAQ,eAAe,gBAAgB,EAAE;AAAA,IAClD;AACA,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,kBAAkB,KAAK,QAAQ,eAAe,iBAAiB,GAAG;AAC1G,WAAK,QAAQ,eAAe,gBAAgB,EAAE;AAAA,IAClD;AAGA,UAAM;AACN,QAAI,aAAa;AACjB,SAAK,IAAI,iCAAiC,KAAK,QAAQ,OAAO;AAE9D,eAAW,UAAU,KAAK,QAAQ,SAAS;AACvC,UAAI,OAAO,MAAM;AACb;AAAA,MACJ;AACA,YAAM,SAAS,MAAM,KAAK,cAAc;AACxC,YAAM,KAAK,GAAG,IAAI;AAClB,SAAG,aAAa,SAAS,KAAK;AAC9B,SAAG,aAAa,QAAQ,qBAAqB;AAC7C,SAAG,aAAa,iBAAiB,GAAG,MAAM,EAAE;AAC5C,SAAG,aAAa,MAAM,QAAQ,SAAS,CAAC;AACxC,UAAI,KAAK,QAAQ,MAAM;AACnB,WAAG,aAAa,aAAa,MAAM;AAAA,MACvC;AACA,SAAG,aAAa,SAAS,OAAO,KAAK;AACrC,UAAI,KAAK,QAAQ,kBAAkB,KAAK,QAAQ,YAAY;AACxD,qBAAa,IAAI,mBAAmB,OAAO,cAAc,EAAE;AAAA,MAC/D;AAEA,YAAM,gBAAgB,aAAa,OAAO,OAAO,UAAU,IAAI,IAAI;AACnE,SAAG,QAAQ,WAAW,GAAG,aAAa;AACtC,4BAAsB,IAAI,MAAM;AAChC,SAAG,WAAW;AACd,SAAG,cAAc,OAAO;AAExB,UAAI,IAAI;AAGR,UAAI,KAAK,QAAQ,YAAY,KAAK,QAAQ,gBAAgB;AACtD,cAAM,oBAAoB,KAAK,IAAI,iBAAiB,YAAY,WAAW;AAC3E,YAAI,KAAK,QAAQ,eAAe;AAAA,UAC5B;AAAA,UACA;AAAA,UACA,OAAO,SAAS,GAAG,QAAQ,QAAQ;AAAA,UACnC;AAAA,QACJ;AAAA,MACJ,OAAO;AACH,YAAI,KAAK,IAAI,OAAO,SAAS,GAAG,QAAQ,QAAQ,GAAG,OAAO,SAAS,GAAG,aAAa,OAAO,CAAC,CAAC;AAAA,MAChG;AAEA,mBAAa,IAAI,SAAS,CAAC;AAC3B,UAAI,OAAO,QAAQ;AACf,WAAG,aAAa,UAAU,EAAE;AAAA,MAChC,OAAO;AACH,sBAAc;AAAA,MAClB;AAGA,UAAI,KAAK,QAAQ,WAAW,KAAK,QAAQ,kBAAkB;AACvD,aAAK,QAAQ,iBAAiB,oBAAoB,EAAE;AAAA,MACxD;AAEA,SAAG,YAAY,EAAE;AACjB;AAAA,IACJ;AAGA,QAAI,aAAa,gBAAgB;AAC7B,YAAM,cAAc,QAAQ,IAAI,oCAAoC;AACpE,UAAI,YAAY,QAAQ;AACpB,cAAM,UAAU,YAAY,YAAY,SAAS,CAAC;AAClD,wBAAgB,SAAS,OAAO;AAAA,MACpC;AAAA,IACJ;AAGA,QAAI,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,YAAY;AACxD,WAAK,QAAQ,WAAW,iBAAiB,EAAE;AAAA,IAC/C;AAEA,WAAO,aAAa,IAAI,MAAM,cAAc,oBAAoB,CAAC;AAGjE,QAAI,SAAS,MAAM,cAAc,gBAAgB;AAC7C,WAAK,IAAI,6BAA6B,MAAM,WAAW,MAAM,cAAc,EAAE;AAC7E,YAAM,iBAAiB,KAAK,cAAc,KAAK;AAC/C,UAAI,OAAO,MAAM,cAAc,iBAAiB;AAChD,UAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB;AACxD,gBAAQ;AAAA,MACZ;AAEA,YAAM,cAAc,QAAQ,IAAI,WAAW;AAE3C,iBAAW,MAAM,aAAa;AAC1B,YAAI,SAAS,IAAI,kBAAkB,GAAG;AAClC;AAAA,QACJ;AACA,YAAI,QAAQ,GAAG;AACX;AAAA,QACJ;AACA,cAAM,cAAc,OAAO,SAAS,GAAG,aAAa,OAAO,CAAC;AAC5D,cAAM,WAAW,GAAG,QAAQ,WAAW,OAAO,SAAS,GAAG,QAAQ,QAAQ,IAAI;AAC9E,YAAI,cAAc,UAAU;AACxB,cAAI,WAAW,cAAc;AAC7B,cAAI,WAAW,UAAU;AACrB,uBAAW;AAAA,UACf;AACA,kBAAQ,cAAc;AACtB,uBAAa,IAAI,SAAS,QAAQ;AAAA,QACtC;AAAA,MACJ;AAAA,IACJ;AAGA,QAAI,KAAK,QAAQ,QAAQ,KAAK,QAAQ,aAAa;AAC/C,WAAK,QAAQ,YAAY,kBAAkB;AAAA,IAC/C;AAGA,UAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,eAAW,eAAe,cAAc;AACpC,kBAAY,iBAAiB,SAAS,MAAM,KAAK,SAAS,WAAW,CAAC;AAAA,IAC1E;AAEA,SAAK,SAAS,aAAa,KAAK,OAAO,iBAAiB,KAAK,cAAc,IAAI,CAAC;AAAA,EACpF;AAAA,EAEA,oBAAoB,OAAO;AACvB,QAAI,MAAM;AACV,QAAI;AAGJ,SAAK,GAAG,IAAI;AACZ,SAAK,YAAY;AACjB,OAAG,aAAa,QAAQ,KAAK;AAC7B,OAAG,aAAa,iBAAiB,GAAG;AACpC,OAAG,aAAa,SAAS,iBAAiB;AAC1C,QAAI,CAAC,KAAK,QAAQ,QAAQ;AACtB,SAAG,aAAa,UAAU,EAAE;AAAA,IAChC;AAEA,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB;AACxD,WAAK,QAAQ,eAAe,gBAAgB,EAAE;AAAA,IAClD;AACA,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,kBAAkB,KAAK,QAAQ,eAAe,iBAAiB,GAAG;AAC1G,WAAK,QAAQ,eAAe,gBAAgB,EAAE;AAAA,IAClD;AAEA,SAAK,IAAI,iCAAiC,KAAK,QAAQ,OAAO;AAC9D,eAAW,UAAU,KAAK,QAAQ,SAAS;AACvC,UAAI,OAAO,MAAM;AACb;AAAA,MACJ;AACA,YAAM,SAAS,MAAM,KAAK,cAAc;AACxC,YAAM,YAAY,OAAO,cAAc,wCAAwC,MAAM,IAAI;AACzF,UAAI,CAAC,WAAW;AACZ,gBAAQ,KAAK,wBAAwB,MAAM;AAC3C;AAAA,MACJ;AACA,YAAM,KAAK,GAAG,IAAI;AAClB,SAAG,aAAa,iBAAiB,GAAG,MAAM,EAAE;AAE5C,YAAM,SAAS,KAAK,oBAAoB,QAAQ,SAAS;AACzD,UAAI,CAAC,KAAK,QAAQ,QAAQ;AACtB,WAAG,WAAW;AAAA,MAClB,OAAO;AACH,eAAO,WAAW;AAAA,MACtB;AAEA,UAAI,OAAO,QAAQ;AACf,WAAG,aAAa,UAAU,EAAE;AAAA,MAChC;AAEA,SAAG,YAAY,MAAM;AACrB,SAAG,YAAY,EAAE;AACjB;AAAA,IACJ;AAGA,QAAI,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,YAAY;AACxD,WAAK,QAAQ,WAAW,iBAAiB,EAAE;AAAA,IAC/C;AAEA,WAAO,aAAa,IAAI,MAAM,cAAc,oBAAoB,CAAC;AAEjE,QAAI,OAAO,KAAK,QAAQ,wBAAwB,YAAY,KAAK,QAAQ;AACrE,WAAK,QAAQ,sBAAsB;AAGvC,UAAM,eAAe,QAAQ,IAAI,KAAK,eAAe;AACrD,eAAW,MAAM,cAAc;AAC3B,YAAM,YAAY,UAAU,KAAK,GAAG,OAAO,IAAI,WAAW;AAC1D,YAAM,eAAe,SAAS,CAAC,MAAM;AACjC,cAAM,MAAM,EAAE,WAAW,EAAE;AAC3B,cAAM,mBAAmB,CAAC,KAAK,QAAQ,iBAAiB,CAAC,KAAK,cAAc,KAAK,CAAC,MAAM,MAAM,GAAG;AACjG,YAAI,QAAQ,MAAM,QAAQ,WAAW,oBAAoB,EAAE,SAAS,UAAU;AAC1E,eAAK,WAAW,KAAK,IAAI;AAAA,QAC7B;AAAA,MACJ,GAAG,KAAK,QAAQ,mBAAmB;AACnC,SAAG,iBAAiB,WAAW,YAAY;AAAA,IAC/C;AAAA,EACJ;AAAA,EAEA,oBAAoB,QAAQ,WAAW;AACnC,UAAM,WAAW,OAAO,eAAe;AACvC,UAAM,SAAS,WAAW,GAAG,QAAQ,IAAI,GAAG,OAAO;AACnD,QAAI,UAAU;AACV,UAAI,CAAC,MAAM,QAAQ,OAAO,UAAU,GAAG;AAEnC,cAAM,eAAe,CAAC,GAAG,IAAI,KAAK,KAAK,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,EAC1E,OAAO,CAAC,MAAM,CAAC,EACf,KAAK;AACV,eAAO,aAAa,CAAC,OAAO,qBAAqB,KAAK,cAAc,iBAAiB,EAAE;AAAA,UACnF,aAAa,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,EAAE;AAAA,QACnD;AAAA,MACJ;AAEA,iBAAW,KAAK,OAAO,YAAY;AAC/B,cAAM,MAAM,GAAG,QAAQ;AACvB,YAAI,QAAQ,EAAE;AACd,YAAI,OAAO,EAAE;AAEb,YAAI,kBAAkB,mBAAmB;AACrC,iBAAO,IAAI,GAAG;AAAA,QAClB;AAAA,MACJ;AAAA,IACJ,OAAO;AAEH,aAAO,OAAO;AACd,aAAO,YAAY;AACnB,aAAO,eAAe;AACtB,aAAO,aAAa;AAAA,IACxB;AAEA,WAAO,QAAQ,OAAO,OAAO;AAC7B,WAAO,KAAK,QAAQ,YAAY;AAEhC,WAAO,aAAa,mBAAmB,UAAU,aAAa,IAAI,CAAC;AACnE,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa;AACT,SAAK,IAAI,aAAa;AACtB,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,UAAM,QAAQ,GAAG,OAAO;AAExB,SAAK,KAAK,QAAQ,CAAC,MAAM,MAAM;AAC3B,WAAK,GAAG,IAAI;AACZ,mBAAa,IAAI,QAAQ,KAAK;AAC9B,mBAAa,IAAI,UAAU,EAAE;AAC7B,mBAAa,IAAI,iBAAiB,IAAI,CAAC;AACvC,SAAG,WAAW;AAEd,UAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB;AACxD,aAAK,QAAQ,eAAe,cAAc,EAAE;AAAA,MAChD;AACA,UACI,KAAK,QAAQ,cACb,KAAK,QAAQ,kBACb,KAAK,QAAQ,eAAe,iBAAiB,GAC/C;AACE,aAAK,QAAQ,eAAe,cAAc,EAAE;AAAA,MAChD;AAGA,UAAI,KAAK,QAAQ,QAAQ;AACrB,WAAG,UAAU,IAAI,eAAe;AAEhC,WAAG,IAAI,SAAS,CAAC,OAAO;AACpB,cAAI,GAAG,OAAO,QAAQ,KAAK,2BAA2B,EAAG;AACzD,cAAI,KAAK,QAAQ,gBAAgB;AAC7B,iBAAK,QAAQ,eAAe,cAAc;AAAA,UAC9C;AACA,sBAAY,GAAG,eAAe,aAAa;AAC3C,cAAI,KAAK,QAAQ,gBAAgB;AAC7B,iBAAK,QAAQ,eAAe,gBAAgB;AAAA,UAChD;AAAA,QACJ,CAAC;AAAA,MACL;AAEA,YAAM;AAEN,iBAAW,UAAU,KAAK,QAAQ,SAAS;AACvC,YAAI,CAAC,QAAQ;AACT,kBAAQ,MAAM,uBAAuB,KAAK,QAAQ,OAAO;AAAA,QAC7D;AAEA,YAAI,OAAO,MAAM;AACb,cAAI,KAAK,OAAO,KAAK,GAAG;AAEpB,gBAAI,OAAO,SAAS,SAAS;AACzB,uBAAS,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,YACnC,OAAO;AACH,iBAAG,aAAa,OAAO,MAAM,KAAK,OAAO,KAAK,CAAC;AAAA,YACnD;AAAA,UACJ;AACA;AAAA,QACJ;AACA,aAAK,GAAG,IAAI;AACZ,WAAG,aAAa,QAAQ,UAAU;AAClC,WAAG,aAAa,iBAAiB,GAAG,GAAG,GAAG,KAAK,cAAc,CAAC,EAAE;AAChE,8BAAsB,IAAI,MAAM;AAEhC,WAAG,aAAa,aAAa,OAAO,KAAK;AACzC,WAAG,WAAW;AAGd,YAAI,OAAO,YAAY,KAAK,QAAQ,gBAAgB;AAChD,mBAAS,IAAI,iBAAiB;AAC9B,eAAK,QAAQ,eAAe,kBAAkB,IAAI,QAAQ,MAAM,CAAC;AAAA,QACrE,OAAO;AAEH,gBAAM,IAAI,KAAK,OAAO,KAAK,KAAK;AAChC,cAAI;AAEJ,kBAAQ,OAAO,WAAW;AAAA,YACtB,KAAK;AACD,mBAAK,EAAE,YAAY;AACnB;AAAA,YACJ,KAAK;AACD,mBAAK,EAAE,YAAY;AACnB;AAAA,YACJ;AACI,mBAAK;AACL;AAAA,UACR;AACA,cAAI,OAAO,QAAQ;AAEf,gBAAI,OAAO,uBAAuB,WAAc,OAAO,MAAM,OAAO,OAAO;AACvE,mBAAK,GAAG,OAAO,kBAAkB;AAAA,YACrC;AACA,gBAAI,OAAO,OAAO,WAAW,YAAY,IAAI;AACzC,iBAAG,YAAY;AAAA;AAAA,gBAEX,OAAO;AAAA,gBACP,OAAO;AAAA,kBACH;AAAA,oBACI,IAAI;AAAA,oBACJ,KAAK;AAAA,kBACT;AAAA,kBACA;AAAA,gBACJ;AAAA,cACJ;AAAA,YACJ,WAAW,OAAO,kBAAkB,UAAU;AAC1C,oBAAM,MAAM,OAAO,OAAO,KAAK,MAAM,EAAE,QAAQ,SAAS,MAAM,UAAU,IAAI,IAAI,GAAG,CAAC;AACpF,iBAAG,YAAY,OAAO,MAAM;AAAA,YAChC;AAAA,UACJ,OAAO;AACH,eAAG,cAAc;AAAA,UACrB;AAAA,QACJ;AACA,WAAG,YAAY,EAAE;AACjB;AAAA,MACJ;AAGA,UAAI,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,YAAY;AACxD,aAAK,QAAQ,WAAW,cAAc,IAAI,IAAI;AAAA,MAClD;AAEA,YAAM,YAAY,EAAE;AAEpB,eAAS,MAAM,eAAe,EAAE,SAAS,MAAM,GAAG,CAAC;AAAA,IACvD,CAAC;AAED,UAAM,aAAa,QAAQ,UAAU;AAGrC,UAAM,OAAO,KAAK;AAClB,YAAQ,MAAM,aAAa,cAAc,KAAK,aAAa,YAAY,CAAC;AACxE,SAAK,OAAO,aAAa,OAAO,IAAI;AAEpC,QAAI,KAAK,QAAQ,aAAa;AAC1B,WAAK,QAAQ,YAAY,cAAc;AAAA,IAC3C;AAEA,SAAK,SAAS;AAEd,QAAI,KAAK,QAAQ,gBAAgB;AAC7B,WAAK,QAAQ,eAAe,gBAAgB,KAAK;AAAA,IACrD;AAEA,SAAK,UAAU,OAAO,YAAY,CAAC,KAAK,KAAK,MAAM;AAEnD,aAAS,MAAM,cAAc;AAAA,EACjC;AAAA,EAEA,WAAW;AACP,SAAK,IAAI,UAAU;AAEnB,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,IAAI,KAAK,QAAQ;AACvB,UAAM,QAAQ,KAAK;AACnB,UAAM,QAAQ,KAAK;AACnB,QAAI,CAAC,SAAS,CAAC,MAAO;AACtB,UAAM,WAAW,QAAQ,OAAO,IAAI;AAGpC,SAAK,QAAQ,KAAK,WAAW;AAE7B,QAAI;AACJ,QAAI,OAAO,IAAI,KAAK,QAAQ;AAC5B,QAAI,MAAM,OAAO,KAAK,QAAQ,UAAU;AAExC,QAAI,OAAO,OAAO;AACd,aAAO;AAAA,IACX;AACA,QAAI,CAAC,OAAO;AACR,YAAM;AAAA,IACV;AAKA,eAAW,MAAM,UAAU;AACvB,UAAI,KAAK,QAAQ,QAAQ;AACrB,wBAAgB,IAAI,QAAQ;AAC5B;AAAA,MACJ;AACA,cAAQ,OAAO,aAAa,IAAI,eAAe,CAAC;AAChD,UAAI,QAAQ,QAAQ,QAAQ,KAAK;AAC7B,qBAAa,IAAI,UAAU,EAAE;AAAA,MACjC,OAAO;AACH,wBAAgB,IAAI,QAAQ;AAAA,MAChC;AAAA,IACJ;AAEA,QAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB;AACxD,WAAK,QAAQ,eAAe,gBAAgB,KAAK;AAAA,IACrD;AAGA,QAAI,KAAK,QAAQ,aAAa;AAC1B,WAAK,QAAQ,YAAY,cAAc;AAAA,IAC3C;AAGA,QAAI,KAAK,UAAU;AACf,WAAK,SAAS,WAAW,KAAK,QAAQ;AACtC,WAAK,QAAQ,WAAW,KAAK,QAAQ;AACrC,WAAK,QAAQ,WAAW,KAAK,QAAQ,KAAK;AAC1C,WAAK,QAAQ,WAAW,KAAK,QAAQ,KAAK;AAAA,IAC9C;AACA,UAAM,cAAc,SAAS,EAAE,cAAc,IAAI,SAAS;AAC1D,UAAM,cAAc,UAAU,EAAE,cAAc,KAAK,SAAS;AAC5D,UAAM,cAAc,WAAW,EAAE,cAAc,GAAG,KAAK,aAAa,CAAC;AACrE,UAAM,gBAAgB,UAAU,KAAK,QAAQ,iBAAiB,KAAK,QAAQ,UAAU,KAAK,aAAa,CAAC;AAAA,EAC5G;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AACT,WAAO,KAAK,KAAK,KAAK,aAAa,IAAI,KAAK,QAAQ,OAAO;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACX,QAAI,KAAK,QAAQ,QAAQ;AACrB,aAAO,KAAK,OAAO,KAAK,QAAQ,aAAa,eAAe,KAAK;AAAA,IACrE;AACA,WAAO,KAAK,KAAK;AAAA,EACrB;AACJ;AAEA,IAAO,oBAAQ;;;ACv9Df,IAAM,aAAN,MAAiB;AAAA;AAAA;AAAA;AAAA,EAIb,YAAY,MAAM;AACd,SAAK,OAAO;AAAA,EAChB;AAAA,EAEA,YAAY;AAAA,EAAC;AAAA,EAEb,eAAe;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhB,YAAY,OAAO;AACf,QAAI,KAAK,KAAK,MAAM,IAAI,EAAE,GAAG;AACzB,WAAK,KAAK,MAAM,IAAI,EAAE,EAAE,KAAK;AAAA,IACjC;AAAA,EACJ;AACJ;AAEA,IAAO,sBAAQ;;;ACRf,IAAM,gBAAN,cAA4B,oBAAW;AAAA,EACnC,YAAY,MAAM;AACd,UAAM,IAAI;AACV,SAAK,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,aAAa;AACvB,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK;AACnB,UAAM,OAAO,QAAQ,MAAM,6BAA6B;AAExD,eAAW,OAAO,MAAM;AACpB,UAAI,SAAS,KAAK,kBAAkB,GAAG;AACnC;AAAA,MACJ;AAEA,YAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,eAAS,SAAS,YAAY;AAC9B,cAAQ,YAAY;AAGpB,UAAI,YAAY,OAAO;AAGvB,UAAI,SAAS;AACb,UAAI,SAAS;AACb,UAAI,iBAAiB;AACrB,UAAI,MAAM;AAEV,YAAM,mBAAmB,CAAC,MAAM;AAC5B,YAAI,EAAE,UAAU,KAAK;AACjB;AAAA,QACJ;AACA,cAAM,WAAW,UAAU,EAAE,UAAU;AACvC,YAAI,IAAI,QAAQ,YAAY,WAAW,OAAO,SAAS,IAAI,QAAQ,QAAQ,GAAG;AAC1E,uBAAa,KAAK,SAAS,QAAQ;AAAA,QACvC;AAAA,MACJ;AAGA,YAAM,iBAAiB,MAAM;AACzB,aAAK,IAAI,gBAAgB;AAGzB,mBAAW,MAAM;AACb,eAAK,aAAa;AAAA,QACtB,GAAG,CAAC;AAEJ,oBAAY,SAAS,mBAAmB;AACxC,YAAI,KAAK,QAAQ,SAAS;AACtB,cAAI,YAAY;AAAA,QACpB;AACA,YAAI,MAAM,WAAW;AAGrB,YAAI,UAAU,aAAa,gBAAgB;AAC3C,YAAI,UAAU,WAAW,cAAc;AAEvC,iBAAS,MAAM,iBAAiB;AAAA,UAC5B,KAAK,aAAa,KAAK,OAAO;AAAA,UAC9B,OAAO,aAAa,KAAK,OAAO;AAAA,QACpC,CAAC;AAAA,MACL;AAGA,SAAG,SAAS,SAAS,CAAC,MAAM;AACxB,UAAE,gBAAgB;AAAA,MACtB,CAAC;AAED,SAAG,SAAS,aAAa,CAAC,MAAM;AAC5B,UAAE,gBAAgB;AAElB,aAAK,aAAa;AAElB,cAAM,SAAS,EAAE;AACjB,cAAM,cAAc,QAAQ,MAAM,oBAAoB;AACtD,cAAM,cAAc,YAAY,OAAO,CAACA,SAAQ;AAC5C,iBAAO,CAACA,KAAI,aAAa,QAAQ;AAAA,QACrC,CAAC;AACD,cAAM,cAAc,YAAY,UAAU,CAAC,WAAW,WAAW,OAAO,UAAU;AAClF,aAAK,IAAI,eAAe;AAExB,iBAAS,SAAS,mBAAmB;AAGrC,wBAAgB,KAAK,WAAW;AAGhC,YAAI,MAAM,WAAW;AAGrB,gBAAQ,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC;AAGhD,iBAAS,EAAE;AACX,iBAAS,IAAI;AAEb,0BAAkB,YAAY,SAAS,eAAe;AACtD,cAAM,cAAc,MAAM,EAAE,OAAO,KAAK,cAAc;AAGtD,qBAAa,KAAK,SAAS,MAAM;AACjC,iBAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AACzC,cAAI,IAAI,aAAa;AACjB,4BAAgB,KAAK,CAAC,GAAG,OAAO;AAAA,UACpC;AAAA,QACJ;AAGA,WAAG,UAAU,aAAa,gBAAgB;AAC1C,WAAG,UAAU,WAAW,cAAc;AAAA,MAC1C,CAAC;AAAA,IACL;AAAA,EACJ;AACJ;AAEA,IAAO,yBAAQ;;;ACnIA,SAAR,iBAAkC,IAAI,MAAM,OAAO,YAAY;AAClE,MAAI,SAAS;AACb,SAAO,OAAO,IAAI,MAAM,MAAM;AAC1B,aAAS,OAAO;AAAA,EACpB;AACA,SAAO;AACX;;;ACLA,IAAM,cAAN,cAA0B,oBAAW;AAAA,EACjC,YAAY;AAIR,SAAK,OAAO,KAAK,KAAK,cAAc,UAAU;AAAA,EAClD;AAAA,EACA,eAAe;AACX,QAAI,KAAK,KAAK,WAAW;AACrB,UAAI,KAAK,KAAK,WAAW,eAAe,IAAI;AAAA,IAChD;AAAA,EACJ;AAAA,EAEA,oBAAoB;AAChB,UAAM,OAAO,KAAK;AAClB,OAAG,KAAK,WAAW,eAAe,IAAI;AAAA,EAC1C;AAAA,EAEA,SAAS,GAAG;AACR,UAAM,OAAO,KAAK;AAClB,UAAM,IAAI,EAAE;AACZ,UAAM,QAAQ,EAAE,QAAQ;AACxB,QAAI,EAAE,SAAS;AACX,WAAK,WAAW,KAAK;AAAA,IACzB,OAAO;AAEH,UAAI,KAAK,eAAe,EAAE,UAAU,GAAG;AAEnC,UAAE,UAAU;AACZ;AAAA,MACJ;AACA,WAAK,WAAW,KAAK;AAAA,IACzB;AACA,SAAK,QAAQ;AAAA,EACjB;AAAA,EAEA,cAAc,GAAG;AACb,MAAE,eAAe;AACjB,UAAM,OAAO,KAAK;AAClB,UAAM,SAAS,iBAAiB,EAAE,QAAQ,OAAO;AACjD,UAAM,OAAO,KAAK;AAClB,UAAM,OAAO,OAAO,sBAAsB;AAC1C,QAAI,IAAI,EAAE,UAAU,KAAK;AACzB,UAAM,IAAI,EAAE,UAAU,KAAK;AAE3B,SAAK,MAAM,MAAM,GAAG,CAAC;AACrB,SAAK,MAAM,OAAO,GAAG,CAAC;AAEtB,oBAAgB,MAAM,QAAQ;AAC9B,QAAI,IAAI,MAAM,KAAK,OAAO;AACtB,WAAK,KAAK;AACV,WAAK,MAAM,OAAO,GAAG,CAAC;AAAA,IAC1B;AAEA,UAAM,uBAAuB,CAACC,OAAM;AAChC,UAAI,CAAC,KAAK,SAASA,GAAE,MAAM,GAAG;AAC1B,qBAAa,MAAM,UAAU,EAAE;AAC/B,YAAI,UAAU,SAAS,oBAAoB;AAAA,MAC/C;AAAA,IACJ;AACA,OAAG,UAAU,SAAS,oBAAoB;AAAA,EAC9C;AAAA,EACA,aAAa;AACT,UAAM,OAAO,KAAK;AAClB,UAAM,OAAO,KAAK;AAClB,WAAO,KAAK,WAAW;AACnB,WAAK,YAAY,KAAK,SAAS;AAAA,IACnC;AACA,SAAK,iBAAiB,UAAU,IAAI;AAEpC,eAAW,OAAO,KAAK,QAAQ,SAAS;AACpC,UAAI,IAAI,MAAM;AACV;AAAA,MACJ;AACA,YAAM,KAAK,SAAS,cAAc,IAAI;AACtC,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,mBAAa,UAAU,QAAQ,UAAU;AACzC,mBAAa,UAAU,aAAa,IAAI,KAAK;AAC7C,UAAI,CAAC,IAAI,QAAQ;AACb,iBAAS,UAAU;AAAA,MACvB;AACA,YAAM,OAAO,SAAS,eAAe,IAAI,KAAK;AAE9C,YAAM,YAAY,QAAQ;AAC1B,YAAM,YAAY,IAAI;AAEtB,SAAG,YAAY,KAAK;AACpB,WAAK,YAAY,EAAE;AAAA,IACvB;AAAA,EACJ;AACJ;AAEA,IAAO,uBAAQ;;;AC7Ff,IAAM,mBAAN,cAA+B,oBAAW;AAAA;AAAA;AAAA;AAAA,EAItC,oBAAoB,IAAI;AACpB,UAAM,OAAO,KAAK;AAClB,OAAG,YAAY;AACf,OAAG,IAAI,aAAa,CAAC,MAAM;AACvB,UAAI,KAAK,QAAQ,eAAe,cAAc,EAAE,gBAAgB;AAC5D,UAAE,eAAe;AACjB;AAAA,MACJ;AACA,WAAK,IAAI,aAAa;AACtB,QAAE,aAAa,gBAAgB;AAC/B,QAAE,aAAa,QAAQ,cAAc,EAAE,OAAO,aAAa,eAAe,CAAC;AAAA,IAC/E,CAAC;AACD,OAAG,IAAI,YAAY,CAAC,MAAM;AACtB,UAAI,EAAE,gBAAgB;AAClB,UAAE,eAAe;AAAA,MACrB;AACA,QAAE,aAAa,aAAa;AAC5B,aAAO;AAAA,IACX,CAAC;AACD,OAAG,IAAI,QAAQ,CAAC,MAAM;AAClB,UAAI,EAAE,iBAAiB;AACnB,UAAE,gBAAgB;AAAA,MACtB;AACA,YAAM,IAAI,EAAE;AACZ,YAAM,SAAS,iBAAiB,GAAG,IAAI;AACvC,YAAM,QAAQ,OAAO,SAAS,EAAE,aAAa,QAAQ,YAAY,CAAC;AAClE,YAAM,cAAc,OAAO,SAAS,OAAO,aAAa,eAAe,CAAC;AAExE,UAAI,UAAU,aAAa;AACvB,aAAK,IAAI,+BAA+B;AACxC;AAAA,MACJ;AACA,WAAK,IAAI,sBAAsB,KAAK,OAAO,WAAW,EAAE;AAExD,YAAM,SAAS,KAAK,cAAc;AAClC,YAAM,MAAM,KAAK,QAAQ,QAAQ,QAAQ,MAAM;AAC/C,WAAK,QAAQ,QAAQ,QAAQ,MAAM,IAAI,KAAK,QAAQ,QAAQ,cAAc,MAAM;AAChF,WAAK,QAAQ,QAAQ,cAAc,MAAM,IAAI;AAE7C,YAAM,YAAY,CAAC,UAAU,QAAQ;AACjC,cAAM,WAAW,IAAI,WAAW,aAAa,eAAe;AAC5D,cAAM,MAAM,KAAK;AAAA,UACb,GAAG,QAAQ,sBAAsB,QAAQ,sBAAsB,WAAW;AAAA,QAC9E;AACA,qBAAa,KAAK,iBAAiB,WAAW;AAC9C,qBAAa,KAAK,iBAAiB,KAAK;AACxC,cAAM,UAAU,SAAS,cAAc,IAAI;AAC3C,YAAI,WAAW,aAAa,SAAS,GAAG;AACxC,YAAI,WAAW,aAAa,KAAK,GAAG;AACpC,gBAAQ,WAAW,aAAa,KAAK,OAAO;AAAA,MAChD;AAGA,iBAAW,OAAO,QAAQ,MAAM,2BAA2B,KAAK,IAAI,GAAG;AACnE,kBAAU,SAAS,GAAG;AAAA,MAC1B;AACA,iBAAW,OAAO,QAAQ,MAAM,2BAA2B,KAAK,IAAI,GAAG;AACnE,kBAAU,SAAS,GAAG;AAAA,MAC1B;AAGA,WAAK,QAAQ,UAAU,QAAQ,MAAM,oCAAoC,EAAE;AAAA,QAAI,CAACC,QAC5E,KAAK,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,UAAU,aAAaA,KAAI,OAAO,CAAC;AAAA,MAC1E;AAEA,eAAS,MAAM,mBAAmB;AAAA,QAC9B,KAAK,IAAI;AAAA,QACT,MAAM;AAAA,QACN,IAAI;AAAA,MACR,CAAC;AACD,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AACJ;AAEA,IAAO,4BAAQ;;;ACjFf,IAAM,eAAN,cAA2B,oBAAW;AAAA,EAClC,YAAY,MAAM;AACd,UAAM,IAAI;AACV,SAAK,QAAQ;AAAA,EACjB;AAAA,EACA,YAAY;AACR,UAAM,OAAO,KAAK;AAClB,SAAK,iBAAiB,cAAc,MAAM,EAAE,SAAS,KAAK,CAAC;AAC3D,SAAK,iBAAiB,aAAa,MAAM,EAAE,SAAS,KAAK,CAAC;AAAA,EAC9D;AAAA,EAEA,eAAe;AACX,UAAM,OAAO,KAAK;AAClB,SAAK,oBAAoB,cAAc,IAAI;AAC3C,SAAK,oBAAoB,aAAa,IAAI;AAAA,EAC9C;AAAA,EAEA,aAAa,GAAG;AACZ,SAAK,QAAQ,EAAE,QAAQ,CAAC;AAAA,EAC5B;AAAA,EAEA,YAAY,GAAG;AACX,QAAI,CAAC,KAAK,OAAO;AACb;AAAA,IACJ;AACA,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK,MAAM,UAAU,EAAE,QAAQ,CAAC,EAAE;AAChD,UAAM,QAAQ,KAAK,MAAM,UAAU,EAAE,QAAQ,CAAC,EAAE;AAEhD,QAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG;AACnC,UAAI,QAAQ,GAAG;AACX,aAAK,QAAQ;AAAA,MACjB,OAAO;AACH,aAAK,QAAQ;AAAA,MACjB;AAAA,IACJ;AACA,SAAK,QAAQ;AAAA,EACjB;AACJ;AAEA,IAAO,wBAAQ;;;ACzCf,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AACzB,IAAM,iBAAiB;AAKvB,IAAM,iBAAN,cAA6B,oBAAW;AAAA,EACpC,cAAc,WAAW,KAAK,cAAc,mBAAmB,EAAE,KAAK,gBAAgB;AAAA,EACtF,iBAAiB,UAAU,gBAAgB;AAAA,EAE3C,eAAe;AACX,QAAI,KAAK,WAAW;AAChB,WAAK,UAAU,oBAAoB,UAAU,IAAI;AAAA,IACrD;AAAA,EACJ;AAAA,EAEA,IAAI,iBAAiB;AACjB,WAAO,KAAK,KAAK,QAAQ;AAAA,EAC7B;AAAA,EAEA,IAAI,cAAc;AACd,WAAO,KAAK,KAAK,QAAQ;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,gBAAgB,MAAM;AAClB,UAAM,OAAO,KAAK;AAClB,UAAM,eAAe,CAAC;AAEtB,UAAM,SAAS,QAAQ,MAAM,GAAG,KAAK,cAAc,UAAU;AAE7D,eAAW,YAAY,QAAQ;AAC3B,YAAM,MAAM,OAAO,SAAS,SAAS,QAAQ,EAAE;AAC/C,YAAM,OAAO,KAAK,KAAK,MAAM,CAAC;AAC9B,UAAI,CAAC,MAAM;AACP,gBAAQ,KAAK,QAAQ,GAAG,YAAY;AACpC;AAAA,MACJ;AACA,UAAI,KAAK,WAAW,GAAG;AACnB,qBAAa,KAAK,IAAI;AAAA,MAC1B,WAAW,KAAK,WAAW,GAAG;AAC1B,qBAAa,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC;AAAA,MACnC,OAAO;AACH,qBAAa,KAAK,OAAO,YAAY,KAAK,IAAI,OAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,MACrE;AAAA,IACJ;AACA,WAAO,KAAK,iBAAiB,aAAa,CAAC,KAAK,CAAC,IAAI;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,OAAO;AACnB,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,KAAK,QAAQ,mBAAmB;AACjC;AAAA,IACJ;AACA,UAAM,SAAS,QAAQ,OAAO,eAAe,gBAAgB,QAAQ;AACrE,eAAW,SAAS,QAAQ;AACxB,YAAM,UAAU;AAChB,UAAI,KAAK,gBAAgB;AACrB,cAAM,QAAQ,UAAU;AAAA,MAC5B;AAAA,IACJ;AACA,SAAK,UAAU,UAAU;AAAA,EAC7B;AAAA,EAEA,WAAW;AACP,WAAO,KAAK,KAAK,cAAc,IAAI;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,IAAI;AAChB,UAAM,KAAK,SAAS,cAAc,IAAI;AACtC,iBAAa,IAAI,SAAS,KAAK;AAC/B,iBAAa,IAAI,QAAQ,qBAAqB;AAC9C,iBAAa,IAAI,iBAAiB,KAAK,SAAS,CAAC;AACjD,OAAG,UAAU,IAAI,GAAG,CAAC,kBAAkB,oBAAoB,iBAAiB,CAAC;AAC7E,OAAG,WAAW;AAEd,SAAK,YAAY,SAAS,cAAc,OAAO;AAC/C,SAAK,UAAU,OAAO;AACtB,SAAK,UAAU,UAAU,IAAI,gBAAgB;AAC7C,SAAK,UAAU,UAAU,IAAI,cAAc;AAC3C,SAAK,UAAU,iBAAiB,UAAU,IAAI;AAE9C,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,SAAS,KAAK;AACpB,UAAM,YAAY,KAAK,SAAS;AAEhC,OAAG,YAAY,KAAK;AAEpB,OAAG,aAAa,SAAS,IAAI;AAC7B,OAAG,YAAY,EAAE;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,IAAI;AAChB,UAAM,KAAK,SAAS,cAAc,IAAI;AACtC,iBAAa,IAAI,QAAQ,qBAAqB;AAC9C,iBAAa,IAAI,iBAAiB,KAAK,SAAS,CAAC;AACjD,OAAG,UAAU,IAAI,gBAAgB;AACjC,OAAG,WAAW;AAEd,OAAG,YAAY,EAAE;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgB,OAAO;AACnB,QAAI,CAAC,KAAK,WAAW;AACjB;AAAA,IACJ;AAEA,UAAM,iBAAiB,UAAU,IAAI;AAErC,UAAM,cAAc,IAAI,MAAM,QAAQ,CAAC;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,IAAI;AAEd,UAAM,KAAK,SAAS,cAAc,IAAI;AACtC,iBAAa,IAAI,QAAQ,iBAAiB;AAC1C,iBAAa,IAAI,iBAAiB,KAAK,SAAS,CAAC;AACjD,OAAG,UAAU,IAAI,gBAAgB;AAGjC,UAAM,QAAQ,SAAS,cAAc,OAAO;AAE5C,UAAM,QAAQ,KAAK,GAAG,aAAa,eAAe;AAClD,UAAM,OAAO,KAAK,iBAAiB,UAAU;AAC7C,UAAM,UAAU,IAAI,cAAc;AAClC,QAAI,KAAK,gBAAgB;AACrB,YAAM,OAAO;AACb,YAAM,QAAQ,UAAU;AAAA,IAC5B;AAGA,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,UAAU,IAAI,mBAAmB;AAEvC,UAAM,YAAY,KAAK;AACvB,OAAG,YAAY,KAAK;AAGpB,UAAM,iBAAiB,SAAS,IAAI;AAEpC,OAAG,YAAY,EAAE;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,GAAG;AACP,QAAI,CAAC,KAAK,eAAgB,QAAO,EAAE,gBAAgB;AAGnD,UAAM,KAAK,EAAE,QACT,YAAY,GAAG,QAAQ,YAAY;AACvC,iBAAa,GAAG,GAAG,KAAK,YAAY,QAAQ,YAAY,OAAO,CAAC,IAAI,KAAK,IAAI,GAAG,QAAQ,OAAK;AAEzF,UAAI,EAAE,SAAS,GAAG,QAAQ,MAAM,GAAI,GAAE,UAAU,EAAE,QAAQ,UAAU;AAAA,IACxE,CAAC;AACD,OAAG,UAAU,GAAG,QAAQ,UAAU;AAClC,KAAC,aAAa,KAAK,SAAS,CAAC;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,GAAG;AACR,UAAM,KAAK,EAAE,QAAQ,OAAO,KAAK;AACjC,QAAI,SAAS,EAAE,QAAQ,gBAAgB,GAAG;AACtC,cAAQ,MAAM,KAAK,cAAc,EAAE,QAAQ,QAAM;AAC7C,YAAI,CAAC,KAAK,eAAe,GAAG,YAAa,IAAG,UAAU,KAAK,UAAU;AAAA,MACzE,CAAC;AAAA,IACL,WAAW,GAAG,QAAQ,KAAK,WAAW,GAAG;AACrC,UAAI,CAAC,GAAG,QAAQ,IAAI,gBAAgB,EAAE,EAAG;AACzC,YAAM,kBAAkB,QAAQ,MAAM,KAAK,WAAW;AACtD,WAAK,UAAU,UAAU,gBAAgB,MAAM,OAAK,EAAE,OAAO;AAAA,IACjE;AACA,QAAI,GAAG,QAAQ,IAAI,gBAAgB,IAAI,KAAK,cAAc,EAAE,GAAG;AAC3D,eAAS,IAAI,gBAAgB;AAAA,QACzB,WAAW,KAAK,aAAa;AAAA,MACjC,GAAG,IAAI;AAAA,IACX;AAAA,EACJ;AACJ;AAEA,IAAO,0BAAQ;;;AC7Mf,IAAM,cAAN,cAA0B,oBAAW;AAAA,EACjC,YAAY,MAAM;AACd,UAAM,IAAI;AAEV,SAAK,iBAAiB;AAEtB,QAAI,KAAK,MAAM,QAAQ;AACnB,WAAK,MAAM,YAAY;AACvB,WAAK,iBAAiB;AAAA,IAC1B;AAAA,EACJ;AAAA;AAAA;AAAA,EAIA,gBAAgB;AACZ,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK,cAAc,OAAO;AACxC,UAAM,KAAK,SAAS,cAAc,IAAI;AACtC,iBAAa,IAAI,QAAQ,KAAK;AAC9B,iBAAa,IAAI,UAAU,EAAE;AAC7B,OAAG,UAAU,IAAI,aAAa;AAC9B,OAAG,WAAW;AACd,WAAO,YAAY,EAAE;AAAA,EACzB;AAAA,EAEA,IAAI,UAAU;AACV,WAAO,KAAK,KAAK,cAAc,cAAc;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB;AACZ,UAAM,OAAO,KAAK;AAClB,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,SAAS;AACV;AAAA,IACJ;AAGA,QAAI,KAAK,QAAQ,UAAU,KAAK,aAAa,GAAG;AAC5C;AAAA,IACJ;AAEA,QAAI,KAAK,SAAS,KAAK,WAAW,GAAG;AACjC;AAAA,IACJ;AACA,QAAI,CAAC,KAAK,QAAQ,YAAY;AAC1B;AAAA,IACJ;AAEA,UAAM,MAAM,KAAK,QAAQ,UAAU,KAAK;AACxC,UAAM,cAAc,KAAK,iBAAiB,wBAAwB,EAAE;AACpE,UAAM,aAAa,cAAc,IAAI,MAAM,cAAc,KAAK,YAAY;AAC1E,QAAI,aAAa,GAAG;AAChB,mBAAa,SAAS,UAAU,UAAU;AAC1C,cAAQ,gBAAgB,QAAQ;AAAA,IACpC,OAAO;AACH,cAAQ,gBAAgB,QAAQ;AAAA,IACpC;AAAA,EACJ;AACJ;AAEA,IAAO,uBAAQ;;;AChEf,IAAM,iBAAN,cAA6B,oBAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASpC,YAAY,IAAI,QAAQ,KAAK,KAAK;AAC9B,UAAM,OAAO,KAAK;AAClB,QAAI,aAAa,IAAI,OAAO,GAAG;AAC3B,aAAO,aAAa,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,CAAC,KAAK,KAAK,QAAQ;AACnB;AAAA,IACJ;AACA,UAAM,WAAW,KAAK,KAAK,CAAC;AAC5B,UAAM,UAAU,KAAK,KAAK,KAAK,KAAK,SAAS,CAAC;AAC9C,QAAI,IAAI,SAAS,OAAO,KAAK,IAAI,SAAS,OAAO,KAAK,EAAE,SAAS,IAAI;AACrE,UAAM,KAAK,QAAQ,OAAO,KAAK,IAAI,QAAQ,OAAO,KAAK,EAAE,SAAS,IAAI;AACtE,QAAI,GAAG,SAAS,EAAE,QAAQ;AACtB,UAAI;AAAA,IACR;AACA,QAAI,QAAQ;AACZ,QAAI,EAAE,UAAU,GAAG;AACf,cAAQ;AAAA,IACZ,WAAW,EAAE,SAAS,IAAI;AACtB,cAAQ;AAAA,IACZ,OAAO;AAEH,cAAQ,aAAa,GAAG,CAAC,QAAQ,EAAE;AAAA,IACvC;AACA,QAAI,QAAQ,KAAK;AACb,cAAQ;AAAA,IACZ;AACA,QAAI,QAAQ,KAAK;AACb,cAAQ;AAAA,IACZ;AACA,iBAAa,IAAI,SAAS,KAAK;AAC/B,WAAO;AAAA,EACX;AACJ;AAEA,IAAO,0BAAQ;;;ACrCf,IAAM,mBAAmB;AAEzB,IAAI;AAMJ,SAAS,eAAe,MAAM;AAC1B,SAAO,KAAK,KAAK,CAAC,GAAG,MAAM;AACvB,UAAM,KAAK,OAAO,SAAS,EAAE,QAAQ,UAAU,KAAK;AACpD,UAAM,KAAK,OAAO,SAAS,EAAE,QAAQ,UAAU,KAAK;AACpD,WAAO,KAAK;AAAA,EAChB,CAAC;AACL;AAMA,IAAM,WAAW,SAAS,CAAC,YAAY;AACnC,aAAW,SAAS,SAAS;AAKzB,UAAM,OAAO,MAAM;AACnB,UAAM,QAAQ,KAAK;AACnB,QAAI,KAAK,QAAQ,eAAe,iBAAiB;AAC7C;AAAA,IACJ;AAEA,UAAM,iBAAiB,MAAM,QAAQ,MAAM,cAAc,IAAI,MAAM,eAAe,CAAC,IAAI,MAAM;AAC7F,UAAM,OAAO,OAAO,SAAS,eAAe,UAAU;AACtD,UAAM,aAAa,MAAM;AACzB,UAAM,iBAAiB,QAAQ,KAAK,WAAW,IAAI,EAAE,OAAO,CAAC,QAAQ,OAAO;AACxE,aAAO,SAAS,GAAG;AAAA,IACvB,GAAG,CAAC;AACJ,UAAM,QAAQ,kBAAkB,cAAc,OAAO;AACrD,UAAM,WAAW;AACjB,UAAM,aAAa,KAAK,QAAQ,eAAe;AAE/C,UAAM,aAAa;AAAA,MACf,QAAQ,KAAK,WAAW,WAAW,EAC9B,QAAQ,EACR,OAAO,CAAC,QAAQ;AAEb,eAAO,IAAI,QAAQ,eAAe;AAAA,MACtC,CAAC;AAAA,IACT;AACA,QAAI,UAAU;AAEd,SAAK,IAAI,YAAY,UAAU,IAAI,cAAc,0BAA0B,IAAI,WAAW,IAAI,EAAE;AAGhG,QAAI,OAAO,GAAG;AACV,UAAI,eAAe,QAAQ;AACvB;AAAA,MACJ;AACA,WAAK,QAAQ,eAAe,aAAa;AACzC,UAAI,YAAY;AAChB,UAAI,OAAO,WAAW,OAAO,CAAC,QAAQ;AAClC,eAAO,CAAC,IAAI,aAAa,QAAQ,KAAK,IAAI,aAAa,iBAAiB;AAAA,MAC5E,CAAC;AACD,UAAI,KAAK,WAAW,GAAG;AACnB,eAAO,WAAW,OAAO,CAAC,QAAQ;AAC9B,iBAAO,CAAC,IAAI,aAAa,QAAQ;AAAA,QACrC,CAAC;AAED,YAAI,KAAK,WAAW,GAAG;AACnB;AAAA,QACJ;AAAA,MACJ;AAEA,iBAAW,OAAO,MAAM;AACpB,YAAI,YAAY,GAAG;AACf;AAAA,QACJ;AAEA,cAAM,WAAW,IAAI;AACrB,cAAM,QAAQ,IAAI,aAAa,OAAO;AACtC,YAAI,CAAC,OAAO;AACR;AAAA,QACJ;AACA,YAAI,QAAQ,YAAY,GAAG,IAAI,WAAW;AAE1C,aAAK,WAAW,OAAO,KAAK;AAC5B,aAAK,WAAW,OAAO,oBAAoB,IAAI;AAC/C,kBAAU;AAEV,qBAAa;AACb,oBAAY,KAAK,MAAM,SAAS;AAAA,MACpC;AAAA,IACJ,OAAO;AACH,UAAI,eAAe,QAAQ;AACvB;AAAA,MACJ;AACA,WAAK,QAAQ,eAAe,aAAa;AAEzC,YAAM,gBACF,WACK,OAAO,CAAC,QAAQ;AACb,eAAO,CAAC,IAAI,aAAa,QAAQ;AAAA,MACrC,CAAC,EACA,OAAO,CAAC,QAAQ,QAAQ;AACrB,cAAM,QAAQ,IAAI,QAAQ,WAAW,OAAO,SAAS,IAAI,QAAQ,QAAQ,IAAI,IAAI;AACjF,eAAO,SAAS;AAAA,MACpB,GAAG,CAAC,IAAI;AAGhB,UAAI,YAAY,OAAO;AAEvB,YAAM,qBAAqB,WACtB,MAAM,EACN,QAAQ,EACR,OAAO,CAAC,QAAQ;AACb,eAAO,IAAI,aAAa,QAAQ;AAAA,MACpC,CAAC;AAEL,iBAAW,OAAO,oBAAoB;AAClC,YAAI,YAAY,UAAU;AACtB;AAAA,QACJ;AACA,cAAM,WAAW,OAAO,SAAS,IAAI,QAAQ,QAAQ;AAGrD,YAAI,WAAW,WAAW;AACtB,sBAAY;AACZ;AAAA,QACJ;AAEA,cAAM,QAAQ,IAAI,aAAa,OAAO;AACtC,YAAI,CAAC,OAAO;AACR;AAAA,QACJ;AAEA,aAAK,WAAW,OAAO,KAAK;AAC5B,aAAK,WAAW,OAAO,oBAAoB,KAAK;AAChD,kBAAU;AAEV,qBAAa;AACb,oBAAY,KAAK,MAAM,SAAS;AAAA,MACpC;AAAA,IACJ;AAGA,UAAM,SAAS,KAAK,KAAK,OAAO,OAAO;AACvC,UAAM,kBAAkB,QAAQ,KAAK,OAAO,kBAAkB,EAAE,OAAO,CAAC,QAAQ,QAAQ;AACpF,aAAO,SAAS,IAAI;AAAA,IACxB,GAAG,CAAC;AACJ,UAAM,uBAAuB,OAAO,cAAc;AAClD,QAAI,kBAAkB,MAAM;AACxB,eAAS,QAAQ,mBAAmB;AAAA,IACxC,WAAW,uBAAuB,KAAK;AACnC,kBAAY,QAAQ,mBAAmB;AAAA,IAC3C;AACA,QAAI,SAAS;AACT,WAAK,YAAY;AAAA,IACrB;AAEA,eAAW,MAAM;AACb,WAAK,QAAQ,eAAe,aAAa;AAAA,IAC7C,GAAG,GAAI;AACP,SAAK,MAAM,MAAM,aAAa;AAAA,EAClC;AACJ,GAAG,GAAG;AACN,IAAM,iBAAiB,IAAI,eAAe,QAAQ;AAKlD,IAAM,iBAAN,cAA6B,oBAAW;AAAA,EACpC,YAAY,MAAM;AACd,UAAM,IAAI;AAEV,SAAK,kBAAkB;AACvB,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,YAAY;AACR,QAAI,KAAK,KAAK,QAAQ,YAAY;AAC9B,WAAK,QAAQ;AAAA,IACjB;AAAA,EACJ;AAAA,EAEA,eAAe;AACX,SAAK,UAAU;AAAA,EACnB;AAAA,EAEA,UAAU;AACN,QAAI,CAAC,KAAK,KAAK,QAAQ,YAAY;AAC/B;AAAA,IACJ;AACA,mBAAe,QAAQ,KAAK,IAAI;AAChC,SAAK,KAAK,MAAM,UAAU;AAC1B,SAAK,KAAK,MAAM,YAAY;AAAA,EAChC;AAAA,EAEA,YAAY;AACR,mBAAe,UAAU,KAAK,IAAI;AAClC,SAAK,KAAK,MAAM,UAAU;AAC1B,SAAK,KAAK,MAAM,YAAY;AAAA,EAChC;AAAA,EAEA,gBAAgB;AACZ,SAAK,kBAAkB;AACvB,QAAI,OAAO;AACP,mBAAa,KAAK;AAAA,IACtB;AAAA,EACJ;AAAA,EAEA,kBAAkB;AACd,YAAQ,WAAW,MAAM;AACrB,WAAK,kBAAkB;AAAA,IAC3B,GAAG,GAAG;AAAA,EACV;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB;AACf,QAAI,OAAO;AAEX,eAAW,OAAO,KAAK,KAAK,QAAQ,SAAS;AACzC,UAAI,IAAI,kBAAkB;AACtB,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,WAAW;AACP,WAAO,KAAK,KAAK,cAAc,IAAI;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,IAAI;AAChB,QAAI,CAAC,KAAK,KAAK,QAAQ,kBAAkB;AACrC;AAAA,IACJ;AACA,UAAM,KAAK,GAAG,MAAM,EAAE;AACtB,iBAAa,IAAI,SAAS,KAAK;AAC/B,iBAAa,IAAI,QAAQ,qBAAqB;AAC9C,iBAAa,IAAI,iBAAiB,KAAK,SAAS,CAAC;AACjD,iBAAa,IAAI,SAAS,IAAI;AAC9B,OAAG,UAAU,IAAI,GAAG,CAAC,GAAG,gBAAgB,WAAW,oBAAoB,iBAAiB,CAAC;AACzF,OAAG,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,IAAI;AAChB,QAAI,CAAC,KAAK,KAAK,QAAQ,kBAAkB;AACrC;AAAA,IACJ;AACA,UAAM,KAAK,GAAG,MAAM,EAAE;AACtB,iBAAa,IAAI,QAAQ,qBAAqB;AAC9C,iBAAa,IAAI,iBAAiB,KAAK,SAAS,CAAC;AACjD,OAAG,UAAU,IAAI,GAAG,gBAAgB,SAAS;AAC7C,OAAG,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,IAAI;AACd,QAAI,CAAC,KAAK,KAAK,QAAQ,kBAAkB;AACrC;AAAA,IACJ;AAEA,UAAM,KAAK,SAAS,cAAc,IAAI;AACtC,iBAAa,IAAI,QAAQ,iBAAiB;AAC1C,iBAAa,IAAI,iBAAiB,KAAK,SAAS,CAAC;AACjD,OAAG,UAAU,IAAI,GAAG,gBAAgB,SAAS;AAG7C,OAAG,YAAY,8CAA8C,gBAAgB;AAAA;AAAA;AAAA;AAAA,cAIvE,gBAAgB;AAAA;AAAA;AAGtB,OAAG,YAAY,EAAE;AAEjB,OAAG,iBAAiB,SAAS,IAAI;AACjC,OAAG,iBAAiB,aAAa,IAAI;AAAA,EACzC;AAAA,EAEA,oBAAoB;AAChB,QAAI,aAAa;AACjB,QAAI,gBAAgB;AACpB,WAAO,aAAa,KAAK;AACrB;AACA,YAAM,OAAO,KAAK,KAAK,MAAM,sCAAsC,aAAa,IAAI;AACpF,UAAI,MAAM;AACN,sBAAc,KAAK;AAAA,MACvB,OAAO;AACH;AAAA,MACJ;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,IAAI;AAEZ,OAAG,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,IAAI;AAER,OAAG,gBAAgB;AASnB,UAAM,KAAK,GAAG;AACd,UAAM,KAAK,GAAG;AACd,UAAM,OAAO,KAAK,IAAI,IAAI,gBAAgB,OAAO;AACjD,UAAM,QAAQ,KAAK,IAAI,IAAI,gBAAgB,QAAQ;AAEnD,SAAK,cAAc;AAEnB,UAAM,aAAa,SAAS,IAAI,GAAG,gBAAgB,WAAW;AAC9D,QAAI,YAAY;AACZ,kBAAY,IAAI,GAAG,gBAAgB,WAAW;AAC9C,WAAK,MAAM,UAAU;AACrB,YAAM,MAAM,UAAU;AAGtB,YAAM,WAAW,GAAG;AACpB,YAAM,aAAa,QAAQ,UAAU,IAAI,gBAAgB,SAAS;AAElE,iBAAW,OAAO,YAAY;AAE1B,WAAG,YAAY,GAAG;AAClB,qBAAa,KAAK,QAAQ;AAAA,MAC9B;AAEA,eAAS,cAAc,YAAY,QAAQ;AAAA,IAC/C,OAAO;AACH,eAAS,IAAI,GAAG,gBAAgB,WAAW;AAC3C,WAAK,MAAM,UAAU;AACrB,YAAM,MAAM,UAAU;AAGtB,YAAM,WAAW,GAAG,IAAI;AACxB,kBAAY,UAAU,EAAE;AACxB,eAAS,UAAU,GAAG,gBAAgB,YAAY;AAElD,YAAM,aAAa,GAAG,MAAM,QAAQ;AACpC,mBAAa,YAAY,WAAW,KAAK,KAAK,cAAc,IAAI,CAAC;AAEjE,YAAM,aAAa,GAAG,SAAS,UAAU;AACzC,eAAS,YAAY,GAAG,gBAAgB,QAAQ;AAEhD,YAAM,aAAa,QAAQ,IAAI,IAAI,gBAAgB,SAAS;AAC5D,YAAM,aAAa,KAAK,kBAAkB;AAE1C,iBAAW,OAAO,YAAY;AAC1B,cAAM,gBAAgB,GAAG,MAAM,UAAU;AAGzC,cAAM,QAAQ,IAAI,QAAQ;AAC1B,cAAM,WAAW,GAAG,MAAM,aAAa;AAEvC,iBAAS,MAAM,QAAQ,GAAG,UAAU;AACpC,iBAAS,YAAY;AAGrB,sBAAc,YAAY,GAAG;AAC7B,wBAAgB,KAAK,QAAQ;AAAA,MACjC;AAAA,IACJ;AAEA,SAAK,gBAAgB;AAAA,EACzB;AACJ;AAEA,IAAO,0BAAQ;;;AC/Yf,IAAM,aAAN,cAAyB,oBAAW;AAAA;AAAA;AAAA;AAAA,EAIhC,aAAa;AACT,WAAO,KAAK,KAAK,QAAQ,QAAQ,SAAS;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,IAAI;AACjB,UAAM,YAAY,SAAS,cAAc,IAAI;AAC7C,iBAAa,WAAW,QAAQ,qBAAqB;AACrD,iBAAa,WAAW,iBAAiB,KAAK,KAAK,cAAc,IAAI,CAAC;AACtE,cAAU,UAAU,IAAI,GAAG,CAAC,cAAc,mBAAmB,oBAAoB,KAAK,WAAW,CAAC;AAClG,cAAU,WAAW;AACrB,OAAG,YAAY,SAAS;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,IAAI;AACjB,UAAM,YAAY,SAAS,cAAc,IAAI;AAC7C,cAAU,aAAa,QAAQ,qBAAqB;AACpD,iBAAa,WAAW,iBAAiB,KAAK,KAAK,cAAc,IAAI,CAAC;AACtE,cAAU,UAAU,IAAI,GAAG,CAAC,cAAc,KAAK,WAAW,CAAC;AAC3D,cAAU,WAAW;AACrB,OAAG,YAAY,SAAS;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,IAAI,MAAM;AACpB,UAAMC,UAAS,KAAK,KAAK;AACzB,UAAM,KAAK,SAAS,cAAc,IAAI;AACtC,iBAAa,IAAI,QAAQ,UAAU;AACnC,iBAAa,IAAI,iBAAiB,KAAK,KAAK,cAAc,IAAI,CAAC;AAC/D,OAAG,UAAU,IAAI,GAAG,CAAC,cAAc,KAAK,WAAW,CAAC;AACpD,OAAG,WAAW;AAGd,UAAM,gBAAgB,SAAS,cAAc,QAAQ;AACrD,kBAAc,UAAU,IAAI,mBAAmB;AAC/C,kBAAc,YAAY;AAC1B,OAAG,YAAY,aAAa;AAC5B,OAAG,eAAe,SAAS,CAAC,OAAO;AAC/B,SAAG,gBAAgB;AACnB,SAAG,OAAO,cAAc,UAAU,OAAO,mBAAmB;AAAA,IAChE,CAAC;AAED,eAAW,UAAU,KAAK,KAAK,QAAQ,SAAS;AAC5C,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,UAAI,OAAO,MAAM;AACb,eAAO,YAAY,OAAO;AAAA,MAC9B,OAAO;AACH,eAAO,YAAY,OAAO,SAAS,OAAO;AAAA,MAC9C;AACA,UAAI,OAAO,OAAO;AACd,eAAO,QAAQ,OAAO;AAAA,MAC1B;AACA,UAAI,OAAO,KAAK;AACZ,eAAO,OAAO;AACd,eAAO,aAAa,YAAY,OAAO,KAAK,IAAI;AAAA,MACpD;AACA,UAAI,OAAO,OAAO;AACd,eAAO,UAAU,IAAI,GAAG,OAAO,MAAM,MAAM,GAAG,CAAC;AAAA,MACnD;AACA,YAAM,gBAAgB,CAAC,OAAO;AAC1B,WAAG,gBAAgB;AACnB,YAAI,OAAO,SAAS;AAChB,gBAAM,IAAI,QAAQA,QAAO,UAAU;AACnC,cAAI,CAAC,GAAG;AACJ,eAAG,eAAe;AAClB;AAAA,UACJ;AAAA,QACJ;AACA,iBAAS,KAAK,MAAM,UAAU;AAAA,UAC1B,MAAM;AAAA,UACN,QAAQ,OAAO;AAAA,QACnB,CAAC;AAAA,MACL;AACA,aAAO,iBAAiB,SAAS,aAAa;AAC9C,SAAG,YAAY,MAAM;AAGrB,UAAI,OAAO,SAAS;AAChB,WAAG,UAAU,IAAI,eAAe;AAChC,WAAG,iBAAiB,SAAS,aAAa;AAAA,MAC9C;AAAA,IACJ;AAEA,OAAG,YAAY,EAAE;AAAA,EACrB;AAAA,EAEA,IAAI,cAAc;AACd,QAAI,KAAK,KAAK,QAAQ,QAAQ,SAAS,KAAK,CAAC,KAAK,KAAK,QAAQ,iBAAiB;AAC5E,aAAO,cAAc,KAAK,KAAK,QAAQ,QAAQ,MAAM;AAAA,IACzD;AACA,WAAO;AAAA,EACX;AACJ;AAEA,IAAO,sBAAQ;;;AC7Gf,IAAM,iBAAN,cAA6B,oBAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQpC,kBAAkB,IAAI,QAAQ,MAAM,GAAG;AACnC,UAAM,SAAS,KAAK,KAAK,aAAa,IAAI;AAC1C,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,OAAO,OAAO,gBAAgB;AACpC,QAAI,MAAM,SAAS,SAAS;AACxB,YAAM,YAAY;AAAA,IACtB;AACA,QAAI,MAAM,SAAS,WAAW;AAC1B,YAAM,OAAO;AACb,YAAM,YAAY;AAAA,IACtB;AACA,UAAM,eAAe;AACrB,UAAM,aAAa;AACnB,UAAM,WAAW;AACjB,UAAM,UAAU,IAAI,aAAa;AACjC,UAAM,OAAO,GAAG,OAAO,QAAQ,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,OAAO,KAAK;AAClE,UAAM,QAAQ,KAAK,OAAO,KAAK;AAC/B,UAAM,QAAQ,QAAQ,OAAO;AAG7B,UAAM,iBAAiB,SAAS,CAAC,OAAO,GAAG,gBAAgB,CAAC;AAE5D,UAAM,iBAAiB,YAAY,CAAC,OAAO;AACvC,UAAI,GAAG,SAAS,YAAY;AACxB,cAAM,MAAM,GAAG,WAAW,GAAG;AAC7B,YAAI,QAAQ,MAAM,QAAQ,SAAS;AAC/B,gBAAM,KAAK;AACX,aAAG,eAAe;AAAA,QACtB;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,UAAM,iBAAiB,QAAQ,MAAM;AAEjC,UAAI,MAAM,UAAU,KAAK,MAAM,QAAQ,KAAK,GAAG;AAC3C;AAAA,MACJ;AAEA,WAAK,MAAM,QAAQ,KAAK,IAAI,MAAM;AAElC,eAAS,KAAK,MAAM,QAAQ;AAAA,QACxB,MAAM;AAAA,QACN,OAAO,MAAM;AAAA,MACjB,CAAC;AAAA,IACL,CAAC;AACD,OAAG,YAAY,KAAK;AAAA,EACxB;AACJ;AAEA,IAAO,0BAAQ;;;ACzDf,IAAM,iBAAN,cAA6B,oBAAW;AAAA,EACpC,YAAY;AAER,QAAI,KAAK,KAAK,QAAQ,gBAAgB,KAAK,KAAK,QAAQ,gBAAgB;AACpE,WAAK,IAAI;AAAA,IACb;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM;AACF,UAAM,OAAO,KAAK;AAClB,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,CAAC,SAAS;AACV;AAAA,IACJ;AACA,UAAM,MAAM,QACP,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,EAClB,KAAK,EAAE;AAEZ,UAAM,WAAW;AAAA;AAAA,cAEX,GAAG;AAAA,+BACc,GAAG;AAAA,8CACY,GAAG;AAAA;AAAA,4BAErB,GAAG;AAAA;AAAA;AAAA;AAIvB,QAAI,CAAC,EAAE,YAAY,GAAG;AAClB,YAAM,cAAc,EAAE,MAAM,KAAK,EAAE,MAAM;AACzC,YAAM,WAAW,QAAQ,KAAK,YAAY,OAAO,IAAI,cAAc;AACnE,kBAAY,mBAAmB,UAAU,QAAQ;AAAA,IACrD;AACA,KAAC,EAAE,IAAI,GAAG,IAAI,IAAI,KAAK,KAAK,mBAAmB,cAAc,aAAa,OAAO,QAAQ;AAAA,EAC7F;AACJ;AAEA,IAAO,0BAAQ;;;AC/Bf,IAAM,YAAN,cAAwB,oBAAW;AAAA,EAC/B,YAAY,MAAM;AACd,UAAM,IAAI;AACV,SAAK,cAAc;AACnB,SAAK,kBAAkB;AACvB,SAAK,eAAe;AACpB,SAAK,aAAa;AAClB,SAAK,IAAI,MAAM;AAAA,EACnB;AAAA,EAEA,MAAM,YAAY;AACd,SAAK,IAAI,WAAW;AACpB,UAAM,OAAO,KAAK;AAElB,SAAK,IAAI,KAAK,OAAO;AAErB,QAAI,CAAC,KAAK,QAAQ,WAAW;AACzB,WAAK,IAAI,UAAU;AACnB;AAAA,IACJ;AAEA,SAAK,IAAI,SAAS;AAElB,UAAM,cAAc,KAAK,UAAU;AACnC,QAAI,aAAa;AACb,YAAM,iBAAiB,YAAY;AAC/B,YAAI,CAAC,KAAK,QAAQ,OAAQ;AAC1B,YAAI,UAAU,KACV,QAAQ,KAAK,IAAI,GAAG;AACxB,gBAAQ,YAAY,CAAC,KAAK,QAAQ,SAAS,WAAW,KAAK,IAAI,IAAI,QAAQ,SAAS;AAChF,gBAAM,IAAI,QAAQ,aAAW,sBAAsB,OAAO,CAAC;AAAA,QAC/D;AACA,qBAAa,KAAK,IAAI,8BAA8B;AAAA,MACxD;AACA,YAAM,eAAe,YAAY;AAC7B,cAAM,eAAe;AAErB,aAAK,IAAI,cAAc;AAEvB,mBAAW,OAAO,YAAY,SAAS;AACnC,cAAI,IAAI,QAAQ;AACZ,kBAAM,UAAU,KAAK,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI,KAAK;AACtE,oBAAQ,SAAS;AAAA,UACrB;AAAA,QACJ;AAEA,aAAK,IAAI,kBAAkB;AAC3B,aAAK,QAAQ,UAAU,YAAY;AACnC,YAAI,KAAK,QAAQ,QAAQ;AACrB,eAAK,OAAO,YAAY;AACxB,eAAK,QAAQ,YAAY;AACzB,eAAK,OAAO,YAAY;AAAA,QAC5B;AAAA,MACJ;AACA,YAAM,aAAa;AAAA,IACvB;AAEA,SAAK,cAAc;AACnB,SAAK,IAAI,eAAe,KAAK,WAAW;AAExC,UAAM,aAAa,KAAK;AACxB,SAAK,WAAW,YAAa,MAAM;AAC/B,aAAO,WAAW,MAAM,MAAM,IAAI,EAAE,QAAQ,MAAM;AAC9C,cAAM,YAAY,KAAK,QAAQ;AAC/B,kBAAU,IAAI,YAAY,KAAK,QAAQ,OAAO;AAE9C,YAAI,CAAC,KAAK,UAAU,SAAS,gBAAgB,GAAG;AAC5C,oBAAU,IAAI,4BAA4B;AAC1C;AAAA,QACJ;AAEA,kBAAU,IAAI,yCAAyC,KAAK,QAAQ,OAAO;AAE3E,YAAI,UAAU,eAAe,CAAC,UAAU,iBAAiB;AACrD,oBAAU,IAAI,sBAAsB;AAEpC,gBAAM,kBAAkB,QAAQ,MAAM,wCAAwC;AAC9E,qBAAW,MAAM,iBAAiB;AAC9B,eAAG,aAAa,aAAa,MAAM;AAAA,UACvC;AAEA,eAAK,cAAc,sCAAsC,UAAU,YAAY,IAAI,IAAI,GACjF,aAAa,aAAa,UAAU,YAAY,OAAO;AAE7D,gBAAMC,WAAU,QAAQ,KAAK,WAAW,iBAAiB;AACzD,oBAAU,IAAI,WAAWA,QAAO;AAEhC,qBAAW,MAAMA,UAAS;AACtB,eAAG,QAAQ,WAAW,aAAa,UAAU,GAAG,QAAQ,IAAI,KAAK;AACjE,sBAAU,IAAI,EAAE,MAAM,GAAG,QAAQ,MAAM,KAAK,GAAG,OAAO,UAAU,CAAC;AAAA,UACrE;AACA,oBAAU,kBAAkB;AAAA,QAChC;AAGA,cAAM,WAAW;AAAA,UACb,MAAM,KAAK;AAAA,UACX,OAAO,KAAK;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,SAAS,KAAK,QAAQ;AAAA,UACtB,SAAS,CAAC;AAAA,UACV,SAAS,KAAK,QAAQ,QAAQ,IAAI,CAAC,SAAS,EAAE,OAAO,IAAI,OAAO,QAAQ,IAAI,OAAO,EAAE;AAAA,UACrF,MAAM,KAAK,QAAQ;AAAA,UACnB,SAAS,KAAK,WAAW;AAAA,UACzB,UAAU,OAAO;AAAA,QACrB;AAEA,cAAM,UAAU,KAAK,WAAW;AAChC,kBAAU,IAAI,WAAW,OAAO;AAEhC,mBAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACpC,mBAAS,QAAQ,GAAG,IAAI,QAAQ,GAAG,KAAK;AACxC,oBAAU,IAAI,EAAE,KAAK,KAAK,QAAQ,GAAG,GAAG,UAAU,QAAQ,CAAC;AAAA,QAC/D;AAEA,kBAAU,IAAI,mBAAmB,QAAQ;AACzC,kBAAU,UAAU,QAAQ;AAE5B,YAAI,CAAC,KAAK,QAAQ,UAAU,UAAU,eAAe,CAAC,UAAU,cAAc;AAC1E,oBAAU,eAAe;AACzB,eAAK,WAAW;AAChB,eAAK,OAAO,UAAU,YAAY;AAClC,eAAK,YAAY;AACjB,oBAAU,IAAI,aAAa;AAAA,QAC/B;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,UAAM,cAAc,MAAM;AACtB,YAAM,YAAY,KAAK,QAAQ;AAC/B,YAAM,QAAQ,UAAU,UAAU;AAClC,UAAI,CAAC,OAAO;AACR;AAAA,MACJ;AACA,YAAM,UAAU,KAAK,QAAQ,QAAQ,IAAI,CAAC,SAAS,EAAE,OAAO,IAAI,OAAO,QAAQ,IAAI,OAAO,EAAE;AAC5F,YAAM,OAAO,KAAK,QAAQ;AAC1B,YAAM,UAAU,KAAK,WAAW;AAChC,YAAM,WAAW,OAAO;AACxB,gBAAU,UAAU,KAAK;AAAA,IAC7B;AAEA,aAAS,iBAAiB,aAAa,WAAW;AAClD,SAAK,iBAAiB,kBAAkB,WAAW;AAEnD,SAAK,iBAAiB,gBAAgB,CAAC,OAAO;AAC1C,UAAI,CAAC,KAAK,UAAU,SAAS,gBAAgB,KAAK,KAAK,UAAU,SAAS,YAAY,GAAG;AACrF;AAAA,MACJ;AAEA,UAAI,CAAC,KAAK,QAAQ,QAAQ;AACtB,oBAAY;AAAA,MAChB;AAEA,YAAM,YAAY,KAAK,QAAQ;AAC/B,UAAI,CAAC,UAAU,eAAe,CAAC,UAAU,iBAAiB;AACtD;AAAA,MACJ;AAEA,UAAI,CAAC,UAAU,cAAc;AACzB,kBAAU,eAAe;AACzB,aAAK,OAAO;AACZ,kBAAU,IAAI,kBAAkB;AAAA,MACpC,WAAW,CAAC,UAAU,YAAY;AAC9B,kBAAU,aAAa;AACvB,eAAO,SAAS,EAAE,KAAK,UAAU,YAAY,UAAU,MAAM,GAAG,UAAU,UAAU,CAAC;AAAA,MACzF;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,OAAO,MAAM;AACT,SAAK,KAAK,IAAI,iBAAiB,GAAG,IAAI;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACR,QAAI;AACJ,QAAI;AACA,cAAQ,KAAK,MAAM,eAAe,QAAQ,iBAAiB,KAAK,KAAK,EAAE,EAAE,CAAC;AAAA,IAC9E,SAAS,GAAG;AAAA,IAAC;AACb,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,OAAO;AACb,mBAAe,QAAQ,iBAAiB,KAAK,KAAK,EAAE,IAAI,KAAK,UAAU,KAAK,CAAC;AAAA,EACjF;AACJ;AAEA,IAAO,qBAAQ;;;ACxLf,kBAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGD,IAAI,CAAC,eAAe,IAAI,WAAW,GAAG;AACpC,iBAAe,OAAO,aAAa,iBAAQ;AAC7C;AAEA,IAAOC,qBAAQ;AAEf,IAAM,SAAS,OAAO,eAAe,cAAc,aAAa;AAChE,OAAO,WAAW;", + "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], + "mappings": "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", "names": ["col", "e", "th", "labels", "filters", "data_grid_default"] } diff --git a/dist/data-grid.min.js b/dist/data-grid.min.js index c93242d..36bc2b5 100644 --- a/dist/data-grid.min.js +++ b/dist/data-grid.min.js @@ -1,4 +1,4 @@ -function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUpperCase())}function V(r){if(r==="true")return!0;if(r==="false")return!1;if(r===""||r==="null")return null;if(r===Number(r).toString())return Number(r);if(r&&typeof r.substring=="function"&&["[","{"].includes(r.substring(0,1)))try{let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(decodeURIComponent(t))}catch{return console.error(`Failed to parse ${r}`),{}}return r}var zt=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];function vt(r){return zt.includes(r)?{passive:!0}:{}}function D(r,t){return r.getAttribute(t)}function U(r,t){return r.hasAttribute(t)}function c(r,t,e="",i=!1){i&&U(r,t)||r.setAttribute(t,`${e}`)}function k(r,t){U(r,t)&&r.removeAttribute(t)}function A(r,t,e){r.addEventListener(t,e,vt(t))}function O(r,t,e){r.removeEventListener(t,e,vt(t))}function y(r,t,e={},i=!1){let o={};i&&(o.bubbles=!0),e&&(o.detail=e),r.dispatchEvent(new CustomEvent(t,o))}function T(r,t){return r.classList.contains(t)}function E(r,t){r.classList.add(...t.split(" "))}function W(r,t){r.classList.remove(...t.split(" "))}function yt(r,t){r.classList.toggle(t)}function I(r,t=document){return r instanceof HTMLElement?r:t.querySelector(r)}function Y(r,t=document){return Array.from(t.querySelectorAll(r))}function N(r,t){return I(t,r)}function g(r,t){return Y(t,r)}function x(r,t=null){let e=document.createElement(r);return t&&t.appendChild(e),e}function xt(r,t){t.parentNode.insertBefore(r,t.nextSibling)}var J=class extends HTMLElement{constructor(t={}){super(),this.options=Object.assign({},this.defaultOptions,this.normalizedDataset,t),this.log("constructor"),this.setup=!1,this.fireEvents=!0,this._ready(),this.log("ready")}get defaultOptions(){return{}}getOption(t){return this.options[t]}setOption(t,e){c(this,`data-${t}`,e)}toggleOption(t){c(this,`data-${t}`,!this.getOption(t))}get normalizedDataset(){let t=this.dataset.config?JSON.parse(this.dataset.config):{},e={...this.dataset};for(let i in e)i==="config"||!e.hasOwnProperty(i)||typeof e[i]=="function"||(e[i]=V(e[i]));return Object.assign(e,t),e}static template(){return""}_ready(){}log(...t){this.options.debug&&console.log(`[${D(this,"id")}] `,...t)}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}_connected(){}connectedCallback(){this.setup||(this.setup=!0,setTimeout(async()=>{this.log("connectedCallback");let t=document.createElement("template");t.innerHTML=this.constructor.template(),this.appendChild(t.content.cloneNode(!0)),await this._connected(),y(this,"connected")},0))}_disconnected(){}disconnectedCallback(){setTimeout(()=>{!this.isConnected&&this.setup&&(this.log("disconnectedCallback"),this._disconnected(),y(this,"disconnected"),this.setup=!1)},0)}get transformAttributes(){return{}}attributeChangedCallback(t,e,i){if(e===i)return;this.log(`attributeChangedCallback: ${t}`);let o=!1,n=this.transformAttributes[t]??V,s=t;s.indexOf("data-")===0&&(s=s.slice(5),o=!0),s=F(s),o?this.options[s]=n(i):this[s]=n(i),this.fireEvents&&this[`${s}Changed`]&&this[`${s}Changed`]()}},Ct=J;function Z(r,t,e,i=!1){let o=document.createElement("option");o.value=`${t}`,i&&(o.selected=!0),o.label=e,r.appendChild(o)}function Q(r,t={}){for(let e of Object.keys(t))if(Array.isArray(t[e]))for(let i of Object.keys(t[e]))r.searchParams.append(isNaN(i)?`${e}[${i}]`:e,t[e][i]);else r.searchParams.append(e,t[e])}function X(r){if(typeof r=="string"){if(r[0]==="["){let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(t)}return r.split(",")}return Array.isArray(r)?r:(console.error("Invalid array",r),[])}function tt(r){let t=r.getBoundingClientRect(),e=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+i,left:t.left+e}}function M(r,t){return r.replace(/\{([^}]+)?\}/g,(e,i)=>t[i])}var et;function _(r,t=document.body,e=!1){let i=window.getComputedStyle(t||document.createElement("div")),o=i.getPropertyValue("font-weight")||"normal",n=i.getPropertyValue("font-size")||"1rem",s=i.getPropertyValue("font-family")||"Arial",l=0;if(e){let u=i.getPropertyValue("padding-left")||"0",h=i.getPropertyValue("padding-right")||"0";l=Number.parseInt(u)+Number.parseInt(h)}et||(et=document.createElement("canvas"));let a=et.getContext("2d");a.font=`${o} ${n} ${s}`;let d=a.measureText(r);return Number.parseInt(d.width)+l}function q(r){return Math.random().toString(36).replace("0.",r||"")}function G(r,t=300){let e=null;return(...i)=>{clearTimeout(e),e=setTimeout(()=>{e=null,r(...i)},t)}}var B={},C={itemsPerPage:"Items per page",gotoPage:"Go to page",gotoFirstPage:"Go to first page",gotoPrevPage:"Go to previous page",gotoNextPage:"Go to next page",gotoLastPage:"Go to last page",of:"of",items:"items",resizeColumn:"Resize column",noData:"No data",areYouSure:"Are you sure?",networkError:"Network response error"};function wt(r,t){t.width&&c(r,"width",t.width),t.class&&E(r,t.class),t.hidden&&(c(r,"hidden",""),t.responsiveHidden&&E(r,"dg-responsive-hidden"))}var it=class r extends Ct{_filterSelector="[id^=dg-filter]";_excludedRowElementSelector="a,button,input,select,textarea";_excludedKeys=[37,39,38,40,45,36,35,33,34,27,20,16,17,91,92,18,93,144,231,"ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Insert","Home","End","PageUp","PageDown","Escape","CapsLock","Shift","Control","Meta","Alt","ContextMenu","NumLock","Unidentified"];_ready(){c(this,"id",this.options.id??q("el-"),!0),this.data=[],this.originalData,this.options=this.options||this.defaultOptions,this.options.singleSelect&&(this.options.selectable=!0),this.fireEvents=!1,this.page=this.options.defaultPage||1,this.pages=0,this.meta,this.plugins={};for(let[t,e]of Object.entries(B))this.plugins[t]=new e(this);for(let t of r.observedAttributes)t.indexOf("data-")===0&&c(this,t,this.options[F(t.slice(5))])}static template(){return` +function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUpperCase())}function V(r){if(r==="true")return!0;if(r==="false")return!1;if(r===""||r==="null")return null;if(r===Number(r).toString())return Number(r);if(r&&typeof r.substring=="function"&&["[","{"].includes(r.substring(0,1)))try{let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(decodeURIComponent(t))}catch{return console.error(`Failed to parse ${r}`),{}}return r}var zt=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];function vt(r){return zt.includes(r)?{passive:!0}:{}}function D(r,t){return r.getAttribute(t)}function U(r,t){return r.hasAttribute(t)}function c(r,t,e="",i=!1){i&&U(r,t)||r.setAttribute(t,`${e}`)}function k(r,t){U(r,t)&&r.removeAttribute(t)}function A(r,t,e){r.addEventListener(t,e,vt(t))}function O(r,t,e){r.removeEventListener(t,e,vt(t))}function y(r,t,e={},i=!1){let o={};i&&(o.bubbles=!0),e&&(o.detail=e),r.dispatchEvent(new CustomEvent(t,o))}function T(r,t){return r.classList.contains(t)}function E(r,t){r.classList.add(...t.split(" "))}function W(r,t){r.classList.remove(...t.split(" "))}function yt(r,t){r.classList.toggle(t)}function I(r,t=document){return r instanceof HTMLElement?r:t.querySelector(r)}function Y(r,t=document){return Array.from(t.querySelectorAll(r))}function N(r,t){return I(t,r)}function g(r,t){return Y(t,r)}function x(r,t=null){let e=document.createElement(r);return t&&t.appendChild(e),e}function xt(r,t){t.parentNode.insertBefore(r,t.nextSibling)}var J=class extends HTMLElement{constructor(t={}){super(),this.options=Object.assign({},this.defaultOptions,this.normalizedDataset,t),this.log("constructor"),this.setup=!1,this.fireEvents=!0,this._ready(),this.log("ready")}get defaultOptions(){return{}}getOption(t){return this.options[t]}setOption(t,e){c(this,`data-${t}`,e)}toggleOption(t){c(this,`data-${t}`,!this.getOption(t))}get normalizedDataset(){let t=this.dataset.config?JSON.parse(this.dataset.config):{},e={...this.dataset};for(let i in e)i==="config"||!e.hasOwnProperty(i)||typeof e[i]=="function"||(e[i]=V(e[i]));return Object.assign(e,t),e}static template(){return""}_ready(){}log(...t){this.options.debug&&console.log(`[${D(this,"id")}] `,...t)}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}_connected(){}connectedCallback(){this.setup||(this.setup=!0,setTimeout(async()=>{this.log("connectedCallback");let t=document.createElement("template");t.innerHTML=this.constructor.template(),this.appendChild(t.content.cloneNode(!0)),await this._connected(),y(this,"connected")},0))}_disconnected(){}disconnectedCallback(){setTimeout(()=>{!this.isConnected&&this.setup&&(this.log("disconnectedCallback"),this._disconnected(),y(this,"disconnected"),this.setup=!1)},0)}get transformAttributes(){return{}}attributeChangedCallback(t,e,i){if(e===i)return;this.log(`attributeChangedCallback: ${t}`);let o=!1,n=this.transformAttributes[t]??V,s=t;s.indexOf("data-")===0&&(s=s.slice(5),o=!0),s=F(s),o?this.options[s]=n(i):this[s]=n(i),this.fireEvents&&this[`${s}Changed`]&&this[`${s}Changed`]()}},Ct=J;function Z(r,t,e,i=!1){let o=document.createElement("option");o.value=`${t}`,i&&(o.selected=!0),o.label=e,r.appendChild(o)}function Q(r,t={}){for(let e of Object.keys(t))if(Array.isArray(t[e]))for(let i of Object.keys(t[e]))r.searchParams.append(isNaN(i)?`${e}[${i}]`:e,t[e][i]);else r.searchParams.append(e,t[e])}function X(r){if(typeof r=="string"){if(r[0]==="["){let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(t)}return r.split(",")}return Array.isArray(r)?r:(console.error("Invalid array",r),[])}function tt(r){let t=r.getBoundingClientRect(),e=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+i,left:t.left+e}}function M(r,t){return r.replace(/\{([^}]+)?\}/g,(e,i)=>t[i])}var et;function _(r,t=document.body,e=!1){let i=window.getComputedStyle(t||document.createElement("div")),o=i.getPropertyValue("font-weight")||"normal",n=i.getPropertyValue("font-size")||"1rem",s=i.getPropertyValue("font-family")||"Arial",a=0;if(e){let u=i.getPropertyValue("padding-left")||"0",h=i.getPropertyValue("padding-right")||"0";a=Number.parseInt(u)+Number.parseInt(h)}et||(et=document.createElement("canvas"));let l=et.getContext("2d");l.font=`${o} ${n} ${s}`;let d=l.measureText(r);return Number.parseInt(d.width)+a}function q(r){return Math.random().toString(36).replace("0.",r||"")}function G(r,t=300){let e=null;return(...i)=>{clearTimeout(e),e=setTimeout(()=>{e=null,r(...i)},t)}}var B={},C={itemsPerPage:"Items per page",gotoPage:"Go to page",gotoFirstPage:"Go to first page",gotoPrevPage:"Go to previous page",gotoNextPage:"Go to next page",gotoLastPage:"Go to last page",of:"of",items:"items",resizeColumn:"Resize column",noData:"No data",areYouSure:"Are you sure?",networkError:"Network response error"};function wt(r,t){t.width&&c(r,"width",t.width),t.class&&E(r,t.class),t.hidden&&(c(r,"hidden",""),t.responsiveHidden&&E(r,"dg-responsive-hidden"))}var it=class r extends Ct{_filterSelector="[id^=dg-filter]";_excludedRowElementSelector="a,button,input,select,textarea";_excludedKeys=[37,39,38,40,45,36,35,33,34,27,20,16,17,91,92,18,93,144,231,"ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Insert","Home","End","PageUp","PageDown","Escape","CapsLock","Shift","Control","Meta","Alt","ContextMenu","NumLock","Unidentified"];_ready(){c(this,"id",this.options.id??q("el-"),!0),this.data=[],this.originalData,this.options=this.options||this.defaultOptions,this.options.singleSelect&&(this.options.selectable=!0),this.fireEvents=!1,this.page=this.options.defaultPage||1,this.pages=0,this.meta,this.plugins={};for(let[t,e]of Object.entries(B))this.plugins[t]=new e(this);for(let t of r.observedAttributes)t.indexOf("data-")===0&&c(this,t,this.options[F(t.slice(5))])}static template(){return` @@ -36,13 +36,13 @@ function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUppe
-`}get labels(){return C}static getLabels(){return C}static setLabels(t){C=Object.assign(C,t)}get noData(){return this.options.noData||this.labels.noData}#t(t){!this.hasDataError&&t.getAttribute("data-empty")!==this.noData&&t.setAttribute("data-empty",this.noData)}get defaultColumn(){return{field:"",title:"",width:0,class:"",attr:"",hidden:!1,editable:!1,noSort:!1,responsive:1,responsiveHidden:!1,format:"",transform:"",filterType:"text",firstFilterOption:{value:"",text:""}}}get defaultOptions(){return{id:null,url:"",perPage:10,debug:!1,filter:!1,menu:!1,sort:!1,server:!1,serverParams:{start:"start",length:"length",search:"search",sort:"sort",sortDir:"sortDir",dataKey:"data",metaKey:"meta",metaTotalKey:"total",metaFilteredKey:"filtered",optionsKey:"options",paramsKey:"params"},defaultSort:"",reorder:!1,dir:"ltr",perPageValues:[10,25,50,100,250],hidePerPage:!1,columns:[],actions:[],collapseActions:!1,selectable:!1,selectVisibleOnly:!0,singleSelect:!1,defaultPage:1,resizable:!1,autosize:!0,expand:!1,autoheight:!0,autohidePager:!1,responsive:!1,responsiveToggle:!0,filterOnEnter:!0,filterKeypressDelay:500,spinnerClass:"",saveState:!1,errorMessage:"",noData:""}}get isInit(){return this.classList.contains("dg-initialized")}get hasDataError(){return this.classList.contains("dg-network-error")}static registerPlugins(t){B=t}static unregisterPlugins(t=null){t===null?B={}:delete B[t]}static registeredPlugins(){return B}convertColumns(t){let e=[];if(typeof t=="object"&&!Array.isArray(t))for(let i of Object.keys(t)){let o=Object.assign({},this.defaultColumn);o.title=t[i],o.field=i,e.push(o)}else for(let i of t){let o=Object.assign({},this.defaultColumn);typeof i=="string"?(o.title=i,o.field=i):typeof i=="object"?(o=Object.assign(o,i),o.field||console.error("Invalid column definition",i),o.title||(o.title=o.field)):console.error("Column definition must be a string or an object"),e.push(o)}return e}static get observedAttributes(){return["page","data-filter","data-sort","data-debug","data-reorder","data-menu","data-selectable","data-single-select","data-url","data-per-page","data-responsive"]}get transformAttributes(){return{columns:t=>this.convertColumns(X(t)),actions:t=>X(t),defaultPage:t=>Number.parseInt(t),perPage:t=>Number.parseInt(t)}}get thead(){return I("thead",this)}get tbody(){return I("tbody",this)}get tfoot(){return I("tfoot",this)}get page(){return Number.parseInt(this.getAttribute("page"))}set page(t){c(this,"page",this.constrainPageValue(t))}urlChanged(t=!1){return t&&!this.isInit?this:(this.reconfig(),this.loadData().then(()=>this.configureUi()))}reconfig(){let t=this.options.columns;return this.options.columns=[],this.configureUi(),this.options.columns=t,this}constrainPageValue(t){let e=t;return this.pages1&&this.page*this.options.perPage>this.totalRecords();)t--;t!==this.page?this.page=t:this.reload(()=>{(!this.plugins.FixedHeight||!this.plugins.FixedHeight.hasFixedHeight)&&this.selectPerPage.scrollIntoView()})}dirChanged(){c(this,"dir",this.options.dir)}defaultSortChanged(){this.sortChanged()}perPageValuesChanged(){if(this.selectPerPage){for(;this.selectPerPage.lastChild;)this.selectPerPage.removeChild(this.selectPerPage.lastChild);for(let t of this.options.perPageValues)Z(this.selectPerPage,t,t,t===this.options.perPage)}}async _connected(){this.table=this.querySelector("table"),this.btnFirst=this.querySelector(".dg-btn-first"),this.btnPrev=this.querySelector(".dg-btn-prev"),this.btnNext=this.querySelector(".dg-btn-next"),this.btnLast=this.querySelector(".dg-btn-last"),this.selectPerPage=this.querySelector(".dg-select-per-page"),this.inputPage=this.querySelector(".dg-input-page"),this.getFirst=this.getFirst.bind(this),this.getPrev=this.getPrev.bind(this),this.getNext=this.getNext.bind(this),this.getLast=this.getLast.bind(this),this.changePerPage=this.changePerPage.bind(this),this.gotoPage=this.gotoPage.bind(this),this.btnFirst.addEventListener("click",this.getFirst),this.btnPrev.addEventListener("click",this.getPrev),this.btnNext.addEventListener("click",this.getNext),this.btnLast.addEventListener("click",this.getLast),this.selectPerPage.addEventListener("change",this.changePerPage),this.selectPerPage.toggleAttribute("hidden",this.options.hidePerPage),this.inputPage.addEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))await t.connected();this.dirChanged(),this.perPageValuesChanged(),await this.init()}_disconnected(){this.btnFirst?.removeEventListener("click",this.getFirst),this.btnPrev?.removeEventListener("click",this.getPrev),this.btnNext?.removeEventListener("click",this.getNext),this.btnLast?.removeEventListener("click",this.getLast),this.selectPerPage?.removeEventListener("change",this.changePerPage),this.inputPage?.removeEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))t.disconnected()}init(){return this.loadData().finally(()=>{this.configureUi(),this.sortChanged(),this.classList.add("dg-initialized"),this.filterChanged(),this.reorderChanged(),this.dirChanged(),this.perPageValuesChanged(),this.pageChanged(),this.fireEvents=!0,this.log("initialized")})}getCol(t){let e=null;for(let i of this.options.columns)i.field===t&&(e=i);return e}getColProp(t,e){let i=this.getCol(t);return i?i[e]:null}setColProp(t,e,i){let o=this.getCol(t);o&&(o[e]=i)}visibleColumns(){return this.options.columns.filter(t=>!t.hidden)}hiddenColumns(){return this.options.columns.filter(t=>t.hidden===!0)}showColumn(t,e=!0){this.setColProp(t,"hidden",!1),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"visible"})}hideColumn(t,e=!0){this.setColProp(t,"hidden",!0),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"hidden"})}startColIndex(){let t=1;return this.options.selectable&&this.plugins.SelectableRows&&t++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&t++,t}isSticky(){return this.hasAttribute("sticky")}columnsLength(t=!1){let e=0;for(let i of this.options.columns)t&&i.hidden||i.attr||e++;return this.options.selectable&&this.plugins.SelectableRows&&e++,this.options.actions.length&&this.plugins.RowActions&&e++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&e++,e}configureUi(){if(!this.table)return this;if(this.table.style.visibility="hidden",this.renderTable(),this.options.responsive&&this.plugins.ResponsiveGrid||(this.table.style.visibility="visible"),!this.rowHeight){let t=N(this,"tbody tr")||N(this,"table tr");t&&(this.rowHeight=t.offsetHeight)}return this.#t(this.tbody),this.fixPage()}filterChanged(){let t=this.querySelector("thead tr.dg-head-filters");this.options.filter?k(t,"hidden"):(this.clearFilters(),c(t,"hidden",""))}reorderChanged(){let t=g(this,"thead tr.dg-head-columns th");for(let e of t)e.classList.contains("dg-selectable")||e.classList.contains("dg-actions")||(this.options.reorder&&this.plugins.DraggableHeaders?e.draggable=!0:e.removeAttribute("draggable"))}sortChanged(){this.log("toggle sort");let t=g(this,"thead tr.dg-head-columns th");for(let e of t){let i=e.getAttribute("field");if(e.classList.contains("dg-not-sortable")||!this.fireEvents&&i===this.options.defaultSort)return;this.options.sort&&!this.getColProp(i,"noSort")?c(e,"aria-sort","none"):k(e,"aria-sort")}}selectableChanged(){this.renderTable()}addRow(t){Array.isArray(this.originalData)&&(this.log("add row"),this.originalData.push(t),this.data=this.originalData.slice(),this.sortData())}removeRow(t=null,e=null){if(!Array.isArray(this.originalData))return;let i=t,o=e;o===null&&(o=this.options.columns[0].field),i===null&&(i=this.originalData[this.originalData.length-1][o]),this.log(`remove row ${o}:${i}`);for(let n=0;n{this.hasDataError||(this.options.server||e?this.renderBody():this.paginate(),typeof t=="function"&&t())}).then(()=>this)}loadData(){let t=()=>!this.data.length&&this.classList.add("dg-empty"),e=this.tbody;return(this.meta||this.originalData||this.isInit)&&(!this.options.server||this.options.server&&!this.fireEvents)?(this.log("skip loadData"),t(),new Promise(i=>{i()})):(this.log("loadData"),this.loading=!0,this.classList.add("dg-loading"),this.classList.remove("dg-empty","dg-network-error"),this.fetchData().then(i=>{if(Array.isArray(i))this.data=i;else{if(!i[this.options.serverParams.dataKey]){console.error("Invalid response, it should contain a data key with an array or be a plain array",i),this.options.url=null;return}this.options=Object.assign(this.options,i[this.options.serverParams.optionsKey]??{}),this.meta=i[this.options.serverParams.metaKey]??{},this.data=i[this.options.serverParams.dataKey]}this.originalData=this.data.slice(),this.fixPage(),this.options.columns.length===0&&this.originalData.length?this.options.columns=this.convertColumns(Object.keys(this.originalData[0])):this.options.columns=this.convertColumns(this.options.columns)}).catch(i=>{this.log(i),e.setAttribute("data-empty",this.options.errorMessage||i.message?.replace(/^\s+|\r\n|\n|\r$/g,"")||C.networkError),this.classList.add("dg-empty","dg-network-error"),y(this,"loadDataFailed",i)}).finally(()=>{t(),this.#t(e),this.classList.remove("dg-loading"),c(this.table,"aria-rowcount",this.data.length),this.loading=!1}))}getFirst(){this.loading||(this.page=1)}getLast(){this.loading||(this.page=this.pages)}getPrev(){this.loading||(this.page=this.page-1)}getNext(){this.loading||(this.page=this.page+1)}gotoPage(t){if(t.type==="keypress"){let e=t.keyCode||t.key;if(e===13||e==="Enter")t.preventDefault();else return}this.page=Number.parseInt(this.inputPage.value)}getSort(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t?t.getAttribute("field"):this.options.defaultSort}getSortDir(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t&&t.getAttribute("aria-sort")||""}getFilters(){let t=[],e=g(this,this._filterSelector);for(let i of e)t[i.dataset.name]=i.value;return t}clearFilters(){let t=g(this,this._filterSelector);for(let e of t)e.value="";this.filterData()}filterData(){if(this.log("filter data"),this.page=1,this.options.server)this.reload();else{this.data=this.originalData?.slice()??[];let t=g(this,this._filterSelector);for(let i of t){let o=i.value;if(o){let n=i.dataset.name;this.data=this.data.filter(s=>`${s[n]}`.toLowerCase().indexOf(o.toLowerCase())!==-1)}}this.pageChanged();let e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");this.options.sort&&e?this.sortData():this.renderBody()}}sortData(t=null){this.log("sort data");let e=t;if(e&&this.getColProp(e.getAttribute("field"),"noSort")){this.log("sorting prevented because column is not sortable");return}if(this.plugins.ColumnResizer?.isResizing){this.log("sorting prevented because resizing");return}if(this.loading){this.log("sorting prevented because loading");return}if(e!==null){let i=n=>["dg-selectable","dg-actions","dg-responsive-toggle"].includes(n),o=g(this,"thead tr:first-child th");for(let n of o)[...n.classList].some(i)||!n.hasAttribute("aria-sort")||n!==e&&n.setAttribute("aria-sort","none");!e.hasAttribute("aria-sort")||e.getAttribute("aria-sort")==="none"?e.setAttribute("aria-sort","ascending"):e.getAttribute("aria-sort")==="ascending"?e.setAttribute("aria-sort","descending"):e.getAttribute("aria-sort")==="descending"&&e.setAttribute("aria-sort","none")}else e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");if(this.options.server)this.loadData().finally(()=>{this.renderBody()});else{let i=e?e.getAttribute("aria-sort"):"none";if(i==="none"){let o=[];this.originalData?.some(n=>(this.data.some(s=>JSON.stringify(n)===JSON.stringify(s)?(o.push(s),!0):!1),o.length===this.data.length)),this.data=o}else{let o=e.getAttribute("field");this.data.sort((n,s)=>{if(!isNaN(n[o])&&!isNaN(s[o]))return i==="ascending"?n[o]-s[o]:s[o]-n[o];let l=i==="ascending"?n[o].toUpperCase():s[o].toUpperCase(),a=i==="ascending"?s[o].toUpperCase():n[o].toUpperCase();switch(!0){case l>a:return 1;case lthis._sort(t,"ascending");sortDesc=t=>this._sort(t,"descending");sortNone=t=>this._sort(t,"none");fetchData(){if(!this.options.url)return new Promise((o,n)=>n("No url set"));let t=window.location.href;t.split("/").pop().includes(".")||(t+=t.endsWith("/")?"":"/");let e=new URL(this.options.url,t),i={r:Date.now()};return this.options.server&&(i[this.options.serverParams.start]=this.page-1,i[this.options.serverParams.length]=this.options.perPage,this.options.filter&&(i[this.options.serverParams.search]=this.getFilters()),i[this.options.serverParams.sort]=this.getSort()||"",i[this.options.serverParams.sortDir]=this.getSortDir(),this.meta?.[this.options.serverParams.paramsKey]&&(i=Object.assign(i,this.meta[this.options.serverParams.paramsKey]))),Q(e,i),fetch(e).then(o=>{let n=new Error(o.statusText||C.networkError);if(!o.ok)throw n.response=o,n;return o.clone().json().catch(s=>{let l=s;throw this.options.debug||(l=n),l.response=o,l})})}renderTable(){this.log("render table"),this.options.menu&&this.plugins.ContextMenu&&this.plugins.ContextMenu.createMenu();let t;this.renderHeader(),this.options.defaultSort&&(t=this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`)),t?this.sortData(t):this.renderBody(),this.renderFooter()}renderHeader(){this.log("render header");let t=this.thead;this.createColumnHeaders(t),this.createColumnFilters(t),this.options.resizable&&this.plugins.ColumnResizer&&this.plugins.ColumnResizer.renderResizer(C.resizeColumn),y(this,"headerRendered")}renderFooter(){this.log("render footer");let t=this.tfoot;if(!t)return;let e=t.querySelector("td");t.removeAttribute("hidden"),c(e,"colspan",this.columnsLength(!0)),t.style.display=""}createColumnHeaders(t){let e=this.clientWidth,i=Math.round(e/this.columnsLength(!0)*2),o=0,n;n=x("tr"),this.headerRow=n,n.setAttribute("role","row"),n.setAttribute("aria-rowindex","1"),n.setAttribute("class","dg-head-columns");let s=t?.querySelector("tr.dg-head-columns th");this.log("createColumnHeaders - sampleTh",s),s||(s=x("th"),t?.querySelector("tr").appendChild(s)),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createHeaderCol(n),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createHeaderCol(n),o=0;let l=0;this.log("createColumnHeaders - columns",this.options.columns);for(let d of this.options.columns){if(d.attr)continue;let u=o+this.startColIndex(),h=x("th");h.setAttribute("scope","col"),h.setAttribute("role","columnheader button"),h.setAttribute("aria-colindex",`${u}`),h.setAttribute("id",q("dg-col-")),this.options.sort&&h.setAttribute("aria-sort","none"),h.setAttribute("field",d.field),this.plugins.ResponsiveGrid&&this.options.responsive&&c(h,"data-responsive",d.responsive||"");let p=_(d.title,s,!0)+20;h.dataset.minWidth=`${p}`,wt(h,d),h.tabIndex=0,h.textContent=d.title;let f=0;if(this.options.autosize&&this.plugins.AutosizeColumn){let b=Math.min(e-l,i);f=this.plugins.AutosizeColumn.computeSize(h,d,Number.parseInt(h.dataset.minWidth),b)}else f=Math.max(Number.parseInt(h.dataset.minWidth),Number.parseInt(h.getAttribute("width")));c(h,"width",f),d.hidden?h.setAttribute("hidden",""):l+=f,this.options.reorder&&this.plugins.DraggableHeaders&&this.plugins.DraggableHeaders.makeHeaderDraggable(h),n.appendChild(h),o++}if(le){this.log(`adjust width to fix size, ${t.offsetWidth} > ${e}`);let d=this.offsetWidth-this.clientWidth,u=t.offsetWidth-e-d;this.options.responsive&&this.plugins.ResponsiveGrid&&(u+=d);let h=g(n,"th[width]");for(let p of h){if(T(p,"dg-not-resizable")||u<=0)continue;let f=Number.parseInt(p.getAttribute("width")),b=p.dataset.minWidth?Number.parseInt(p.dataset.minWidth):0;if(f>b){let S=f-u;Sthis.sortData(d));this.table&&c(this.table,"aria-colcount",this.columnsLength(!0))}createColumnFilters(t){let e=0,i;i=x("tr"),this.filterRow=i,i.setAttribute("role","row"),i.setAttribute("aria-rowindex","2"),i.setAttribute("class","dg-head-filters"),this.options.filter||i.setAttribute("hidden",""),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createFilterCol(i),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createFilterCol(i),this.log("createColumnFilters - columns",this.options.columns);for(let n of this.options.columns){if(n.attr)continue;let s=e+this.startColIndex(),l=t?.querySelector(`tr.dg-head-columns th[aria-colindex="${s}"]`);if(!l){console.warn("Related th not found",s);continue}let a=x("th");a.setAttribute("aria-colindex",`${s}`);let d=this.createFilterElement(n,l);this.options.filter?d.tabIndex=0:a.tabIndex=0,n.hidden&&a.setAttribute("hidden",""),a.appendChild(d),i.appendChild(a),e++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionFilter(i),t?.replaceChild(i,t.querySelector("tr.dg-head-filters")),(typeof this.options.filterKeypressDelay!="number"||this.options.filterOnEnter)&&(this.options.filterKeypressDelay=0);let o=g(i,this._filterSelector);for(let n of o){let s=/select/i.test(n.tagName)?"change":"keyup",l=G(a=>{let d=a.keyCode||a.key,u=!this.options.filterOnEnter&&!this._excludedKeys.some(h=>h===d);(d===13||d==="Enter"||u||a.type==="change")&&this.filterData.call(this)},this.options.filterKeypressDelay);n.addEventListener(s,l)}}createFilterElement(t,e){let i=t.filterType==="select",o=i?x("select"):x("input");if(i){if(!Array.isArray(t.filterList)){let n=[...new Set((this.data??[]).map(s=>s[t.field]))].filter(s=>s).sort();t.filterList=[t.firstFilterOption||this.defaultColumn.firstFilterOption].concat(n.map(s=>({value:s,text:s})))}for(let n of t.filterList){let s=x("option");s.value=n.value,s.text=n.text,o instanceof HTMLSelectElement&&o.add(s)}}else o.type="text",o.inputMode="search",o.autocomplete="off",o.spellcheck=!1;return o.dataset.name=t.field,o.id=q("dg-filter-"),o.setAttribute("aria-labelledby",e.getAttribute("id")),o}renderBody(){this.log("render body");let t,e,i,o=x("tbody");this.data.forEach((s,l)=>{t=x("tr"),c(t,"role","row"),c(t,"hidden",""),c(t,"aria-rowindex",l+1),t.tabIndex=0,this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createDataCol(t),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createDataCol(t),this.options.expand&&(t.classList.add("dg-expandable"),A(t,"click",a=>{a.target.matches(this._excludedRowElementSelector)||(this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.blockObserver(),yt(a.currentTarget,"dg-expanded"),this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.unblockObserver())})),i=0;for(let a of this.options.columns){if(a||console.error("Empty column found!",this.options.columns),a.attr){s[a.field]&&(a.attr==="class"?E(t,s[a.field]):t.setAttribute(a.attr,s[a.field]));return}if(e=x("td"),e.setAttribute("role","gridcell"),e.setAttribute("aria-colindex",`${i}${this.startColIndex()}`),wt(e,a),e.setAttribute("data-name",a.title),e.tabIndex=-1,a.editable&&this.plugins.EditableColumn)E(e,"dg-editable-col"),this.plugins.EditableColumn.makeEditableInput(e,a,s,l);else{let d=s[a.field]??"",u;switch(a.transform){case"uppercase":u=d.toUpperCase();break;case"lowercase":u=d.toLowerCase();break;default:u=d;break}if(a.format){if(a.defaultFormatValue!==void 0&&(u===""||u===null)&&(u=`${a.defaultFormatValue}`),typeof a.format=="string"&&u)e.innerHTML=M(a.format,Object.assign({_v:d,_tv:u},s));else if(a.format instanceof Function){let h=a.format.call(this,{column:a,rowData:s,cellData:u,td:e,tr:t});e.innerHTML=h||u||d}}else e.textContent=u}t.appendChild(e),i++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionRow(t,s),o.appendChild(t),y(this,"rowRendered",{rowData:s,tr:t})}),o.setAttribute("role","rowgroup");let n=this.tbody;n&&o.setAttribute("data-empty",n.getAttribute("data-empty")),this.table?.replaceChild(o,n),this.plugins.FixedHeight&&this.plugins.FixedHeight.createFakeRow(),this.paginate(),this.plugins.SelectableRows&&this.plugins.SelectableRows.shouldSelectAll(o),this.classList.toggle("dg-empty",!this.data.length),y(this,"bodyRendered")}paginate(){this.log("paginate");let t=this.totalRecords(),e=this.page||1,i=this.tbody,o=this.tfoot;if(!i||!o)return;let n=g(i,"tr");this.pages=this.totalPages();let s,l=e*this.options.perPage,a=l-this.options.perPage+1;l>t&&(l=t),t||(a=0);for(let d of n){if(this.options.server){k(d,"hidden");continue}s=Number(D(d,"aria-rowindex")),s>l||s=this.pages,this.btnLast.disabled=this.page>=this.pages),o.querySelector(".dg-low").textContent=a.toString(),o.querySelector(".dg-high").textContent=l.toString(),o.querySelector(".dg-total").textContent=`${this.totalRecords()}`,o.toggleAttribute("hidden",this.options.autohidePager&&this.options.perPage>this.totalRecords())}totalPages(){return Math.ceil(this.totalRecords()/this.options.perPage)}totalRecords(){return this.options.server?this.meta?.[this.options.serverParams.metaFilteredKey]||0:this.data.length}},j=it;var st=class{constructor(t){this.grid=t}connected(){}disconnected(){}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}},m=st;var ot=class extends m{constructor(t){super(t),this.isResizing=!1}renderResizer(t){let e=this.grid,i=e.table,o=g(e,"thead tr.dg-head-columns th");for(let n of o){if(T(n,"dg-not-resizable"))continue;let s=document.createElement("div");E(s,"dg-resizer"),s.ariaLabel=t,n.appendChild(s);let l=0,a=0,d=0,u=0,h=f=>{if(f.clientX>u)return;let b=a+(f.clientX-l);n.dataset.minWidth&&b>Number.parseInt(n.dataset.minWidth)&&c(n,"width",b)},p=()=>{e.log("resized column"),setTimeout(()=>{this.isResizing=!1},0),W(s,"dg-resizer-active"),e.options.reorder&&(n.draggable=!0),n.style.overflow="hidden",O(document,"mousemove",h),O(document,"mouseup",p),y(e,"columnResized",{col:D(n,"field"),width:D(n,"width")})};A(s,"click",f=>{f.stopPropagation()}),A(s,"mousedown",f=>{f.stopPropagation(),this.isResizing=!0;let b=f.target,P=g(e,"dg-head-columns th").filter(v=>!v.hasAttribute("hidden")),w=P.findIndex(v=>v===b.parentNode);e.log("resize column"),E(s,"dg-resizer-active"),k(n,"draggable"),n.style.overflow="visible",s.style.height=`${i.offsetHeight-1}px`,l=f.clientX,a=n.offsetWidth,d=(P.length-w)*30,u=tt(b).left+e.offsetWidth-d,c(n,"width",a);for(let v=0;vw&&k(o[v],"width");A(document,"mousemove",h),A(document,"mouseup",p)})}}},Pt=ot;function K(r,t,e="nodeName"){let i=r;for(;i[e]!==t;)i=i.parentElement;return i}var nt=class extends m{connected(){this.menu=this.grid.querySelector(".dg-menu")}disconnected(){this.grid.headerRow&&O(this.grid.headerRow,"contextmenu",this)}attachContextMenu(){let t=this.grid;A(t.headerRow,"contextmenu",this)}onchange(t){let e=this.grid,i=t.target,o=i.dataset.name;if(i.checked)e.showColumn(o);else{if(e.visibleColumns().length<=1){i.checked=!0;return}e.hideColumn(o)}e.fixPage()}oncontextmenu(t){t.preventDefault();let e=this.grid,i=K(t.target,"THEAD"),o=this.menu,n=i.getBoundingClientRect(),s=t.clientX-n.left,l=t.clientY-n.top;o.style.top=`${l}px`,o.style.left=`${s}px`,k(o,"hidden"),s+150>n.width&&(s-=o.offsetWidth,o.style.left=`${s}px`);let a=d=>{o.contains(d.target)||(c(o,"hidden",""),O(document,"click",a))};A(document,"click",a)}createMenu(){let t=this.grid,e=this.menu;for(;e.lastChild;)e.removeChild(e.lastChild);e.addEventListener("change",this);for(let i of t.options.columns){if(i.attr)continue;let o=document.createElement("li"),n=document.createElement("label"),s=document.createElement("input");c(s,"type","checkbox"),c(s,"data-name",i.field),i.hidden||(s.checked=!0);let l=document.createTextNode(i.title);n.appendChild(s),n.appendChild(l),o.appendChild(n),e.appendChild(o)}}},At=nt;var rt=class extends m{makeHeaderDraggable(t){let e=this.grid;t.draggable=!0,A(t,"dragstart",i=>{if(e.plugins.ColumnResizer?.isResizing&&i.preventDefault){i.preventDefault();return}e.log("reorder col"),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",i.target.getAttribute("aria-colindex"))}),A(t,"dragover",i=>(i.preventDefault&&i.preventDefault(),i.dataTransfer.dropEffect="move",!1)),A(t,"drop",i=>{i.stopPropagation&&i.stopPropagation();let o=i.target,n=K(o,"TH"),s=Number.parseInt(i.dataTransfer.getData("text/plain")),l=Number.parseInt(n.getAttribute("aria-colindex"));if(s===l){e.log("reordered col stayed the same");return}e.log(`reordered col from ${s} to ${l}`);let a=e.startColIndex(),d=e.options.columns[s-a];e.options.columns[s-a]=e.options.columns[l-a],e.options.columns[l-a]=d;let u=(h,p)=>{let f=p.parentNode.getAttribute("aria-rowindex"),b=e.querySelector(`${h} tr[aria-rowindex="${f}"] [aria-colindex="${l}"]`);c(p,"aria-colindex",l),c(b,"aria-colindex",s);let S=document.createElement("th");p.parentNode.insertBefore(S,p),b.parentNode.replaceChild(p,b),S.parentNode.replaceChild(b,S)};for(let h of g(e,`thead th[aria-colindex="${s}"]`))u("thead",h);for(let h of g(e,`tbody td[aria-colindex="${s}"]`))u("tbody",h);return e.options.columns=g(e,"thead tr.dg-head-columns th[field]").map(h=>e.options.columns.find(p=>p.field===D(h,"field"))),y(e,"columnReordered",{col:d.field,from:s,to:l}),!1})}},St=rt;var at=class extends m{constructor(t){super(t),this.touch=null}connected(){let t=this.grid;t.addEventListener("touchstart",this,{passive:!0}),t.addEventListener("touchmove",this,{passive:!0})}disconnected(){let t=this.grid;t.removeEventListener("touchstart",this),t.removeEventListener("touchmove",this)}ontouchstart(t){this.touch=t.touches[0]}ontouchmove(t){if(!this.touch)return;let e=this.grid,i=this.touch.clientX-t.touches[0].clientX,o=this.touch.clientY-t.touches[0].clientY;Math.abs(i)>Math.abs(o)&&(i>0?e.getNext():e.getPrev()),this.touch=null}},Lt=at;var H="dg-selectable",lt="dg-select-all",kt="form-check-input",dt=class extends m{#t=`tbody tr${this.visibleOnly?":not([hidden])":""} .${H} input[type=checkbox]`;#e=`tbody .${H} input`;disconnected(){this.selectAll&&this.selectAll.removeEventListener("change",this)}get isSingleSelect(){return this.grid.options.singleSelect}get visibleOnly(){return this.grid.options.selectVisibleOnly}getSelection(...t){let e=this.grid,i=[],o=g(e,`${this.#e}:checked`);for(let n of o){let s=Number.parseInt(n.dataset.id),l=e.data[s-1];if(!l){console.warn(`Item ${s} not found`);continue}t.length===0?i.push(l):t.length===1?i.push(l[t[0]]):i.push(Object.fromEntries(t.map(a=>[a,l[a]])))}return this.isSingleSelect?i[0]??{}:i}clearCheckboxes(t){if(!this.grid.options.selectVisibleOnly)return;let i=g(t,`tr[hidden] .${H} input`);for(let o of i)o.checked=!1,this.isSingleSelect&&(o.dataset.toggled="false");this.selectAll.checked=!1}colIndex(){return this.grid.startColIndex()-2}createHeaderCol(t){let e=document.createElement("th");c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0,this.selectAll=document.createElement("input"),this.selectAll.type="checkbox",this.selectAll.classList.add(lt),this.selectAll.classList.add(kt),this.selectAll.addEventListener("change",this);let i=document.createElement("label");i.hidden=this.isSingleSelect,i.appendChild(this.selectAll),e.appendChild(i),e.setAttribute("width","40"),t.appendChild(e)}createFilterCol(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H),e.tabIndex=0,t.appendChild(e)}shouldSelectAll(t){this.selectAll&&(t.addEventListener("change",this),t.dispatchEvent(new Event("change")))}createDataCol(t){let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H);let i=document.createElement("input");i.dataset.id=t.getAttribute("aria-rowindex"),i.type=this.isSingleSelect?"radio":"checkbox",i.classList.add(kt),this.isSingleSelect&&(i.name="dg-row-select",i.dataset.toggled="false");let o=document.createElement("label");o.classList.add("dg-clickable-cell"),o.appendChild(i),e.appendChild(o),o.addEventListener("click",this),t.appendChild(e)}onclick(t){if(!this.isSingleSelect)return t.stopPropagation();let e=t.target,i=e.dataset.toggled!=="true";i&&Y(`${this.#t.replace("checkbox","radio")}`,this.grid)?.forEach(o=>{o.name===e.name&&o!==e&&(o.checked=o.dataset.toggled=!1)}),e.checked=e.dataset.toggled=i,!i&&this.onchange(t)}onchange(t){let e=t.target,i=this.grid;if(T(t.target,lt))g(i,this.#e).forEach(o=>{(!this.visibleOnly||o.offsetWidth)&&(o.checked=this.selectAll.checked)});else if(e.matches(this.#t)){if(!e.closest(`.${H}`))return;let o=g(i,this.#t);this.selectAll.checked=o.every(n=>n.checked)}e.matches(`.${lt},${this.#e}`)&&y(e,"rowsSelected",{selection:i.getSelection()},!0)}},Et=dt;var ct=class extends m{constructor(t){super(t),this.hasFixedHeight=!1,t.style.height&&(t.style.overflowY="auto",this.hasFixedHeight=!0)}createFakeRow(){let e=this.grid.querySelector("tbody"),i=document.createElement("tr");c(i,"role","row"),c(i,"hidden",""),i.classList.add("dg-fake-row"),i.tabIndex=0,e?.appendChild(i)}get fakeRow(){return this.grid.querySelector(".dg-fake-row")}updateFakeRow(){let t=this.grid,e=this.fakeRow;if(!e||t.options.perPage>t.totalRecords()||t.page!==t.totalPages()||!t.options.autoheight)return;let i=t.options.perPage*t.rowHeight,o=t.querySelectorAll("tbody tr:not([hidden])").length,n=o>1?i-o*t.rowHeight:i;n>0?(c(e,"height",n),e.removeAttribute("hidden")):e.removeAttribute("height")}},Dt=ct;var ht=class extends m{computeSize(t,e,i,o){let n=this.grid;if(U(t,"width"))return D(t,"width");if(!n.data.length)return;let s=n.data[0],l=n.data[n.data.length-1],a=s[e.field]?s[e.field].toString():"",d=l[e.field]?l[e.field].toString():"";d.length>a.length&&(a=d);let u=0;return a.length<=6?u=i:a.length>50?u=o:u=_(`${a}0000`,t),u>o&&(u=o),u{let i=Number.parseInt(t.dataset.responsive)||1;return(Number.parseInt(e.dataset.responsive)||1)-i})}var Wt=G(r=>{for(let t of r){let e=t.target,i=e.table;if(e.plugins.ResponsiveGrid.observerBlocked)return;let o=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize,n=Number.parseInt(o.inlineSize),s=i.offsetWidth,l=g(e.headerRow,"th").reduce((P,w)=>P+w.offsetWidth,0),a=(l||s)-n-1,d=50,u=e.plugins.ResponsiveGrid.prevAction,h=Ft(g(e.headerRow,"th[field]").reverse().filter(P=>P.dataset.responsive!=="0")),p=!1;if(e.log(`table is ${s}/${l} and available size is ${n}. Diff: ${a}`),a>0){if(u==="show")return;e.plugins.ResponsiveGrid.prevAction="hide";let P=a,w=h.filter(v=>!v.hasAttribute("hidden")&&v.hasAttribute("data-responsive"));if(w.length===0&&(w=h.filter(v=>!v.hasAttribute("hidden")),w.length===1))return;for(let v of w){if(P<0)continue;let $=v.offsetWidth,R=v.getAttribute("field");R&&(v.dataset.baseWidth=`${v.offsetWidth}`,e.hideColumn(R,!1),e.setColProp(R,"responsiveHidden",!0),p=!0,P-=$,P=Math.round(P))}}else{if(u==="hide")return;e.plugins.ResponsiveGrid.prevAction="show";let P=h.filter($=>!$.hasAttribute("hidden")).reduce(($,R)=>{let z=R.dataset.minWidth?Number.parseInt(R.dataset.minWidth):R.offsetWidth;return $+z},0)+d,w=n-P,v=h.slice().reverse().filter($=>$.hasAttribute("hidden"));for(let $ of v){if(ww){w=-1;continue}let z=$.getAttribute("field");z&&(e.showColumn(z,!1),e.setColProp(z,"responsiveHidden",!1),p=!0,w-=R,w=Math.round(w))}}let f=N(e.table,"tfoot"),b=g(e.table,".dg-footer > div").reduce((P,w)=>P+w.offsetWidth,0),S=f.offsetWidth-b;b>n?E(f,"dg-footer-compact"):S>250&&W(f,"dg-footer-compact"),p&&e.renderTable(),setTimeout(()=>{e.plugins.ResponsiveGrid.prevAction=null},1e3),e.table.style.visibility="visible"}},100),Rt=new ResizeObserver(Wt),gt=class extends m{constructor(t){super(t),this.observerBlocked=!1,this.prevAction=null}connected(){this.grid.options.responsive&&this.observe()}disconnected(){this.unobserve()}observe(){this.grid.options.responsive&&(Rt.observe(this.grid),this.grid.style.display="block",this.grid.style.overflowX="hidden")}unobserve(){Rt.unobserve(this.grid),this.grid.style.display="unset",this.grid.style.overflowX="unset"}blockObserver(){this.observerBlocked=!0,ut&&clearTimeout(ut)}unblockObserver(){ut=setTimeout(()=>{this.observerBlocked=!1},200)}hasHiddenColumns(){let t=!1;for(let e of this.grid.options.columns)e.responsiveHidden&&(t=!0);return t}colIndex(){return this.grid.startColIndex()-1}createHeaderCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),c(e,"width","40"),e.classList.add(`${L}-toggle`,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0}createFilterCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.tabIndex=0}createDataCol(t){if(!this.grid.options.responsiveToggle)return;let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.innerHTML=`
+`}get labels(){return C}static getLabels(){return C}static setLabels(t){C=Object.assign(C,t)}get noData(){return this.options.noData||this.labels.noData}#t(t){!this.hasDataError&&t.getAttribute("data-empty")!==this.noData&&t.setAttribute("data-empty",this.noData)}get defaultColumn(){return{field:"",title:"",width:0,class:"",attr:"",hidden:!1,editable:!1,noSort:!1,responsive:1,responsiveHidden:!1,format:"",transform:"",filterType:"text",firstFilterOption:{value:"",text:""}}}get defaultOptions(){return{id:null,url:"",perPage:10,debug:!1,filter:!1,menu:!1,sort:!1,server:!1,serverParams:{start:"start",length:"length",search:"search",sort:"sort",sortDir:"sortDir",dataKey:"data",metaKey:"meta",metaTotalKey:"total",metaFilteredKey:"filtered",optionsKey:"options",paramsKey:"params"},defaultSort:"",reorder:!1,dir:"ltr",perPageValues:[10,25,50,100,250],hidePerPage:!1,columns:[],actions:[],collapseActions:!1,selectable:!1,selectVisibleOnly:!0,singleSelect:!1,defaultPage:1,resizable:!1,autosize:!0,expand:!1,autoheight:!0,autohidePager:!1,responsive:!1,responsiveToggle:!0,filterOnEnter:!0,filterKeypressDelay:500,spinnerClass:"",saveState:!1,errorMessage:"",noData:""}}get isInit(){return this.classList.contains("dg-initialized")}get hasDataError(){return this.classList.contains("dg-network-error")}static registerPlugins(t){B=t}static unregisterPlugins(t=null){t===null?B={}:delete B[t]}static registeredPlugins(){return B}convertColumns(t){let e=[];if(typeof t=="object"&&!Array.isArray(t))for(let i of Object.keys(t)){let o=Object.assign({},this.defaultColumn);o.title=t[i],o.field=i,e.push(o)}else for(let i of t){let o=Object.assign({},this.defaultColumn);typeof i=="string"?(o.title=i,o.field=i):typeof i=="object"?(o=Object.assign(o,i),o.field||console.error("Invalid column definition",i),o.title||(o.title=o.field)):console.error("Column definition must be a string or an object"),e.push(o)}return e}static get observedAttributes(){return["page","data-filter","data-sort","data-debug","data-reorder","data-menu","data-selectable","data-single-select","data-url","data-per-page","data-responsive"]}get transformAttributes(){return{columns:t=>this.convertColumns(X(t)),actions:t=>X(t),defaultPage:t=>Number.parseInt(t),perPage:t=>Number.parseInt(t)}}get thead(){return I("thead",this)}get tbody(){return I("tbody",this)}get tfoot(){return I("tfoot",this)}get page(){return Number.parseInt(this.getAttribute("page"))}set page(t){c(this,"page",this.constrainPageValue(t))}urlChanged(t=!1){return t&&!this.isInit?this:(this.reconfig(),this.loadData().then(()=>this.configureUi()))}reconfig(){let t=this.options.columns;return this.options.columns=[],this.configureUi(),this.options.columns=t,this}constrainPageValue(t){let e=t;return this.pages1&&this.page*this.options.perPage>this.totalRecords();)t--;t!==this.page?this.page=t:this.reload(()=>{(!this.plugins.FixedHeight||!this.plugins.FixedHeight.hasFixedHeight)&&this.selectPerPage.scrollIntoView()})}dirChanged(){c(this,"dir",this.options.dir)}defaultSortChanged(){this.sortChanged()}perPageValuesChanged(){if(this.selectPerPage){for(;this.selectPerPage.lastChild;)this.selectPerPage.removeChild(this.selectPerPage.lastChild);for(let t of this.options.perPageValues)Z(this.selectPerPage,t,t,t===this.options.perPage)}}async _connected(){this.table=this.querySelector("table"),this.btnFirst=this.querySelector(".dg-btn-first"),this.btnPrev=this.querySelector(".dg-btn-prev"),this.btnNext=this.querySelector(".dg-btn-next"),this.btnLast=this.querySelector(".dg-btn-last"),this.selectPerPage=this.querySelector(".dg-select-per-page"),this.inputPage=this.querySelector(".dg-input-page"),this.getFirst=this.getFirst.bind(this),this.getPrev=this.getPrev.bind(this),this.getNext=this.getNext.bind(this),this.getLast=this.getLast.bind(this),this.changePerPage=this.changePerPage.bind(this),this.gotoPage=this.gotoPage.bind(this),this.btnFirst.addEventListener("click",this.getFirst),this.btnPrev.addEventListener("click",this.getPrev),this.btnNext.addEventListener("click",this.getNext),this.btnLast.addEventListener("click",this.getLast),this.selectPerPage.addEventListener("change",this.changePerPage),this.selectPerPage.toggleAttribute("hidden",this.options.hidePerPage),this.inputPage.addEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))await t.connected();this.dirChanged(),this.perPageValuesChanged(),await this.init()}_disconnected(){this.btnFirst?.removeEventListener("click",this.getFirst),this.btnPrev?.removeEventListener("click",this.getPrev),this.btnNext?.removeEventListener("click",this.getNext),this.btnLast?.removeEventListener("click",this.getLast),this.selectPerPage?.removeEventListener("change",this.changePerPage),this.inputPage?.removeEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))t.disconnected()}init(){return this.loadData().finally(()=>{this.configureUi(),this.sortChanged(),this.classList.add("dg-initialized"),this.filterChanged(),this.reorderChanged(),this.dirChanged(),this.perPageValuesChanged(),this.pageChanged(),this.fireEvents=!0,this.log("initialized")})}getCol(t){let e=null;for(let i of this.options.columns)i.field===t&&(e=i);return e}getColProp(t,e){let i=this.getCol(t);return i?i[e]:null}setColProp(t,e,i){let o=this.getCol(t);o&&(o[e]=i)}visibleColumns(){return this.options.columns.filter(t=>!t.hidden)}hiddenColumns(){return this.options.columns.filter(t=>t.hidden===!0)}showColumn(t,e=!0){this.setColProp(t,"hidden",!1),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"visible"})}hideColumn(t,e=!0){this.setColProp(t,"hidden",!0),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"hidden"})}startColIndex(){let t=1;return this.options.selectable&&this.plugins.SelectableRows&&t++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&t++,t}isSticky(){return this.hasAttribute("sticky")}columnsLength(t=!1){let e=0;for(let i of this.options.columns)t&&i.hidden||i.attr||e++;return this.options.selectable&&this.plugins.SelectableRows&&e++,this.options.actions.length&&this.plugins.RowActions&&e++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&e++,e}configureUi(){if(!this.table)return this;if(this.table.style.visibility="hidden",this.renderTable(),this.options.responsive&&this.plugins.ResponsiveGrid||(this.table.style.visibility="visible"),!this.rowHeight){let t=N(this,"tbody tr")||N(this,"table tr");t&&(this.rowHeight=t.offsetHeight)}return this.#t(this.tbody),this.fixPage()}filterChanged(){let t=this.querySelector("thead tr.dg-head-filters");this.options.filter?k(t,"hidden"):(this.clearFilters(),c(t,"hidden",""))}reorderChanged(){let t=g(this,"thead tr.dg-head-columns th");for(let e of t)e.classList.contains("dg-selectable")||e.classList.contains("dg-actions")||(this.options.reorder&&this.plugins.DraggableHeaders?e.draggable=!0:e.removeAttribute("draggable"))}sortChanged(){this.log("toggle sort");let t=g(this,"thead tr.dg-head-columns th");for(let e of t){let i=e.getAttribute("field");if(e.classList.contains("dg-not-sortable")||!this.fireEvents&&i===this.options.defaultSort)return;this.options.sort&&!this.getColProp(i,"noSort")?c(e,"aria-sort","none"):k(e,"aria-sort")}}selectableChanged(){this.renderTable()}addRow(t){Array.isArray(this.originalData)&&(this.log("add row"),this.originalData.push(t),this.data=this.originalData.slice(),this.sortData())}removeRow(t=null,e=null){if(!Array.isArray(this.originalData))return;let i=t,o=e;o===null&&(o=this.options.columns[0].field),i===null&&(i=this.originalData[this.originalData.length-1][o]),this.log(`remove row ${o}:${i}`);for(let n=0;n{this.hasDataError||(this.options.server||e?this.renderBody():this.paginate(),typeof t=="function"&&t())}).then(()=>this)}loadData(){let t=()=>!this.data.length&&this.classList.add("dg-empty"),e=this.tbody;return(this.meta||this.originalData||this.isInit)&&(!this.options.server||this.options.server&&!this.fireEvents)?(this.log("skip loadData"),t(),new Promise(i=>{i()})):(this.log("loadData"),this.loading=!0,this.classList.add("dg-loading"),this.classList.remove("dg-empty","dg-network-error"),this.fetchData().then(i=>{if(Array.isArray(i))this.data=i;else{if(!i[this.options.serverParams.dataKey]){console.error("Invalid response, it should contain a data key with an array or be a plain array",i),this.options.url=null;return}this.options=Object.assign(this.options,i[this.options.serverParams.optionsKey]??{}),this.meta=i[this.options.serverParams.metaKey]??{},this.data=i[this.options.serverParams.dataKey]}this.originalData=this.data.slice(),this.fixPage(),this.options.columns.length===0&&this.originalData.length?this.options.columns=this.convertColumns(Object.keys(this.originalData[0])):this.options.columns=this.convertColumns(this.options.columns)}).catch(i=>{this.log(i),e.setAttribute("data-empty",this.options.errorMessage||i.message?.replace(/^\s+|\r\n|\n|\r$/g,"")||C.networkError),this.classList.add("dg-empty","dg-network-error"),y(this,"loadDataFailed",i)}).finally(()=>{t(),this.#t(e),this.classList.remove("dg-loading"),c(this.table,"aria-rowcount",this.data.length),this.loading=!1}))}getFirst(){this.loading||(this.page=1)}getLast(){this.loading||(this.page=this.pages)}getPrev(){this.loading||(this.page=this.page-1)}getNext(){this.loading||(this.page=this.page+1)}gotoPage(t){if(t.type==="keypress"){let e=t.keyCode||t.key;if(e===13||e==="Enter")t.preventDefault();else return}this.page=Number.parseInt(this.inputPage.value)}getSort(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t?t.getAttribute("field"):this.options.defaultSort}getSortDir(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t&&t.getAttribute("aria-sort")||""}getFilters(){let t=[],e=g(this,this._filterSelector);for(let i of e)t[i.dataset.name]=i.value;return t}clearFilters(){let t=g(this,this._filterSelector);for(let e of t)e.value="";this.filterData()}filterData(){if(this.log("filter data"),this.page=1,this.options.server)this.reload();else{this.data=this.originalData?.slice()??[];let t=g(this,this._filterSelector);for(let i of t){let o=i.value;if(o){let n=i.dataset.name;this.data=this.data.filter(s=>`${s[n]}`.toLowerCase().indexOf(o.toLowerCase())!==-1)}}this.pageChanged();let e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");this.options.sort&&e?this.sortData():this.renderBody()}}sortData(t=null){this.log("sort data");let e=t;if(e&&this.getColProp(e.getAttribute("field"),"noSort")){this.log("sorting prevented because column is not sortable");return}if(this.plugins.ColumnResizer?.isResizing){this.log("sorting prevented because resizing");return}if(this.loading){this.log("sorting prevented because loading");return}if(e!==null){let i=n=>["dg-selectable","dg-actions","dg-responsive-toggle"].includes(n),o=g(this,"thead tr:first-child th");for(let n of o)[...n.classList].some(i)||!n.hasAttribute("aria-sort")||n!==e&&n.setAttribute("aria-sort","none");!e.hasAttribute("aria-sort")||e.getAttribute("aria-sort")==="none"?e.setAttribute("aria-sort","ascending"):e.getAttribute("aria-sort")==="ascending"?e.setAttribute("aria-sort","descending"):e.getAttribute("aria-sort")==="descending"&&e.setAttribute("aria-sort","none")}else e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");if(this.options.server)this.loadData().finally(()=>{this.renderBody()});else{let i=e?e.getAttribute("aria-sort"):"none";if(i==="none"){let o=[];this.originalData?.some(n=>(this.data.some(s=>JSON.stringify(n)===JSON.stringify(s)?(o.push(s),!0):!1),o.length===this.data.length)),this.data=o}else{let o=e.getAttribute("field");this.data.sort((n,s)=>{if(!isNaN(n[o])&&!isNaN(s[o]))return i==="ascending"?n[o]-s[o]:s[o]-n[o];let a=i==="ascending"?n[o].toUpperCase():s[o].toUpperCase(),l=i==="ascending"?s[o].toUpperCase():n[o].toUpperCase();switch(!0){case a>l:return 1;case athis._sort(t,"ascending");sortDesc=t=>this._sort(t,"descending");sortNone=t=>this._sort(t,"none");fetchData(){if(!this.options.url)return new Promise((o,n)=>n("No url set"));let t=window.location.href;t.split("/").pop().includes(".")||(t+=t.endsWith("/")?"":"/");let e=new URL(this.options.url,t),i={r:Date.now()};return this.options.server&&(i[this.options.serverParams.start]=this.page-1,i[this.options.serverParams.length]=this.options.perPage,this.options.filter&&(i[this.options.serverParams.search]=this.getFilters()),i[this.options.serverParams.sort]=this.getSort()||"",i[this.options.serverParams.sortDir]=this.getSortDir(),this.meta?.[this.options.serverParams.paramsKey]&&(i=Object.assign(i,this.meta[this.options.serverParams.paramsKey]))),Q(e,i),fetch(e).then(o=>{let n=new Error(o.statusText||C.networkError);if(!o.ok)throw n.response=o,n;return o.clone().json().catch(s=>{let a=s;throw this.options.debug||(a=n),a.response=o,a})})}renderTable(){this.log("render table"),this.options.menu&&this.plugins.ContextMenu&&this.plugins.ContextMenu.createMenu();let t;this.renderHeader(),this.options.defaultSort&&(t=this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`)),t?this.sortData(t):this.renderBody(),this.renderFooter()}renderHeader(){this.log("render header");let t=this.thead;this.createColumnHeaders(t),this.createColumnFilters(t),this.options.resizable&&this.plugins.ColumnResizer&&this.plugins.ColumnResizer.renderResizer(C.resizeColumn),y(this,"headerRendered")}renderFooter(){this.log("render footer");let t=this.tfoot;if(!t)return;let e=t.querySelector("td");t.removeAttribute("hidden"),c(e,"colspan",this.columnsLength(!0)),t.style.display=""}createColumnHeaders(t){let e=this.clientWidth,i=Math.round(e/this.columnsLength(!0)*2),o=0,n;n=x("tr"),this.headerRow=n,n.setAttribute("role","row"),n.setAttribute("aria-rowindex","1"),n.setAttribute("class","dg-head-columns");let s=t?.querySelector("tr.dg-head-columns th");this.log("createColumnHeaders - sampleTh",s),s||(s=x("th"),t?.querySelector("tr").appendChild(s)),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createHeaderCol(n),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createHeaderCol(n),o=0;let a=0;this.log("createColumnHeaders - columns",this.options.columns);for(let d of this.options.columns){if(d.attr)continue;let u=o+this.startColIndex(),h=x("th");h.setAttribute("scope","col"),h.setAttribute("role","columnheader button"),h.setAttribute("aria-colindex",`${u}`),h.setAttribute("id",q("dg-col-")),this.options.sort&&h.setAttribute("aria-sort","none"),h.setAttribute("field",d.field),this.plugins.ResponsiveGrid&&this.options.responsive&&c(h,"data-responsive",d.responsive||"");let p=_(d.title,s,!0)+20;h.dataset.minWidth=`${p}`,wt(h,d),h.tabIndex=0,h.textContent=d.title;let f=0;if(this.options.autosize&&this.plugins.AutosizeColumn){let b=Math.min(e-a,i);f=this.plugins.AutosizeColumn.computeSize(h,d,Number.parseInt(h.dataset.minWidth),b)}else f=Math.max(Number.parseInt(h.dataset.minWidth),Number.parseInt(h.getAttribute("width")));c(h,"width",f),d.hidden?h.setAttribute("hidden",""):a+=f,this.options.reorder&&this.plugins.DraggableHeaders&&this.plugins.DraggableHeaders.makeHeaderDraggable(h),n.appendChild(h),o++}if(ae){this.log(`adjust width to fix size, ${t.offsetWidth} > ${e}`);let d=this.offsetWidth-this.clientWidth,u=t.offsetWidth-e-d;this.options.responsive&&this.plugins.ResponsiveGrid&&(u+=d);let h=g(n,"th[width]");for(let p of h){if(T(p,"dg-not-resizable")||u<=0)continue;let f=Number.parseInt(p.getAttribute("width")),b=p.dataset.minWidth?Number.parseInt(p.dataset.minWidth):0;if(f>b){let S=f-u;Sthis.sortData(d));this.table&&c(this.table,"aria-colcount",this.columnsLength(!0))}createColumnFilters(t){let e=0,i;i=x("tr"),this.filterRow=i,i.setAttribute("role","row"),i.setAttribute("aria-rowindex","2"),i.setAttribute("class","dg-head-filters"),this.options.filter||i.setAttribute("hidden",""),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createFilterCol(i),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createFilterCol(i),this.log("createColumnFilters - columns",this.options.columns);for(let n of this.options.columns){if(n.attr)continue;let s=e+this.startColIndex(),a=t?.querySelector(`tr.dg-head-columns th[aria-colindex="${s}"]`);if(!a){console.warn("Related th not found",s);continue}let l=x("th");l.setAttribute("aria-colindex",`${s}`);let d=this.createFilterElement(n,a);this.options.filter?d.tabIndex=0:l.tabIndex=0,n.hidden&&l.setAttribute("hidden",""),l.appendChild(d),i.appendChild(l),e++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionFilter(i),t?.replaceChild(i,t.querySelector("tr.dg-head-filters")),(typeof this.options.filterKeypressDelay!="number"||this.options.filterOnEnter)&&(this.options.filterKeypressDelay=0);let o=g(i,this._filterSelector);for(let n of o){let s=/select/i.test(n.tagName)?"change":"keyup",a=G(l=>{let d=l.keyCode||l.key,u=!this.options.filterOnEnter&&!this._excludedKeys.some(h=>h===d);(d===13||d==="Enter"||u||l.type==="change")&&this.filterData.call(this)},this.options.filterKeypressDelay);n.addEventListener(s,a)}}createFilterElement(t,e){let i=t.filterType==="select",o=i?x("select"):x("input");if(i){if(!Array.isArray(t.filterList)){let n=[...new Set((this.data??[]).map(s=>s[t.field]))].filter(s=>s).sort();t.filterList=[t.firstFilterOption||this.defaultColumn.firstFilterOption].concat(n.map(s=>({value:s,text:s})))}for(let n of t.filterList){let s=x("option");s.value=n.value,s.text=n.text,o instanceof HTMLSelectElement&&o.add(s)}}else o.type="text",o.inputMode="search",o.autocomplete="off",o.spellcheck=!1;return o.dataset.name=t.field,o.id=q("dg-filter-"),o.setAttribute("aria-labelledby",e.getAttribute("id")),o}renderBody(){this.log("render body");let t,e,i,o=x("tbody");this.data.forEach((s,a)=>{t=x("tr"),c(t,"role","row"),c(t,"hidden",""),c(t,"aria-rowindex",a+1),t.tabIndex=0,this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createDataCol(t),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createDataCol(t),this.options.expand&&(t.classList.add("dg-expandable"),A(t,"click",l=>{l.target.matches(this._excludedRowElementSelector)||(this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.blockObserver(),yt(l.currentTarget,"dg-expanded"),this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.unblockObserver())})),i=0;for(let l of this.options.columns){if(l||console.error("Empty column found!",this.options.columns),l.attr){s[l.field]&&(l.attr==="class"?E(t,s[l.field]):t.setAttribute(l.attr,s[l.field]));return}if(e=x("td"),e.setAttribute("role","gridcell"),e.setAttribute("aria-colindex",`${i}${this.startColIndex()}`),wt(e,l),e.setAttribute("data-name",l.title),e.tabIndex=-1,l.editable&&this.plugins.EditableColumn)E(e,"dg-editable-col"),this.plugins.EditableColumn.makeEditableInput(e,l,s,a);else{let d=s[l.field]??"",u;switch(l.transform){case"uppercase":u=d.toUpperCase();break;case"lowercase":u=d.toLowerCase();break;default:u=d;break}if(l.format){if(l.defaultFormatValue!==void 0&&(u===""||u===null)&&(u=`${l.defaultFormatValue}`),typeof l.format=="string"&&u)e.innerHTML=M(l.format,Object.assign({_v:d,_tv:u},s));else if(l.format instanceof Function){let h=l.format.call(this,{column:l,rowData:s,cellData:u,td:e,tr:t});e.innerHTML=h||u||d}}else e.textContent=u}t.appendChild(e),i++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionRow(t,s),o.appendChild(t),y(this,"rowRendered",{rowData:s,tr:t})}),o.setAttribute("role","rowgroup");let n=this.tbody;n&&o.setAttribute("data-empty",n.getAttribute("data-empty")),this.table?.replaceChild(o,n),this.plugins.FixedHeight&&this.plugins.FixedHeight.createFakeRow(),this.paginate(),this.plugins.SelectableRows&&this.plugins.SelectableRows.shouldSelectAll(o),this.classList.toggle("dg-empty",!this.data.length),y(this,"bodyRendered")}paginate(){this.log("paginate");let t=this.totalRecords(),e=this.page||1,i=this.tbody,o=this.tfoot;if(!i||!o)return;let n=g(i,"tr");this.pages=this.totalPages();let s,a=e*this.options.perPage,l=a-this.options.perPage+1;a>t&&(a=t),t||(l=0);for(let d of n){if(this.options.server){k(d,"hidden");continue}s=Number(D(d,"aria-rowindex")),s>a||s=this.pages,this.btnLast.disabled=this.page>=this.pages),o.querySelector(".dg-low").textContent=l.toString(),o.querySelector(".dg-high").textContent=a.toString(),o.querySelector(".dg-total").textContent=`${this.totalRecords()}`,o.toggleAttribute("hidden",this.options.autohidePager&&this.options.perPage>this.totalRecords())}totalPages(){return Math.ceil(this.totalRecords()/this.options.perPage)}totalRecords(){return this.options.server?this.meta?.[this.options.serverParams.metaFilteredKey]||0:this.data.length}},j=it;var st=class{constructor(t){this.grid=t}connected(){}disconnected(){}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}},m=st;var ot=class extends m{constructor(t){super(t),this.isResizing=!1}renderResizer(t){let e=this.grid,i=e.table,o=g(e,"thead tr.dg-head-columns th");for(let n of o){if(T(n,"dg-not-resizable"))continue;let s=document.createElement("div");E(s,"dg-resizer"),s.ariaLabel=t,n.appendChild(s);let a=0,l=0,d=0,u=0,h=f=>{if(f.clientX>u)return;let b=l+(f.clientX-a);n.dataset.minWidth&&b>Number.parseInt(n.dataset.minWidth)&&c(n,"width",b)},p=()=>{e.log("resized column"),setTimeout(()=>{this.isResizing=!1},0),W(s,"dg-resizer-active"),e.options.reorder&&(n.draggable=!0),n.style.overflow="hidden",O(document,"mousemove",h),O(document,"mouseup",p),y(e,"columnResized",{col:D(n,"field"),width:D(n,"width")})};A(s,"click",f=>{f.stopPropagation()}),A(s,"mousedown",f=>{f.stopPropagation(),this.isResizing=!0;let b=f.target,P=g(e,"dg-head-columns th").filter(v=>!v.hasAttribute("hidden")),w=P.findIndex(v=>v===b.parentNode);e.log("resize column"),E(s,"dg-resizer-active"),k(n,"draggable"),n.style.overflow="visible",s.style.height=`${i.offsetHeight-1}px`,a=f.clientX,l=n.offsetWidth,d=(P.length-w)*30,u=tt(b).left+e.offsetWidth-d,c(n,"width",l);for(let v=0;vw&&k(o[v],"width");A(document,"mousemove",h),A(document,"mouseup",p)})}}},Pt=ot;function K(r,t,e="nodeName"){let i=r;for(;i[e]!==t;)i=i.parentElement;return i}var nt=class extends m{connected(){this.menu=this.grid.querySelector(".dg-menu")}disconnected(){this.grid.headerRow&&O(this.grid.headerRow,"contextmenu",this)}attachContextMenu(){let t=this.grid;A(t.headerRow,"contextmenu",this)}onchange(t){let e=this.grid,i=t.target,o=i.dataset.name;if(i.checked)e.showColumn(o);else{if(e.visibleColumns().length<=1){i.checked=!0;return}e.hideColumn(o)}e.fixPage()}oncontextmenu(t){t.preventDefault();let e=K(t.target,"THEAD"),i=this.menu,o=e.getBoundingClientRect(),n=t.clientX-o.left,s=t.clientY-o.top;i.style.top=`${s}px`,i.style.left=`${n}px`,k(i,"hidden"),n+150>o.width&&(n-=i.offsetWidth,i.style.left=`${n}px`);let a=l=>{i.contains(l.target)||(c(i,"hidden",""),O(document,"click",a))};A(document,"click",a)}createMenu(){let t=this.grid,e=this.menu;for(;e.lastChild;)e.removeChild(e.lastChild);e.addEventListener("change",this);for(let i of t.options.columns){if(i.attr)continue;let o=document.createElement("li"),n=document.createElement("label"),s=document.createElement("input");c(s,"type","checkbox"),c(s,"data-name",i.field),i.hidden||(s.checked=!0);let a=document.createTextNode(i.title);n.appendChild(s),n.appendChild(a),o.appendChild(n),e.appendChild(o)}}},At=nt;var rt=class extends m{makeHeaderDraggable(t){let e=this.grid;t.draggable=!0,A(t,"dragstart",i=>{if(e.plugins.ColumnResizer?.isResizing&&i.preventDefault){i.preventDefault();return}e.log("reorder col"),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",i.target.getAttribute("aria-colindex"))}),A(t,"dragover",i=>(i.preventDefault&&i.preventDefault(),i.dataTransfer.dropEffect="move",!1)),A(t,"drop",i=>{i.stopPropagation&&i.stopPropagation();let o=i.target,n=K(o,"TH"),s=Number.parseInt(i.dataTransfer.getData("text/plain")),a=Number.parseInt(n.getAttribute("aria-colindex"));if(s===a){e.log("reordered col stayed the same");return}e.log(`reordered col from ${s} to ${a}`);let l=e.startColIndex(),d=e.options.columns[s-l];e.options.columns[s-l]=e.options.columns[a-l],e.options.columns[a-l]=d;let u=(h,p)=>{let f=p.parentNode.getAttribute("aria-rowindex"),b=e.querySelector(`${h} tr[aria-rowindex="${f}"] [aria-colindex="${a}"]`);c(p,"aria-colindex",a),c(b,"aria-colindex",s);let S=document.createElement("th");p.parentNode.insertBefore(S,p),b.parentNode.replaceChild(p,b),S.parentNode.replaceChild(b,S)};for(let h of g(e,`thead th[aria-colindex="${s}"]`))u("thead",h);for(let h of g(e,`tbody td[aria-colindex="${s}"]`))u("tbody",h);return e.options.columns=g(e,"thead tr.dg-head-columns th[field]").map(h=>e.options.columns.find(p=>p.field===D(h,"field"))),y(e,"columnReordered",{col:d.field,from:s,to:a}),!1})}},St=rt;var at=class extends m{constructor(t){super(t),this.touch=null}connected(){let t=this.grid;t.addEventListener("touchstart",this,{passive:!0}),t.addEventListener("touchmove",this,{passive:!0})}disconnected(){let t=this.grid;t.removeEventListener("touchstart",this),t.removeEventListener("touchmove",this)}ontouchstart(t){this.touch=t.touches[0]}ontouchmove(t){if(!this.touch)return;let e=this.grid,i=this.touch.clientX-t.touches[0].clientX,o=this.touch.clientY-t.touches[0].clientY;Math.abs(i)>Math.abs(o)&&(i>0?e.getNext():e.getPrev()),this.touch=null}},Lt=at;var H="dg-selectable",lt="dg-select-all",kt="form-check-input",dt=class extends m{#t=`tbody tr${this.visibleOnly?":not([hidden])":""} .${H} input[type=checkbox]`;#e=`tbody .${H} input`;disconnected(){this.selectAll&&this.selectAll.removeEventListener("change",this)}get isSingleSelect(){return this.grid.options.singleSelect}get visibleOnly(){return this.grid.options.selectVisibleOnly}getSelection(...t){let e=this.grid,i=[],o=g(e,`${this.#e}:checked`);for(let n of o){let s=Number.parseInt(n.dataset.id),a=e.data[s-1];if(!a){console.warn(`Item ${s} not found`);continue}t.length===0?i.push(a):t.length===1?i.push(a[t[0]]):i.push(Object.fromEntries(t.map(l=>[l,a[l]])))}return this.isSingleSelect?i[0]??{}:i}clearCheckboxes(t){if(!this.grid.options.selectVisibleOnly)return;let i=g(t,`tr[hidden] .${H} input`);for(let o of i)o.checked=!1,this.isSingleSelect&&(o.dataset.toggled="false");this.selectAll.checked=!1}colIndex(){return this.grid.startColIndex()-2}createHeaderCol(t){let e=document.createElement("th");c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0,this.selectAll=document.createElement("input"),this.selectAll.type="checkbox",this.selectAll.classList.add(lt),this.selectAll.classList.add(kt),this.selectAll.addEventListener("change",this);let i=document.createElement("label");i.hidden=this.isSingleSelect,i.appendChild(this.selectAll),e.appendChild(i),e.setAttribute("width","40"),t.appendChild(e)}createFilterCol(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H),e.tabIndex=0,t.appendChild(e)}shouldSelectAll(t){this.selectAll&&(t.addEventListener("change",this),t.dispatchEvent(new Event("change")))}createDataCol(t){let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H);let i=document.createElement("input");i.dataset.id=t.getAttribute("aria-rowindex"),i.type=this.isSingleSelect?"radio":"checkbox",i.classList.add(kt),this.isSingleSelect&&(i.name="dg-row-select",i.dataset.toggled="false");let o=document.createElement("label");o.classList.add("dg-clickable-cell"),o.appendChild(i),e.appendChild(o),o.addEventListener("click",this),t.appendChild(e)}onclick(t){if(!this.isSingleSelect)return t.stopPropagation();let e=t.target,i=e.dataset.toggled!=="true";i&&Y(`${this.#t.replace("checkbox","radio")}`,this.grid)?.forEach(o=>{o.name===e.name&&o!==e&&(o.checked=o.dataset.toggled=!1)}),e.checked=e.dataset.toggled=i,!i&&this.onchange(t)}onchange(t){let e=t.target,i=this.grid;if(T(t.target,lt))g(i,this.#e).forEach(o=>{(!this.visibleOnly||o.offsetWidth)&&(o.checked=this.selectAll.checked)});else if(e.matches(this.#t)){if(!e.closest(`.${H}`))return;let o=g(i,this.#t);this.selectAll.checked=o.every(n=>n.checked)}e.matches(`.${lt},${this.#e}`)&&y(e,"rowsSelected",{selection:i.getSelection()},!0)}},Et=dt;var ct=class extends m{constructor(t){super(t),this.hasFixedHeight=!1,t.style.height&&(t.style.overflowY="auto",this.hasFixedHeight=!0)}createFakeRow(){let e=this.grid.querySelector("tbody"),i=document.createElement("tr");c(i,"role","row"),c(i,"hidden",""),i.classList.add("dg-fake-row"),i.tabIndex=0,e?.appendChild(i)}get fakeRow(){return this.grid.querySelector(".dg-fake-row")}updateFakeRow(){let t=this.grid,e=this.fakeRow;if(!e||t.options.perPage>t.totalRecords()||t.page!==t.totalPages()||!t.options.autoheight)return;let i=t.options.perPage*t.rowHeight,o=t.querySelectorAll("tbody tr:not([hidden])").length,n=o>1?i-o*t.rowHeight:i;n>0?(c(e,"height",n),e.removeAttribute("hidden")):e.removeAttribute("height")}},Dt=ct;var ht=class extends m{computeSize(t,e,i,o){let n=this.grid;if(U(t,"width"))return D(t,"width");if(!n.data.length)return;let s=n.data[0],a=n.data[n.data.length-1],l=s[e.field]?s[e.field].toString():"",d=a[e.field]?a[e.field].toString():"";d.length>l.length&&(l=d);let u=0;return l.length<=6?u=i:l.length>50?u=o:u=_(`${l}0000`,t),u>o&&(u=o),u{let i=Number.parseInt(t.dataset.responsive)||1;return(Number.parseInt(e.dataset.responsive)||1)-i})}var Wt=G(r=>{for(let t of r){let e=t.target,i=e.table;if(e.plugins.ResponsiveGrid.observerBlocked)return;let o=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize,n=Number.parseInt(o.inlineSize),s=i.offsetWidth,a=g(e.headerRow,"th").reduce((P,w)=>P+w.offsetWidth,0),l=(a||s)-n-1,d=50,u=e.plugins.ResponsiveGrid.prevAction,h=Ft(g(e.headerRow,"th[field]").reverse().filter(P=>P.dataset.responsive!=="0")),p=!1;if(e.log(`table is ${s}/${a} and available size is ${n}. Diff: ${l}`),l>0){if(u==="show")return;e.plugins.ResponsiveGrid.prevAction="hide";let P=l,w=h.filter(v=>!v.hasAttribute("hidden")&&v.hasAttribute("data-responsive"));if(w.length===0&&(w=h.filter(v=>!v.hasAttribute("hidden")),w.length===1))return;for(let v of w){if(P<0)continue;let $=v.offsetWidth,R=v.getAttribute("field");R&&(v.dataset.baseWidth=`${v.offsetWidth}`,e.hideColumn(R,!1),e.setColProp(R,"responsiveHidden",!0),p=!0,P-=$,P=Math.round(P))}}else{if(u==="hide")return;e.plugins.ResponsiveGrid.prevAction="show";let P=h.filter($=>!$.hasAttribute("hidden")).reduce(($,R)=>{let z=R.dataset.minWidth?Number.parseInt(R.dataset.minWidth):R.offsetWidth;return $+z},0)+d,w=n-P,v=h.slice().reverse().filter($=>$.hasAttribute("hidden"));for(let $ of v){if(ww){w=-1;continue}let z=$.getAttribute("field");z&&(e.showColumn(z,!1),e.setColProp(z,"responsiveHidden",!1),p=!0,w-=R,w=Math.round(w))}}let f=N(e.table,"tfoot"),b=g(e.table,".dg-footer > div").reduce((P,w)=>P+w.offsetWidth,0),S=f.offsetWidth-b;b>n?E(f,"dg-footer-compact"):S>250&&W(f,"dg-footer-compact"),p&&e.renderTable(),setTimeout(()=>{e.plugins.ResponsiveGrid.prevAction=null},1e3),e.table.style.visibility="visible"}},100),Rt=new ResizeObserver(Wt),gt=class extends m{constructor(t){super(t),this.observerBlocked=!1,this.prevAction=null}connected(){this.grid.options.responsive&&this.observe()}disconnected(){this.unobserve()}observe(){this.grid.options.responsive&&(Rt.observe(this.grid),this.grid.style.display="block",this.grid.style.overflowX="hidden")}unobserve(){Rt.unobserve(this.grid),this.grid.style.display="unset",this.grid.style.overflowX="unset"}blockObserver(){this.observerBlocked=!0,ut&&clearTimeout(ut)}unblockObserver(){ut=setTimeout(()=>{this.observerBlocked=!1},200)}hasHiddenColumns(){let t=!1;for(let e of this.grid.options.columns)e.responsiveHidden&&(t=!0);return t}colIndex(){return this.grid.startColIndex()-1}createHeaderCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),c(e,"width","40"),e.classList.add(`${L}-toggle`,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0}createFilterCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.tabIndex=0}createDataCol(t){if(!this.grid.options.responsiveToggle)return;let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.innerHTML=`
`,t.appendChild(e),e.addEventListener("click",this),e.addEventListener("mousedown",this)}computeLabelWidth(){let t=0,e=0;for(;t<120;){e++;let i=N(this.grid,`.dg-head-columns th[aria-colindex="${e}"]`);if(i)t+=i.offsetWidth;else break}return t}onmousedown(t){t.preventDefault()}onclick(t){t.stopPropagation();let e=t.currentTarget,i=e.parentElement,o=N(e,`.${L}-open`),n=N(e,`.${L}-close`);if(this.blockObserver(),T(i,`${L}-expanded`)){W(i,`${L}-expanded`),o.style.display="unset",n.style.display="none";let l=i.nextElementSibling,a=g(l,`.${L}-hidden`);for(let d of a)i.appendChild(d),c(d,"hidden");l.parentElement.removeChild(l)}else{E(i,`${L}-expanded`),o.style.display="none",n.style.display="unset";let l=x("tr");xt(l,i),E(l,`${L}-child-row`);let a=x("td",l);c(a,"colspan",this.grid.columnsLength(!0));let d=x("table",a);E(d,`${L}-table`);let u=g(i,`.${L}-hidden`),h=this.computeLabelWidth();for(let p of u){let f=x("tr",d),b=p.dataset.name,S=x("th",f);S.style.width=`${h}px`,S.innerHTML=b,f.appendChild(p),k(p,"hidden")}}this.unblockObserver()}},It=gt;var pt=class extends m{hasActions(){return this.grid.options.actions.length>0}makeActionHeader(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions","dg-not-sortable","dg-not-resizable",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionFilter(t){let e=document.createElement("th");e.setAttribute("role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionRow(t,e){let i=this.grid.labels,o=document.createElement("td");c(o,"role","gridcell"),c(o,"aria-colindex",this.grid.columnsLength(!0)),o.classList.add("dg-actions",this.actionClass),o.tabIndex=0;let n=document.createElement("button");n.classList.add("dg-actions-toggle"),n.innerHTML="\u2630",o.appendChild(n),A(n,"click",s=>{s.stopPropagation(),s.target.parentElement.classList.toggle("dg-actions-expand")});for(let s of this.grid.options.actions){let l=document.createElement("button");s.html?l.innerHTML=s.html:l.innerText=s.title??s.name,s.title&&(l.title=s.title),s.url&&(l.type="submit",l.formAction=M(s.url,e)),s.class&&l.classList.add(...s.class.split(" "));let a=d=>{if(d.stopPropagation(),s.confirm&&!confirm(i.areYouSure)){d.preventDefault();return}y(this.grid,"action",{data:e,action:s.name})};l.addEventListener("click",a),o.appendChild(l),s.default&&(t.classList.add("dg-actionable"),t.addEventListener("click",a))}t.appendChild(o)}get actionClass(){return this.grid.options.actions.length<3&&!this.grid.options.collapseActions?`dg-actions-${this.grid.options.actions.length}`:"dg-actions-more"}},Tt=pt;var ft=class extends m{makeEditableInput(t,e,i,o){let n=this.grid.getAttribute("id"),s=document.createElement("input");s.type=e.editableType||"text",s.type==="email"&&(s.inputMode="email"),s.type==="decimal"&&(s.type="text",s.inputMode="decimal"),s.autocomplete="off",s.spellcheck=!1,s.tabIndex=0,s.classList.add("dg-editable"),s.name=`${n.replace("-","_")}[${o+1}][${e.field}]`,s.value=i[e.field],s.dataset.field=e.field,s.addEventListener("click",l=>l.stopPropagation()),s.addEventListener("keypress",l=>{if(l.type==="keypress"){let a=l.keyCode||l.key;(a===13||a==="Enter")&&(s.blur(),l.preventDefault())}}),s.addEventListener("blur",()=>{s.value!==i[s.dataset.field]&&(i[s.dataset.field]=s.value,y(this.grid,"edit",{data:i,value:s.value}))}),t.appendChild(s)}},Nt=ft;var mt=class extends m{connected(){this.grid.options.spinnerClass&&this.grid.plugins.SpinnerSupport&&this.add()}add(){let t=this.grid,e=t.options.spinnerClass;if(!e)return;let i=e.split(" ").map(n=>`.${n}`).join(""),o=` +
`,t.appendChild(e),e.addEventListener("click",this),e.addEventListener("mousedown",this)}computeLabelWidth(){let t=0,e=0;for(;t<120;){e++;let i=N(this.grid,`.dg-head-columns th[aria-colindex="${e}"]`);if(i)t+=i.offsetWidth;else break}return t}onmousedown(t){t.preventDefault()}onclick(t){t.stopPropagation();let e=t.currentTarget,i=e.parentElement,o=N(e,`.${L}-open`),n=N(e,`.${L}-close`);if(this.blockObserver(),T(i,`${L}-expanded`)){W(i,`${L}-expanded`),o.style.display="unset",n.style.display="none";let a=i.nextElementSibling,l=g(a,`.${L}-hidden`);for(let d of l)i.appendChild(d),c(d,"hidden");a.parentElement.removeChild(a)}else{E(i,`${L}-expanded`),o.style.display="none",n.style.display="unset";let a=x("tr");xt(a,i),E(a,`${L}-child-row`);let l=x("td",a);c(l,"colspan",this.grid.columnsLength(!0));let d=x("table",l);E(d,`${L}-table`);let u=g(i,`.${L}-hidden`),h=this.computeLabelWidth();for(let p of u){let f=x("tr",d),b=p.dataset.name,S=x("th",f);S.style.width=`${h}px`,S.innerHTML=b,f.appendChild(p),k(p,"hidden")}}this.unblockObserver()}},It=gt;var pt=class extends m{hasActions(){return this.grid.options.actions.length>0}makeActionHeader(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions","dg-not-sortable","dg-not-resizable",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionFilter(t){let e=document.createElement("th");e.setAttribute("role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionRow(t,e){let i=this.grid.labels,o=document.createElement("td");c(o,"role","gridcell"),c(o,"aria-colindex",this.grid.columnsLength(!0)),o.classList.add("dg-actions",this.actionClass),o.tabIndex=0;let n=document.createElement("button");n.classList.add("dg-actions-toggle"),n.innerHTML="\u2630",o.appendChild(n),A(n,"click",s=>{s.stopPropagation(),s.target.parentElement.classList.toggle("dg-actions-expand")});for(let s of this.grid.options.actions){let a=document.createElement("button");s.html?a.innerHTML=s.html:a.innerText=s.title??s.name,s.title&&(a.title=s.title),s.url&&(a.type="submit",a.formAction=M(s.url,e)),s.class&&a.classList.add(...s.class.split(" "));let l=d=>{if(d.stopPropagation(),s.confirm&&!confirm(i.areYouSure)){d.preventDefault();return}y(this.grid,"action",{data:e,action:s.name})};a.addEventListener("click",l),o.appendChild(a),s.default&&(t.classList.add("dg-actionable"),t.addEventListener("click",l))}t.appendChild(o)}get actionClass(){return this.grid.options.actions.length<3&&!this.grid.options.collapseActions?`dg-actions-${this.grid.options.actions.length}`:"dg-actions-more"}},Tt=pt;var ft=class extends m{makeEditableInput(t,e,i,o){let n=this.grid.getAttribute("id"),s=document.createElement("input");s.type=e.editableType||"text",s.type==="email"&&(s.inputMode="email"),s.type==="decimal"&&(s.type="text",s.inputMode="decimal"),s.autocomplete="off",s.spellcheck=!1,s.tabIndex=0,s.classList.add("dg-editable"),s.name=`${n.replace("-","_")}[${o+1}][${e.field}]`,s.value=i[e.field],s.dataset.field=e.field,s.addEventListener("click",a=>a.stopPropagation()),s.addEventListener("keypress",a=>{if(a.type==="keypress"){let l=a.keyCode||a.key;(l===13||l==="Enter")&&(s.blur(),a.preventDefault())}}),s.addEventListener("blur",()=>{s.value!==i[s.dataset.field]&&(i[s.dataset.field]=s.value,y(this.grid,"edit",{data:i,value:s.value}))}),t.appendChild(s)}},Nt=ft;var mt=class extends m{connected(){this.grid.options.spinnerClass&&this.grid.plugins.SpinnerSupport&&this.add()}add(){let t=this.grid,e=t.options.spinnerClass;if(!e)return;let i=e.split(" ").map(n=>`.${n}`).join(""),o=` -`;if(!I("#dg-styles")){let n=I("head")??I("body"),s=/head/i.test(n.tagName)?"beforeend":"afterbegin";n.insertAdjacentHTML(s,o)}!I(`i${i}`,t)&&t.insertAdjacentHTML("afterbegin",``)}},Ht=mt;var bt=class extends m{constructor(t){super(t),this.cachedState=null,this.isFilterSortSet=!1,this.isDataLoaded=!1,this.isScrolled=!1,this.log("Init")}async connected(){this.log("connected");let t=this.grid;if(this.log(t.options),!t.options.saveState){this.log("disabled");return}this.log("enabled");let e=this._getState();if(e){let n=async()=>{if(!t.options.server)return;let l=500,a=Date.now(),d;for(;(d=!t.options.columns?.length)&&Date.now()-arequestAnimationFrame(u));d&&this.log("Timeout waiting for columns.")};await(async()=>{await n(),this.log("hide columns");for(let l of e.columns)if(l.hidden){let a=t.options.columns.find(d=>d.field===l.field);a.hidden=!0}this.log("set: meta, pages"),t.options.perPage=e.perPage,t.options.server&&(t.meta=e.meta,t.pages=e.pages,t.page=e.page)})()}this.cachedState=e,this.log("cachedState",this.cachedState);let i=t.loadData;t.loadData=function(...n){return i.apply(this,n).finally(()=>{let s=this.plugins.SaveState;if(s.log("loadData",this.options.columns),!t.classList.contains("dg-initialized")){s.log("not init, loadData skipped");return}if(s.log("loadData finished, set param controls",this.options.columns),s.cachedState&&!s.isFilterSortSet){s.log("set sort and filters");let d=g(t,"thead tr.dg-head-columns th[aria-sort]");for(let h of d)h.setAttribute("aria-sort","none");t.querySelector(`thead tr.dg-head-columns th[field='${s.cachedState.sort}']`)?.setAttribute("aria-sort",s.cachedState.sortDir);let u=g(t.filterRow,"[id^=dg-filter]");s.log("filters",u);for(let h of u)h.value=s?.cachedState?.filters?.[h.dataset.name]??"",s.log({name:h.dataset.name,val:h.value,saveState:s});s.isFilterSortSet=!0}let l={meta:t.meta,pages:t.pages,page:t.page,perPage:t.options.perPage,filters:{},columns:t.options.columns.map(d=>({field:d.field,hidden:d.hidden})),sort:t.getSort(),sortDir:t.getSortDir(),scrollTo:window.scrollY},a=t.getFilters();s.log("filters",a);for(let d of Object.keys(a))l.filters[d]=a[d]??"",s.log({key:d,val:a[d],newState:l,filters:a});s.log("store new state",l),s._setState(l),!t.options.server&&s.cachedState&&!s.isDataLoaded&&(s.isDataLoaded=!0,t.filterData(),t.page=s.cachedState.page,t.pageChanged(),s.log("data loaded"))})};let o=()=>{let n=t.plugins.SaveState,s=n._getState();s&&(s.columns=t.options.columns.map(l=>({field:l.field,hidden:l.hidden})),s.sort=t.getSort(),s.sortDir=t.getSortDir(),s.scrollTo=window.scrollY,n._setState(s))};document.addEventListener("scrollend",o),t.addEventListener("headerRendered",o),t.addEventListener("bodyRendered",n=>{if(!t.classList.contains("dg-initialized")||t.classList.contains("dg-loading"))return;t.options.server||o();let s=t.plugins.SaveState;!s.cachedState||!s.isFilterSortSet||(s.isDataLoaded?s.isScrolled||(s.isScrolled=!0,window.scrollTo({top:s.cachedState.scrollTo,left:0,behavior:"instant"})):(s.isDataLoaded=!0,t.reload(),s.log("***grid reloaded")))})}log(...t){this.grid.log("[Save-State] ",...t)}_getState(){let t;try{t=JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`))}catch{}return t}_setState(t){sessionStorage.setItem(`gridSaveState_${this.grid.id}`,JSON.stringify(t))}},Ot=bt;j.registerPlugins({ColumnResizer:Pt,ContextMenu:At,DraggableHeaders:St,TouchSupport:Lt,SelectableRows:Et,FixedHeight:Dt,AutosizeColumn:$t,ResponsiveGrid:It,RowActions:Tt,EditableColumn:Nt,SpinnerSupport:Ht,SaveState:Ot});customElements.get("data-grid")||customElements.define("data-grid",j);var xi=j,Mt=typeof globalThis<"u"?globalThis:self;Mt.DataGrid=j;export{xi as default}; +`;if(!I("#dg-styles")){let n=I("head")??I("body"),s=/head/i.test(n.tagName)?"beforeend":"afterbegin";n.insertAdjacentHTML(s,o)}!I(`i${i}`,t)&&t.insertAdjacentHTML("afterbegin",``)}},Ht=mt;var bt=class extends m{constructor(t){super(t),this.cachedState=null,this.isFilterSortSet=!1,this.isDataLoaded=!1,this.isScrolled=!1,this.log("Init")}async connected(){this.log("connected");let t=this.grid;if(this.log(t.options),!t.options.saveState){this.log("disabled");return}this.log("enabled");let e=this._getState();if(e){let n=async()=>{if(!t.options.server)return;let a=500,l=Date.now(),d;for(;(d=!t.options.columns?.length)&&Date.now()-lrequestAnimationFrame(u));d&&this.log("Timeout waiting for columns.")};await(async()=>{await n(),this.log("hide columns");for(let a of e.columns)if(a.hidden){let l=t.options.columns.find(d=>d.field===a.field);l.hidden=!0}this.log("set: meta, pages"),t.options.perPage=e.perPage,t.options.server&&(t.meta=e.meta,t.pages=e.pages,t.page=e.page)})()}this.cachedState=e,this.log("cachedState",this.cachedState);let i=t.loadData;t.loadData=function(...n){return i.apply(this,n).finally(()=>{let s=this.plugins.SaveState;if(s.log("loadData",this.options.columns),!t.classList.contains("dg-initialized")){s.log("not init, loadData skipped");return}if(s.log("loadData finished, set param controls",this.options.columns),s.cachedState&&!s.isFilterSortSet){s.log("set sort and filters");let d=g(t,"thead tr.dg-head-columns th[aria-sort]");for(let h of d)h.setAttribute("aria-sort","none");t.querySelector(`thead tr.dg-head-columns th[field='${s.cachedState.sort}']`)?.setAttribute("aria-sort",s.cachedState.sortDir);let u=g(t.filterRow,"[id^=dg-filter]");s.log("filters",u);for(let h of u)h.value=s?.cachedState?.filters?.[h.dataset.name]??"",s.log({name:h.dataset.name,val:h.value,saveState:s});s.isFilterSortSet=!0}let a={meta:t.meta,pages:t.pages,page:t.page,perPage:t.options.perPage,filters:{},columns:t.options.columns.map(d=>({field:d.field,hidden:d.hidden})),sort:t.getSort(),sortDir:t.getSortDir(),scrollTo:window.scrollY},l=t.getFilters();s.log("filters",l);for(let d of Object.keys(l))a.filters[d]=l[d]??"",s.log({key:d,val:l[d],newState:a,filters:l});s.log("store new state",a),s._setState(a),!t.options.server&&s.cachedState&&!s.isDataLoaded&&(s.isDataLoaded=!0,t.filterData(),t.page=s.cachedState.page,t.pageChanged(),s.log("data loaded"))})};let o=()=>{let n=t.plugins.SaveState,s=n._getState();s&&(s.columns=t.options.columns.map(a=>({field:a.field,hidden:a.hidden})),s.sort=t.getSort(),s.sortDir=t.getSortDir(),s.scrollTo=window.scrollY,n._setState(s))};document.addEventListener("scrollend",o),t.addEventListener("headerRendered",o),t.addEventListener("bodyRendered",n=>{if(!t.classList.contains("dg-initialized")||t.classList.contains("dg-loading"))return;t.options.server||o();let s=t.plugins.SaveState;!s.cachedState||!s.isFilterSortSet||(s.isDataLoaded?s.isScrolled||(s.isScrolled=!0,window.scrollTo({top:s.cachedState.scrollTo,left:0,behavior:"instant"})):(s.isDataLoaded=!0,t.reload(),s.log("***grid reloaded")))})}log(...t){this.grid.log("[Save-State] ",...t)}_getState(){let t;try{t=JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`))}catch{}return t}_setState(t){sessionStorage.setItem(`gridSaveState_${this.grid.id}`,JSON.stringify(t))}},Ot=bt;j.registerPlugins({ColumnResizer:Pt,ContextMenu:At,DraggableHeaders:St,TouchSupport:Lt,SelectableRows:Et,FixedHeight:Dt,AutosizeColumn:$t,ResponsiveGrid:It,RowActions:Tt,EditableColumn:Nt,SpinnerSupport:Ht,SaveState:Ot});customElements.get("data-grid")||customElements.define("data-grid",j);var xi=j,Mt=typeof globalThis<"u"?globalThis:self;Mt.DataGrid=j;export{xi as default}; /** * Data Grid custom element * https://github.com/lekoala/data-grid/ diff --git a/dist/data-grid.min.js.map b/dist/data-grid.min.js.map index 66aae5b..69c1308 100644 --- a/dist/data-grid.min.js.map +++ b/dist/data-grid.min.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/utils/camelize.js", "../src/utils/normalizeData.js", "../src/utils/shortcuts.js", "../src/core/base-element.js", "../src/utils/addSelectOption.js", "../src/utils/appendParamsToUrl.js", "../src/utils/convertArray.js", "../src/utils/elementOffset.js", "../src/utils/interpolate.js", "../src/utils/getTextWidth.js", "../src/utils/randstr.js", "../src/utils/debounce.js", "../src/data-grid.js", "../src/core/base-plugin.js", "../src/plugins/column-resizer.js", "../src/utils/getParentElement.js", "../src/plugins/context-menu.js", "../src/plugins/draggable-headers.js", "../src/plugins/touch-support.js", "../src/plugins/selectable-rows.js", "../src/plugins/fixed-height.js", "../src/plugins/autosize-column.js", "../src/plugins/responsive-grid.js", "../src/plugins/row-actions.js", "../src/plugins/editable-column.js", "../src/plugins/spinner-support.js", "../src/plugins/save-state.js", "../data-grid.js"], - "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const grid = this.grid;\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], - "mappings": "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", + "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], + "mappings": "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", "names": ["camelize", "str", "m", "chr", "normalizeData", "v", "val", "supportedPassiveTypes", "passiveOpts", "type", "getAttribute", "el", "name", "hasAttribute", "setAttribute", "v", "check", "removeAttribute", "on", "listener", "off", "dispatch", "el", "name", "data", "bubbles", "opts", "hasClass", "addClass", "removeClass", "toggleClass", "$", "selector", "base", "$$", "find", "findAll", "ce", "tagName", "parent", "el", "insertAfter", "newNode", "existingNode", "BaseElement", "options", "opt", "v", "setAttribute", "jsonConfig", "data", "key", "normalizeData", "getAttribute", "event", "template", "dispatch", "attributeName", "oldValue", "newValue", "isOption", "transformer", "attr", "camelize", "base_element_default", "addSelectOption", "el", "value", "label", "checked", "opt", "appendParamsToUrl", "url", "params", "key", "k", "convertArray", "v", "bv", "elementOffset", "el", "rect", "scrollLeft", "scrollTop", "interpolate", "str", "data", "$1", "$2", "canvas", "getTextWidth", "text", "el", "withPadding", "styles", "fontWeight", "fontSize", "fontFamily", "padding", "paddingLeft", "paddingRight", "context", "metrics", "randstr", "prefix", "debounce", "handler", "timeout", "timer", "args", "plugins", "labels", "applyColumnDefinition", "el", "column", "setAttribute", "addClass", "DataGrid", "_DataGrid", "base_element_default", "randstr", "pluginName", "pluginClass", "attr", "camelize", "v", "#setNoData", "tbody", "list", "plugin", "columns", "cols", "key", "col", "item", "convertArray", "$", "val", "initOnly", "pv", "updatePage", "addSelectOption", "field", "found", "prop", "c", "render", "dispatch", "start", "visibleOnly", "len", "tr", "find", "row", "removeAttribute", "headers", "findAll", "th", "fieldName", "value", "k", "i", "keys", "force", "data", "metaKey", "dataKey", "callbackOrUrl", "needRender", "flagEmpty", "resolve", "response", "err", "event", "filters", "inputs", "input", "name", "baseCol", "haveClasses", "sort", "stack", "itemA", "itemB", "a", "b", "valA", "valB", "columnName", "sortDir", "dir", "reject", "base", "url", "params", "appendParamsToUrl", "newError", "error", "sortedColumn", "thead", "tfoot", "td", "availableWidth", "colMaxWidth", "idx", "ce", "sampleTh", "totalWidth", "colIdx", "computedWidth", "getTextWidth", "w", "colAvailableWidth", "visibleCols", "lastCol", "scrollbarWidth", "diff", "thWithWidth", "hasClass", "actualWidth", "minWidth", "newWidth", "rowsWithSort", "sortableRow", "relatedTh", "filter", "filteredRows", "eventName", "eventHandler", "debounce", "e", "isKeyPressFilter", "isSelect", "uniqueValues", "opt", "on", "ev", "toggleClass", "tv", "interpolate", "prev", "total", "p", "bodyRows", "index", "high", "low", "getAttribute", "data_grid_default", "BasePlugin", "grid", "event", "base_plugin_default", "ColumnResizer", "base_plugin_default", "grid", "resizeLabel", "table", "cols", "findAll", "col", "hasClass", "resizer", "addClass", "startX", "startW", "remainingSpace", "max", "mouseMoveHandler", "e", "newWidth", "setAttribute", "mouseUpHandler", "removeClass", "off", "dispatch", "getAttribute", "on", "target", "visibleCols", "columnIndex", "column", "removeAttribute", "elementOffset", "j", "column_resizer_default", "getParentElement", "el", "type", "prop", "parent", "ContextMenu", "base_plugin_default", "off", "grid", "on", "e", "t", "field", "target", "getParentElement", "menu", "rect", "x", "y", "removeAttribute", "documentClickHandler", "setAttribute", "col", "li", "label", "checkbox", "text", "context_menu_default", "DraggableHeaders", "base_plugin_default", "th", "grid", "on", "e", "t", "target", "getParentElement", "index", "targetIndex", "offset", "tmp", "swapNodes", "selector", "el1", "rowIndex", "el2", "setAttribute", "newNode", "findAll", "c", "getAttribute", "dispatch", "draggable_headers_default", "TouchSupport", "base_plugin_default", "grid", "e", "xDiff", "yDiff", "touch_support_default", "SELECTABLE_CLASS", "SELECT_ALL_CLASS", "CHECKBOX_CLASS", "SelectableRows", "base_plugin_default", "#cbSelector", "#inputSelector", "keys", "grid", "selectedData", "inputs", "findAll", "checkbox", "idx", "item", "k", "tbody", "input", "tr", "th", "setAttribute", "label", "td", "e", "el", "unchecked", "$$", "r", "hasClass", "cb", "totalCheckboxes", "dispatch", "selectable_rows_default", "FixedHeight", "base_plugin_default", "grid", "tbody", "tr", "setAttribute", "fakeRow", "max", "visibleRows", "fakeHeight", "fixed_height_default", "AutosizeColumn", "base_plugin_default", "th", "column", "min", "max", "grid", "hasAttribute", "getAttribute", "firstVal", "lastVal", "v", "v2", "width", "getTextWidth", "setAttribute", "autosize_column_default", "RESPONSIVE_CLASS", "obsTo", "sortByPriority", "list", "a", "b", "v1", "callback", "debounce", "entries", "entry", "grid", "table", "contentBoxSize", "size", "tableWidth", "realTableWidth", "findAll", "result", "th", "diff", "minWidth", "prevAction", "headerCols", "col", "changed", "remaining", "cols", "colWidth", "field", "requiredWidth", "width", "filteredHeaderCols", "footer", "find", "realFooterWidth", "div", "availableFooterWidth", "addClass", "removeClass", "resizeObserver", "ResponsiveGrid", "base_plugin_default", "flag", "tr", "ce", "setAttribute", "td", "idealWidth", "consideredCol", "hCol", "ev", "open", "close", "hasClass", "childRow", "hiddenCols", "insertAfter", "childRowTd", "childTable", "childTableRow", "label", "labelCol", "removeAttribute", "responsive_grid_default", "RowActions", "base_plugin_default", "tr", "actionsTh", "setAttribute", "item", "labels", "td", "actionsToggle", "on", "ev", "action", "button", "interpolate", "actionHandler", "dispatch", "row_actions_default", "EditableColumn", "base_plugin_default", "td", "column", "item", "i", "gridId", "input", "ev", "key", "dispatch", "editable_column_default", "SpinnerSupport", "base_plugin_default", "grid", "classes", "cls", "e", "template", "$", "styleParent", "position", "spinner_support_default", "SaveState", "base_plugin_default", "grid", "cachedState", "waitForColumns", "timeout", "start", "colAbsent", "resolve", "col", "hideCol", "c", "dgLoadData", "args", "saveState", "sortableHeaders", "findAll", "el", "filters", "newState", "key", "updateState", "state", "ev", "data", "save_state_default", "data_grid_default", "column_resizer_default", "context_menu_default", "draggable_headers_default", "touch_support_default", "selectable_rows_default", "fixed_height_default", "autosize_column_default", "responsive_grid_default", "row_actions_default", "editable_column_default", "spinner_support_default", "save_state_default", "global"] } diff --git a/src/plugins/context-menu.js b/src/plugins/context-menu.js index 451d9e6..00dbc48 100644 --- a/src/plugins/context-menu.js +++ b/src/plugins/context-menu.js @@ -1,101 +1,100 @@ -import BasePlugin from "../core/base-plugin.js"; -import getParentElement from "../utils/getParentElement.js"; -import { find, off, on, removeAttribute, setAttribute } from "../utils/shortcuts.js"; - -/** - * Create a right click menu on the headers - */ -class ContextMenu extends BasePlugin { - connected() { - /** - * @type {HTMLUListElement} - */ - this.menu = this.grid.querySelector(".dg-menu"); - } - disconnected() { - if (this.grid.headerRow) { - off(this.grid.headerRow, "contextmenu", this); - } - } - - attachContextMenu() { - const grid = this.grid; - on(grid.headerRow, "contextmenu", this); - } - - onchange(e) { - const grid = this.grid; - const t = e.target; - const field = t.dataset.name; - if (t.checked) { - grid.showColumn(field); - } else { - // Prevent hidding last - if (grid.visibleColumns().length <= 1) { - // Restore checkbox value - t.checked = true; - return; - } - grid.hideColumn(field); - } - grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10). - } - - oncontextmenu(e) { - e.preventDefault(); - const grid = this.grid; - const target = getParentElement(e.target, "THEAD"); - const menu = this.menu; - const rect = target.getBoundingClientRect(); - let x = e.clientX - rect.left; - const y = e.clientY - rect.top; - - menu.style.top = `${y}px`; - menu.style.left = `${x}px`; - - removeAttribute(menu, "hidden"); - if (x + 150 > rect.width) { - x -= menu.offsetWidth; - menu.style.left = `${x}px`; - } - - const documentClickHandler = (e) => { - if (!menu.contains(e.target)) { - setAttribute(menu, "hidden", ""); - off(document, "click", documentClickHandler); - } - }; - on(document, "click", documentClickHandler); - } - createMenu() { - const grid = this.grid; - const menu = this.menu; - while (menu.lastChild) { - menu.removeChild(menu.lastChild); - } - menu.addEventListener("change", this); - - for (const col of grid.options.columns) { - if (col.attr) { - continue; - } - const li = document.createElement("li"); - const label = document.createElement("label"); - const checkbox = document.createElement("input"); - setAttribute(checkbox, "type", "checkbox"); - setAttribute(checkbox, "data-name", col.field); - if (!col.hidden) { - checkbox.checked = true; - } - const text = document.createTextNode(col.title); - - label.appendChild(checkbox); - label.appendChild(text); - - li.appendChild(label); - menu.appendChild(li); - } - } -} - -export default ContextMenu; +import BasePlugin from "../core/base-plugin.js"; +import getParentElement from "../utils/getParentElement.js"; +import { find, off, on, removeAttribute, setAttribute } from "../utils/shortcuts.js"; + +/** + * Create a right click menu on the headers + */ +class ContextMenu extends BasePlugin { + connected() { + /** + * @type {HTMLUListElement} + */ + this.menu = this.grid.querySelector(".dg-menu"); + } + disconnected() { + if (this.grid.headerRow) { + off(this.grid.headerRow, "contextmenu", this); + } + } + + attachContextMenu() { + const grid = this.grid; + on(grid.headerRow, "contextmenu", this); + } + + onchange(e) { + const grid = this.grid; + const t = e.target; + const field = t.dataset.name; + if (t.checked) { + grid.showColumn(field); + } else { + // Prevent hidding last + if (grid.visibleColumns().length <= 1) { + // Restore checkbox value + t.checked = true; + return; + } + grid.hideColumn(field); + } + grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10). + } + + oncontextmenu(e) { + e.preventDefault(); + const target = getParentElement(e.target, "THEAD"); + const menu = this.menu; + const rect = target.getBoundingClientRect(); + let x = e.clientX - rect.left; + const y = e.clientY - rect.top; + + menu.style.top = `${y}px`; + menu.style.left = `${x}px`; + + removeAttribute(menu, "hidden"); + if (x + 150 > rect.width) { + x -= menu.offsetWidth; + menu.style.left = `${x}px`; + } + + const documentClickHandler = (e) => { + if (!menu.contains(e.target)) { + setAttribute(menu, "hidden", ""); + off(document, "click", documentClickHandler); + } + }; + on(document, "click", documentClickHandler); + } + createMenu() { + const grid = this.grid; + const menu = this.menu; + while (menu.lastChild) { + menu.removeChild(menu.lastChild); + } + menu.addEventListener("change", this); + + for (const col of grid.options.columns) { + if (col.attr) { + continue; + } + const li = document.createElement("li"); + const label = document.createElement("label"); + const checkbox = document.createElement("input"); + setAttribute(checkbox, "type", "checkbox"); + setAttribute(checkbox, "data-name", col.field); + if (!col.hidden) { + checkbox.checked = true; + } + const text = document.createTextNode(col.title); + + label.appendChild(checkbox); + label.appendChild(text); + + li.appendChild(label); + menu.appendChild(li); + } + } +} + +export default ContextMenu; From 99afe86a9a9264aaf9df163a2dfd78129a47842f Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Tue, 24 Mar 2026 16:54:38 -0400 Subject: [PATCH 2/4] Updated esbuild. --- package-lock.json | 855 +++++++++++++--------------------------------- package.json | 2 +- 2 files changed, 230 insertions(+), 627 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2b3fd71..064500b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "sass": "^1.86.3" }, "devDependencies": { - "@happy-dom/global-registrator": "^17.4.4", + "@happy-dom/global-registrator": "^20.8.7", "ava": "^6.2.0", "esbuild": "*", "jsdoc": "^4.0.4", @@ -71,9 +71,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", - "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", "cpu": [ "ppc64" ], @@ -88,9 +88,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", - "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", "cpu": [ "arm" ], @@ -105,9 +105,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", - "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", "cpu": [ "arm64" ], @@ -122,9 +122,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", - "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", "cpu": [ "x64" ], @@ -139,9 +139,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", - "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", "cpu": [ "arm64" ], @@ -156,9 +156,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", - "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", "cpu": [ "x64" ], @@ -173,9 +173,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", - "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", "cpu": [ "arm64" ], @@ -190,9 +190,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", - "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", "cpu": [ "x64" ], @@ -207,9 +207,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", - "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", "cpu": [ "arm" ], @@ -224,9 +224,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", - "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", "cpu": [ "arm64" ], @@ -241,9 +241,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", - "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", "cpu": [ "ia32" ], @@ -258,9 +258,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", - "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", "cpu": [ "loong64" ], @@ -275,9 +275,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", - "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", "cpu": [ "mips64el" ], @@ -292,9 +292,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", - "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", "cpu": [ "ppc64" ], @@ -309,9 +309,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", - "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", "cpu": [ "riscv64" ], @@ -326,9 +326,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", - "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", "cpu": [ "s390x" ], @@ -343,9 +343,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", - "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", "cpu": [ "x64" ], @@ -360,9 +360,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", - "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", "cpu": [ "arm64" ], @@ -377,9 +377,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", - "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", "cpu": [ "x64" ], @@ -394,9 +394,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", - "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", "cpu": [ "arm64" ], @@ -411,9 +411,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", - "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", "cpu": [ "x64" ], @@ -428,9 +428,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", - "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", "cpu": [ "arm64" ], @@ -445,9 +445,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", - "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", "cpu": [ "x64" ], @@ -462,9 +462,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", - "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", "cpu": [ "arm64" ], @@ -479,9 +479,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", - "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", "cpu": [ "ia32" ], @@ -496,9 +496,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", - "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", "cpu": [ "x64" ], @@ -513,77 +513,17 @@ } }, "node_modules/@happy-dom/global-registrator": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@happy-dom/global-registrator/-/global-registrator-17.4.4.tgz", - "integrity": "sha512-njrU74GrYVHO43upIJr96f7pEmUG7YLZbHCGiHALBECeVnDKpepzL9kVc7KIl8S2nQOkPA0rAA1EyC3xASb54w==", + "version": "20.8.7", + "resolved": "https://registry.npmjs.org/@happy-dom/global-registrator/-/global-registrator-20.8.7.tgz", + "integrity": "sha512-fOmQ7AQG1xAYmyYeneq5jWSsgHb8YFHY5aDeW2bKIv1gQBYXiEdMvgkoPGs4Q8o2G5UVDKUNyQxuqYuTuXlZMw==", "dev": true, "license": "MIT", "dependencies": { - "happy-dom": "^17.4.4" + "@types/node": ">=20.0.0", + "happy-dom": "^20.8.7" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=20.0.0" } }, "node_modules/@isaacs/fs-minipass": { @@ -980,17 +920,6 @@ "node": ">=0.10" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@rollup/pluginutils": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", @@ -1069,6 +998,33 @@ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, + "node_modules/@types/node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/whatwg-mimetype": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", + "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@vercel/nft": { "version": "0.27.9", "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.27.9.tgz", @@ -1406,9 +1362,9 @@ "dev": true }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -1881,21 +1837,6 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/current-module-paths": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.2.tgz", @@ -1993,13 +1934,6 @@ } } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, "node_modules/electron-to-chromium": { "version": "1.5.136", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.136.tgz", @@ -2038,9 +1972,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", - "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2051,32 +1985,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.8", - "@esbuild/android-arm": "0.25.8", - "@esbuild/android-arm64": "0.25.8", - "@esbuild/android-x64": "0.25.8", - "@esbuild/darwin-arm64": "0.25.8", - "@esbuild/darwin-x64": "0.25.8", - "@esbuild/freebsd-arm64": "0.25.8", - "@esbuild/freebsd-x64": "0.25.8", - "@esbuild/linux-arm": "0.25.8", - "@esbuild/linux-arm64": "0.25.8", - "@esbuild/linux-ia32": "0.25.8", - "@esbuild/linux-loong64": "0.25.8", - "@esbuild/linux-mips64el": "0.25.8", - "@esbuild/linux-ppc64": "0.25.8", - "@esbuild/linux-riscv64": "0.25.8", - "@esbuild/linux-s390x": "0.25.8", - "@esbuild/linux-x64": "0.25.8", - "@esbuild/netbsd-arm64": "0.25.8", - "@esbuild/netbsd-x64": "0.25.8", - "@esbuild/openbsd-arm64": "0.25.8", - "@esbuild/openbsd-x64": "0.25.8", - "@esbuild/openharmony-arm64": "0.25.8", - "@esbuild/sunos-x64": "0.25.8", - "@esbuild/win32-arm64": "0.25.8", - "@esbuild/win32-ia32": "0.25.8", - "@esbuild/win32-x64": "0.25.8" + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" } }, "node_modules/escalade": { @@ -2248,23 +2182,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -2413,17 +2330,34 @@ } }, "node_modules/happy-dom": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.4.4.tgz", - "integrity": "sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA==", + "version": "20.8.7", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.8.7.tgz", + "integrity": "sha512-7wfBi+UqulQlyLcis+9a+hTK0A/fMO4QKP6w6J9HnadXVkRdOvGf/N5G4XVpfgCYfnY7oKazlOSdWmsfatNSLQ==", "dev": true, "license": "MIT", "dependencies": { - "webidl-conversions": "^7.0.0", - "whatwg-mimetype": "^3.0.0" + "@types/node": ">=20.0.0", + "@types/whatwg-mimetype": "^3.0.2", + "@types/ws": "^8.18.1", + "entities": "^7.0.1", + "whatwg-mimetype": "^3.0.0", + "ws": "^8.18.3" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/happy-dom/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/has-flag": { @@ -2470,9 +2404,9 @@ } }, "node_modules/immutable": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", - "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", + "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", "license": "MIT" }, "node_modules/imurmurhash": { @@ -2604,29 +2538,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -2637,10 +2548,11 @@ } }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -2845,10 +2757,11 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -2863,18 +2776,12 @@ "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", "dev": true }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -2996,9 +2903,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -3029,14 +2936,13 @@ } }, "node_modules/minizlib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", - "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, "license": "MIT", "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" }, "engines": { "node": ">= 18" @@ -3222,13 +3128,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, "node_modules/parse-ms": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", @@ -3252,33 +3151,6 @@ "node": ">=0.10.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/path-type": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", @@ -3578,69 +3450,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -3740,29 +3549,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -3889,62 +3675,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -3960,30 +3690,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4039,39 +3745,22 @@ } }, "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", + "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", + "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "engines": { "node": ">=18" } }, - "node_modules/tar/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/temp-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", @@ -4198,10 +3887,18 @@ } }, "node_modules/underscore": { - "version": "1.13.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", - "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", - "dev": true + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" }, "node_modules/unicorn-magic": { "version": "0.1.0", @@ -4264,16 +3961,6 @@ "node": ">=12.17" } }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, "node_modules/well-known-symbols": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", @@ -4311,22 +3998,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -4360,96 +4031,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -4530,6 +4111,28 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xmlcreate": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", diff --git a/package.json b/package.json index b336025..87aeda2 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ ] }, "devDependencies": { - "@happy-dom/global-registrator": "^17.4.4", + "@happy-dom/global-registrator": "^20.8.7", "ava": "^6.2.0", "esbuild": "*", "jsdoc": "^4.0.4", From ee34e766e1473ec4c4873ddc506d8893bf90a1ac Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Wed, 25 Mar 2026 14:50:21 -0400 Subject: [PATCH 3/4] Added paste event handling for column filter text input elements. --- dist/data-grid.js | 8 +- dist/data-grid.js.map | 4 +- dist/data-grid.min.js | 8 +- dist/data-grid.min.js.map | 6 +- src/data-grid.js | 3924 +++++++++++++++++++------------------ 5 files changed, 1979 insertions(+), 1971 deletions(-) diff --git a/dist/data-grid.js b/dist/data-grid.js index 1823be3..6b8ebe4 100644 --- a/dist/data-grid.js +++ b/dist/data-grid.js @@ -1638,15 +1638,19 @@ var DataGrid = class _DataGrid extends base_element_default { this.options.filterKeypressDelay = 0; const filteredRows = findAll(tr, this._filterSelector); for (const el of filteredRows) { - const eventName = /select/i.test(el.tagName) ? "change" : "keyup"; + const isSelect = /select/i.test(el.tagName); + const eventName = isSelect ? "change" : "keyup"; const eventHandler = debounce((e) => { const key = e.keyCode || e.key; const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key); - if (key === 13 || key === "Enter" || isKeyPressFilter || e.type === "change") { + if (key === 13 || key === "Enter" || isKeyPressFilter || e.type === "change" || e.type === "paste") { this.filterData.call(this); } }, this.options.filterKeypressDelay); el.addEventListener(eventName, eventHandler); + if (!isSelect) { + el.addEventListener("paste", eventHandler); + } } } createFilterElement(column, relatedTh) { diff --git a/dist/data-grid.js.map b/dist/data-grid.js.map index 0b5f42a..8706248 100644 --- a/dist/data-grid.js.map +++ b/dist/data-grid.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/utils/camelize.js", "../src/utils/normalizeData.js", "../src/utils/shortcuts.js", "../src/core/base-element.js", "../src/utils/addSelectOption.js", "../src/utils/appendParamsToUrl.js", "../src/utils/convertArray.js", "../src/utils/elementOffset.js", "../src/utils/interpolate.js", "../src/utils/getTextWidth.js", "../src/utils/randstr.js", "../src/utils/debounce.js", "../src/data-grid.js", "../src/core/base-plugin.js", "../src/plugins/column-resizer.js", "../src/utils/getParentElement.js", "../src/plugins/context-menu.js", "../src/plugins/draggable-headers.js", "../src/plugins/touch-support.js", "../src/plugins/selectable-rows.js", "../src/plugins/fixed-height.js", "../src/plugins/autosize-column.js", "../src/plugins/responsive-grid.js", "../src/plugins/row-actions.js", "../src/plugins/editable-column.js", "../src/plugins/spinner-support.js", "../src/plugins/save-state.js", "../data-grid.js"], - "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], - "mappings": "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", + "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const isSelect = /select/i.test(el.tagName);\r\n const eventName = isSelect ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\" || e.type === \"paste\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n if (!isSelect) { // Add paste event support for text input filters\r\n el.addEventListener(\"paste\", eventHandler);\r\n }\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], + "mappings": "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", "names": ["col", "e", "th", "labels", "filters", "data_grid_default"] } diff --git a/dist/data-grid.min.js b/dist/data-grid.min.js index 36bc2b5..1670135 100644 --- a/dist/data-grid.min.js +++ b/dist/data-grid.min.js @@ -1,4 +1,4 @@ -function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUpperCase())}function V(r){if(r==="true")return!0;if(r==="false")return!1;if(r===""||r==="null")return null;if(r===Number(r).toString())return Number(r);if(r&&typeof r.substring=="function"&&["[","{"].includes(r.substring(0,1)))try{let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(decodeURIComponent(t))}catch{return console.error(`Failed to parse ${r}`),{}}return r}var zt=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];function vt(r){return zt.includes(r)?{passive:!0}:{}}function D(r,t){return r.getAttribute(t)}function U(r,t){return r.hasAttribute(t)}function c(r,t,e="",i=!1){i&&U(r,t)||r.setAttribute(t,`${e}`)}function k(r,t){U(r,t)&&r.removeAttribute(t)}function A(r,t,e){r.addEventListener(t,e,vt(t))}function O(r,t,e){r.removeEventListener(t,e,vt(t))}function y(r,t,e={},i=!1){let o={};i&&(o.bubbles=!0),e&&(o.detail=e),r.dispatchEvent(new CustomEvent(t,o))}function T(r,t){return r.classList.contains(t)}function E(r,t){r.classList.add(...t.split(" "))}function W(r,t){r.classList.remove(...t.split(" "))}function yt(r,t){r.classList.toggle(t)}function I(r,t=document){return r instanceof HTMLElement?r:t.querySelector(r)}function Y(r,t=document){return Array.from(t.querySelectorAll(r))}function N(r,t){return I(t,r)}function g(r,t){return Y(t,r)}function x(r,t=null){let e=document.createElement(r);return t&&t.appendChild(e),e}function xt(r,t){t.parentNode.insertBefore(r,t.nextSibling)}var J=class extends HTMLElement{constructor(t={}){super(),this.options=Object.assign({},this.defaultOptions,this.normalizedDataset,t),this.log("constructor"),this.setup=!1,this.fireEvents=!0,this._ready(),this.log("ready")}get defaultOptions(){return{}}getOption(t){return this.options[t]}setOption(t,e){c(this,`data-${t}`,e)}toggleOption(t){c(this,`data-${t}`,!this.getOption(t))}get normalizedDataset(){let t=this.dataset.config?JSON.parse(this.dataset.config):{},e={...this.dataset};for(let i in e)i==="config"||!e.hasOwnProperty(i)||typeof e[i]=="function"||(e[i]=V(e[i]));return Object.assign(e,t),e}static template(){return""}_ready(){}log(...t){this.options.debug&&console.log(`[${D(this,"id")}] `,...t)}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}_connected(){}connectedCallback(){this.setup||(this.setup=!0,setTimeout(async()=>{this.log("connectedCallback");let t=document.createElement("template");t.innerHTML=this.constructor.template(),this.appendChild(t.content.cloneNode(!0)),await this._connected(),y(this,"connected")},0))}_disconnected(){}disconnectedCallback(){setTimeout(()=>{!this.isConnected&&this.setup&&(this.log("disconnectedCallback"),this._disconnected(),y(this,"disconnected"),this.setup=!1)},0)}get transformAttributes(){return{}}attributeChangedCallback(t,e,i){if(e===i)return;this.log(`attributeChangedCallback: ${t}`);let o=!1,n=this.transformAttributes[t]??V,s=t;s.indexOf("data-")===0&&(s=s.slice(5),o=!0),s=F(s),o?this.options[s]=n(i):this[s]=n(i),this.fireEvents&&this[`${s}Changed`]&&this[`${s}Changed`]()}},Ct=J;function Z(r,t,e,i=!1){let o=document.createElement("option");o.value=`${t}`,i&&(o.selected=!0),o.label=e,r.appendChild(o)}function Q(r,t={}){for(let e of Object.keys(t))if(Array.isArray(t[e]))for(let i of Object.keys(t[e]))r.searchParams.append(isNaN(i)?`${e}[${i}]`:e,t[e][i]);else r.searchParams.append(e,t[e])}function X(r){if(typeof r=="string"){if(r[0]==="["){let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(t)}return r.split(",")}return Array.isArray(r)?r:(console.error("Invalid array",r),[])}function tt(r){let t=r.getBoundingClientRect(),e=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+i,left:t.left+e}}function M(r,t){return r.replace(/\{([^}]+)?\}/g,(e,i)=>t[i])}var et;function _(r,t=document.body,e=!1){let i=window.getComputedStyle(t||document.createElement("div")),o=i.getPropertyValue("font-weight")||"normal",n=i.getPropertyValue("font-size")||"1rem",s=i.getPropertyValue("font-family")||"Arial",a=0;if(e){let u=i.getPropertyValue("padding-left")||"0",h=i.getPropertyValue("padding-right")||"0";a=Number.parseInt(u)+Number.parseInt(h)}et||(et=document.createElement("canvas"));let l=et.getContext("2d");l.font=`${o} ${n} ${s}`;let d=l.measureText(r);return Number.parseInt(d.width)+a}function q(r){return Math.random().toString(36).replace("0.",r||"")}function G(r,t=300){let e=null;return(...i)=>{clearTimeout(e),e=setTimeout(()=>{e=null,r(...i)},t)}}var B={},C={itemsPerPage:"Items per page",gotoPage:"Go to page",gotoFirstPage:"Go to first page",gotoPrevPage:"Go to previous page",gotoNextPage:"Go to next page",gotoLastPage:"Go to last page",of:"of",items:"items",resizeColumn:"Resize column",noData:"No data",areYouSure:"Are you sure?",networkError:"Network response error"};function wt(r,t){t.width&&c(r,"width",t.width),t.class&&E(r,t.class),t.hidden&&(c(r,"hidden",""),t.responsiveHidden&&E(r,"dg-responsive-hidden"))}var it=class r extends Ct{_filterSelector="[id^=dg-filter]";_excludedRowElementSelector="a,button,input,select,textarea";_excludedKeys=[37,39,38,40,45,36,35,33,34,27,20,16,17,91,92,18,93,144,231,"ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Insert","Home","End","PageUp","PageDown","Escape","CapsLock","Shift","Control","Meta","Alt","ContextMenu","NumLock","Unidentified"];_ready(){c(this,"id",this.options.id??q("el-"),!0),this.data=[],this.originalData,this.options=this.options||this.defaultOptions,this.options.singleSelect&&(this.options.selectable=!0),this.fireEvents=!1,this.page=this.options.defaultPage||1,this.pages=0,this.meta,this.plugins={};for(let[t,e]of Object.entries(B))this.plugins[t]=new e(this);for(let t of r.observedAttributes)t.indexOf("data-")===0&&c(this,t,this.options[F(t.slice(5))])}static template(){return` +function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUpperCase())}function V(r){if(r==="true")return!0;if(r==="false")return!1;if(r===""||r==="null")return null;if(r===Number(r).toString())return Number(r);if(r&&typeof r.substring=="function"&&["[","{"].includes(r.substring(0,1)))try{let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(decodeURIComponent(t))}catch{return console.error(`Failed to parse ${r}`),{}}return r}var zt=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];function vt(r){return zt.includes(r)?{passive:!0}:{}}function D(r,t){return r.getAttribute(t)}function U(r,t){return r.hasAttribute(t)}function c(r,t,e="",i=!1){i&&U(r,t)||r.setAttribute(t,`${e}`)}function k(r,t){U(r,t)&&r.removeAttribute(t)}function S(r,t,e){r.addEventListener(t,e,vt(t))}function O(r,t,e){r.removeEventListener(t,e,vt(t))}function y(r,t,e={},i=!1){let o={};i&&(o.bubbles=!0),e&&(o.detail=e),r.dispatchEvent(new CustomEvent(t,o))}function T(r,t){return r.classList.contains(t)}function E(r,t){r.classList.add(...t.split(" "))}function W(r,t){r.classList.remove(...t.split(" "))}function yt(r,t){r.classList.toggle(t)}function I(r,t=document){return r instanceof HTMLElement?r:t.querySelector(r)}function Y(r,t=document){return Array.from(t.querySelectorAll(r))}function N(r,t){return I(t,r)}function g(r,t){return Y(t,r)}function x(r,t=null){let e=document.createElement(r);return t&&t.appendChild(e),e}function xt(r,t){t.parentNode.insertBefore(r,t.nextSibling)}var J=class extends HTMLElement{constructor(t={}){super(),this.options=Object.assign({},this.defaultOptions,this.normalizedDataset,t),this.log("constructor"),this.setup=!1,this.fireEvents=!0,this._ready(),this.log("ready")}get defaultOptions(){return{}}getOption(t){return this.options[t]}setOption(t,e){c(this,`data-${t}`,e)}toggleOption(t){c(this,`data-${t}`,!this.getOption(t))}get normalizedDataset(){let t=this.dataset.config?JSON.parse(this.dataset.config):{},e={...this.dataset};for(let i in e)i==="config"||!e.hasOwnProperty(i)||typeof e[i]=="function"||(e[i]=V(e[i]));return Object.assign(e,t),e}static template(){return""}_ready(){}log(...t){this.options.debug&&console.log(`[${D(this,"id")}] `,...t)}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}_connected(){}connectedCallback(){this.setup||(this.setup=!0,setTimeout(async()=>{this.log("connectedCallback");let t=document.createElement("template");t.innerHTML=this.constructor.template(),this.appendChild(t.content.cloneNode(!0)),await this._connected(),y(this,"connected")},0))}_disconnected(){}disconnectedCallback(){setTimeout(()=>{!this.isConnected&&this.setup&&(this.log("disconnectedCallback"),this._disconnected(),y(this,"disconnected"),this.setup=!1)},0)}get transformAttributes(){return{}}attributeChangedCallback(t,e,i){if(e===i)return;this.log(`attributeChangedCallback: ${t}`);let o=!1,n=this.transformAttributes[t]??V,s=t;s.indexOf("data-")===0&&(s=s.slice(5),o=!0),s=F(s),o?this.options[s]=n(i):this[s]=n(i),this.fireEvents&&this[`${s}Changed`]&&this[`${s}Changed`]()}},Ct=J;function Z(r,t,e,i=!1){let o=document.createElement("option");o.value=`${t}`,i&&(o.selected=!0),o.label=e,r.appendChild(o)}function Q(r,t={}){for(let e of Object.keys(t))if(Array.isArray(t[e]))for(let i of Object.keys(t[e]))r.searchParams.append(isNaN(i)?`${e}[${i}]`:e,t[e][i]);else r.searchParams.append(e,t[e])}function X(r){if(typeof r=="string"){if(r[0]==="["){let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(t)}return r.split(",")}return Array.isArray(r)?r:(console.error("Invalid array",r),[])}function tt(r){let t=r.getBoundingClientRect(),e=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+i,left:t.left+e}}function M(r,t){return r.replace(/\{([^}]+)?\}/g,(e,i)=>t[i])}var et;function _(r,t=document.body,e=!1){let i=window.getComputedStyle(t||document.createElement("div")),o=i.getPropertyValue("font-weight")||"normal",n=i.getPropertyValue("font-size")||"1rem",s=i.getPropertyValue("font-family")||"Arial",a=0;if(e){let h=i.getPropertyValue("padding-left")||"0",u=i.getPropertyValue("padding-right")||"0";a=Number.parseInt(h)+Number.parseInt(u)}et||(et=document.createElement("canvas"));let l=et.getContext("2d");l.font=`${o} ${n} ${s}`;let d=l.measureText(r);return Number.parseInt(d.width)+a}function q(r){return Math.random().toString(36).replace("0.",r||"")}function G(r,t=300){let e=null;return(...i)=>{clearTimeout(e),e=setTimeout(()=>{e=null,r(...i)},t)}}var B={},C={itemsPerPage:"Items per page",gotoPage:"Go to page",gotoFirstPage:"Go to first page",gotoPrevPage:"Go to previous page",gotoNextPage:"Go to next page",gotoLastPage:"Go to last page",of:"of",items:"items",resizeColumn:"Resize column",noData:"No data",areYouSure:"Are you sure?",networkError:"Network response error"};function wt(r,t){t.width&&c(r,"width",t.width),t.class&&E(r,t.class),t.hidden&&(c(r,"hidden",""),t.responsiveHidden&&E(r,"dg-responsive-hidden"))}var it=class r extends Ct{_filterSelector="[id^=dg-filter]";_excludedRowElementSelector="a,button,input,select,textarea";_excludedKeys=[37,39,38,40,45,36,35,33,34,27,20,16,17,91,92,18,93,144,231,"ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Insert","Home","End","PageUp","PageDown","Escape","CapsLock","Shift","Control","Meta","Alt","ContextMenu","NumLock","Unidentified"];_ready(){c(this,"id",this.options.id??q("el-"),!0),this.data=[],this.originalData,this.options=this.options||this.defaultOptions,this.options.singleSelect&&(this.options.selectable=!0),this.fireEvents=!1,this.page=this.options.defaultPage||1,this.pages=0,this.meta,this.plugins={};for(let[t,e]of Object.entries(B))this.plugins[t]=new e(this);for(let t of r.observedAttributes)t.indexOf("data-")===0&&c(this,t,this.options[F(t.slice(5))])}static template(){return` @@ -36,13 +36,13 @@ function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUppe
-`}get labels(){return C}static getLabels(){return C}static setLabels(t){C=Object.assign(C,t)}get noData(){return this.options.noData||this.labels.noData}#t(t){!this.hasDataError&&t.getAttribute("data-empty")!==this.noData&&t.setAttribute("data-empty",this.noData)}get defaultColumn(){return{field:"",title:"",width:0,class:"",attr:"",hidden:!1,editable:!1,noSort:!1,responsive:1,responsiveHidden:!1,format:"",transform:"",filterType:"text",firstFilterOption:{value:"",text:""}}}get defaultOptions(){return{id:null,url:"",perPage:10,debug:!1,filter:!1,menu:!1,sort:!1,server:!1,serverParams:{start:"start",length:"length",search:"search",sort:"sort",sortDir:"sortDir",dataKey:"data",metaKey:"meta",metaTotalKey:"total",metaFilteredKey:"filtered",optionsKey:"options",paramsKey:"params"},defaultSort:"",reorder:!1,dir:"ltr",perPageValues:[10,25,50,100,250],hidePerPage:!1,columns:[],actions:[],collapseActions:!1,selectable:!1,selectVisibleOnly:!0,singleSelect:!1,defaultPage:1,resizable:!1,autosize:!0,expand:!1,autoheight:!0,autohidePager:!1,responsive:!1,responsiveToggle:!0,filterOnEnter:!0,filterKeypressDelay:500,spinnerClass:"",saveState:!1,errorMessage:"",noData:""}}get isInit(){return this.classList.contains("dg-initialized")}get hasDataError(){return this.classList.contains("dg-network-error")}static registerPlugins(t){B=t}static unregisterPlugins(t=null){t===null?B={}:delete B[t]}static registeredPlugins(){return B}convertColumns(t){let e=[];if(typeof t=="object"&&!Array.isArray(t))for(let i of Object.keys(t)){let o=Object.assign({},this.defaultColumn);o.title=t[i],o.field=i,e.push(o)}else for(let i of t){let o=Object.assign({},this.defaultColumn);typeof i=="string"?(o.title=i,o.field=i):typeof i=="object"?(o=Object.assign(o,i),o.field||console.error("Invalid column definition",i),o.title||(o.title=o.field)):console.error("Column definition must be a string or an object"),e.push(o)}return e}static get observedAttributes(){return["page","data-filter","data-sort","data-debug","data-reorder","data-menu","data-selectable","data-single-select","data-url","data-per-page","data-responsive"]}get transformAttributes(){return{columns:t=>this.convertColumns(X(t)),actions:t=>X(t),defaultPage:t=>Number.parseInt(t),perPage:t=>Number.parseInt(t)}}get thead(){return I("thead",this)}get tbody(){return I("tbody",this)}get tfoot(){return I("tfoot",this)}get page(){return Number.parseInt(this.getAttribute("page"))}set page(t){c(this,"page",this.constrainPageValue(t))}urlChanged(t=!1){return t&&!this.isInit?this:(this.reconfig(),this.loadData().then(()=>this.configureUi()))}reconfig(){let t=this.options.columns;return this.options.columns=[],this.configureUi(),this.options.columns=t,this}constrainPageValue(t){let e=t;return this.pages1&&this.page*this.options.perPage>this.totalRecords();)t--;t!==this.page?this.page=t:this.reload(()=>{(!this.plugins.FixedHeight||!this.plugins.FixedHeight.hasFixedHeight)&&this.selectPerPage.scrollIntoView()})}dirChanged(){c(this,"dir",this.options.dir)}defaultSortChanged(){this.sortChanged()}perPageValuesChanged(){if(this.selectPerPage){for(;this.selectPerPage.lastChild;)this.selectPerPage.removeChild(this.selectPerPage.lastChild);for(let t of this.options.perPageValues)Z(this.selectPerPage,t,t,t===this.options.perPage)}}async _connected(){this.table=this.querySelector("table"),this.btnFirst=this.querySelector(".dg-btn-first"),this.btnPrev=this.querySelector(".dg-btn-prev"),this.btnNext=this.querySelector(".dg-btn-next"),this.btnLast=this.querySelector(".dg-btn-last"),this.selectPerPage=this.querySelector(".dg-select-per-page"),this.inputPage=this.querySelector(".dg-input-page"),this.getFirst=this.getFirst.bind(this),this.getPrev=this.getPrev.bind(this),this.getNext=this.getNext.bind(this),this.getLast=this.getLast.bind(this),this.changePerPage=this.changePerPage.bind(this),this.gotoPage=this.gotoPage.bind(this),this.btnFirst.addEventListener("click",this.getFirst),this.btnPrev.addEventListener("click",this.getPrev),this.btnNext.addEventListener("click",this.getNext),this.btnLast.addEventListener("click",this.getLast),this.selectPerPage.addEventListener("change",this.changePerPage),this.selectPerPage.toggleAttribute("hidden",this.options.hidePerPage),this.inputPage.addEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))await t.connected();this.dirChanged(),this.perPageValuesChanged(),await this.init()}_disconnected(){this.btnFirst?.removeEventListener("click",this.getFirst),this.btnPrev?.removeEventListener("click",this.getPrev),this.btnNext?.removeEventListener("click",this.getNext),this.btnLast?.removeEventListener("click",this.getLast),this.selectPerPage?.removeEventListener("change",this.changePerPage),this.inputPage?.removeEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))t.disconnected()}init(){return this.loadData().finally(()=>{this.configureUi(),this.sortChanged(),this.classList.add("dg-initialized"),this.filterChanged(),this.reorderChanged(),this.dirChanged(),this.perPageValuesChanged(),this.pageChanged(),this.fireEvents=!0,this.log("initialized")})}getCol(t){let e=null;for(let i of this.options.columns)i.field===t&&(e=i);return e}getColProp(t,e){let i=this.getCol(t);return i?i[e]:null}setColProp(t,e,i){let o=this.getCol(t);o&&(o[e]=i)}visibleColumns(){return this.options.columns.filter(t=>!t.hidden)}hiddenColumns(){return this.options.columns.filter(t=>t.hidden===!0)}showColumn(t,e=!0){this.setColProp(t,"hidden",!1),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"visible"})}hideColumn(t,e=!0){this.setColProp(t,"hidden",!0),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"hidden"})}startColIndex(){let t=1;return this.options.selectable&&this.plugins.SelectableRows&&t++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&t++,t}isSticky(){return this.hasAttribute("sticky")}columnsLength(t=!1){let e=0;for(let i of this.options.columns)t&&i.hidden||i.attr||e++;return this.options.selectable&&this.plugins.SelectableRows&&e++,this.options.actions.length&&this.plugins.RowActions&&e++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&e++,e}configureUi(){if(!this.table)return this;if(this.table.style.visibility="hidden",this.renderTable(),this.options.responsive&&this.plugins.ResponsiveGrid||(this.table.style.visibility="visible"),!this.rowHeight){let t=N(this,"tbody tr")||N(this,"table tr");t&&(this.rowHeight=t.offsetHeight)}return this.#t(this.tbody),this.fixPage()}filterChanged(){let t=this.querySelector("thead tr.dg-head-filters");this.options.filter?k(t,"hidden"):(this.clearFilters(),c(t,"hidden",""))}reorderChanged(){let t=g(this,"thead tr.dg-head-columns th");for(let e of t)e.classList.contains("dg-selectable")||e.classList.contains("dg-actions")||(this.options.reorder&&this.plugins.DraggableHeaders?e.draggable=!0:e.removeAttribute("draggable"))}sortChanged(){this.log("toggle sort");let t=g(this,"thead tr.dg-head-columns th");for(let e of t){let i=e.getAttribute("field");if(e.classList.contains("dg-not-sortable")||!this.fireEvents&&i===this.options.defaultSort)return;this.options.sort&&!this.getColProp(i,"noSort")?c(e,"aria-sort","none"):k(e,"aria-sort")}}selectableChanged(){this.renderTable()}addRow(t){Array.isArray(this.originalData)&&(this.log("add row"),this.originalData.push(t),this.data=this.originalData.slice(),this.sortData())}removeRow(t=null,e=null){if(!Array.isArray(this.originalData))return;let i=t,o=e;o===null&&(o=this.options.columns[0].field),i===null&&(i=this.originalData[this.originalData.length-1][o]),this.log(`remove row ${o}:${i}`);for(let n=0;n{this.hasDataError||(this.options.server||e?this.renderBody():this.paginate(),typeof t=="function"&&t())}).then(()=>this)}loadData(){let t=()=>!this.data.length&&this.classList.add("dg-empty"),e=this.tbody;return(this.meta||this.originalData||this.isInit)&&(!this.options.server||this.options.server&&!this.fireEvents)?(this.log("skip loadData"),t(),new Promise(i=>{i()})):(this.log("loadData"),this.loading=!0,this.classList.add("dg-loading"),this.classList.remove("dg-empty","dg-network-error"),this.fetchData().then(i=>{if(Array.isArray(i))this.data=i;else{if(!i[this.options.serverParams.dataKey]){console.error("Invalid response, it should contain a data key with an array or be a plain array",i),this.options.url=null;return}this.options=Object.assign(this.options,i[this.options.serverParams.optionsKey]??{}),this.meta=i[this.options.serverParams.metaKey]??{},this.data=i[this.options.serverParams.dataKey]}this.originalData=this.data.slice(),this.fixPage(),this.options.columns.length===0&&this.originalData.length?this.options.columns=this.convertColumns(Object.keys(this.originalData[0])):this.options.columns=this.convertColumns(this.options.columns)}).catch(i=>{this.log(i),e.setAttribute("data-empty",this.options.errorMessage||i.message?.replace(/^\s+|\r\n|\n|\r$/g,"")||C.networkError),this.classList.add("dg-empty","dg-network-error"),y(this,"loadDataFailed",i)}).finally(()=>{t(),this.#t(e),this.classList.remove("dg-loading"),c(this.table,"aria-rowcount",this.data.length),this.loading=!1}))}getFirst(){this.loading||(this.page=1)}getLast(){this.loading||(this.page=this.pages)}getPrev(){this.loading||(this.page=this.page-1)}getNext(){this.loading||(this.page=this.page+1)}gotoPage(t){if(t.type==="keypress"){let e=t.keyCode||t.key;if(e===13||e==="Enter")t.preventDefault();else return}this.page=Number.parseInt(this.inputPage.value)}getSort(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t?t.getAttribute("field"):this.options.defaultSort}getSortDir(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t&&t.getAttribute("aria-sort")||""}getFilters(){let t=[],e=g(this,this._filterSelector);for(let i of e)t[i.dataset.name]=i.value;return t}clearFilters(){let t=g(this,this._filterSelector);for(let e of t)e.value="";this.filterData()}filterData(){if(this.log("filter data"),this.page=1,this.options.server)this.reload();else{this.data=this.originalData?.slice()??[];let t=g(this,this._filterSelector);for(let i of t){let o=i.value;if(o){let n=i.dataset.name;this.data=this.data.filter(s=>`${s[n]}`.toLowerCase().indexOf(o.toLowerCase())!==-1)}}this.pageChanged();let e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");this.options.sort&&e?this.sortData():this.renderBody()}}sortData(t=null){this.log("sort data");let e=t;if(e&&this.getColProp(e.getAttribute("field"),"noSort")){this.log("sorting prevented because column is not sortable");return}if(this.plugins.ColumnResizer?.isResizing){this.log("sorting prevented because resizing");return}if(this.loading){this.log("sorting prevented because loading");return}if(e!==null){let i=n=>["dg-selectable","dg-actions","dg-responsive-toggle"].includes(n),o=g(this,"thead tr:first-child th");for(let n of o)[...n.classList].some(i)||!n.hasAttribute("aria-sort")||n!==e&&n.setAttribute("aria-sort","none");!e.hasAttribute("aria-sort")||e.getAttribute("aria-sort")==="none"?e.setAttribute("aria-sort","ascending"):e.getAttribute("aria-sort")==="ascending"?e.setAttribute("aria-sort","descending"):e.getAttribute("aria-sort")==="descending"&&e.setAttribute("aria-sort","none")}else e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");if(this.options.server)this.loadData().finally(()=>{this.renderBody()});else{let i=e?e.getAttribute("aria-sort"):"none";if(i==="none"){let o=[];this.originalData?.some(n=>(this.data.some(s=>JSON.stringify(n)===JSON.stringify(s)?(o.push(s),!0):!1),o.length===this.data.length)),this.data=o}else{let o=e.getAttribute("field");this.data.sort((n,s)=>{if(!isNaN(n[o])&&!isNaN(s[o]))return i==="ascending"?n[o]-s[o]:s[o]-n[o];let a=i==="ascending"?n[o].toUpperCase():s[o].toUpperCase(),l=i==="ascending"?s[o].toUpperCase():n[o].toUpperCase();switch(!0){case a>l:return 1;case athis._sort(t,"ascending");sortDesc=t=>this._sort(t,"descending");sortNone=t=>this._sort(t,"none");fetchData(){if(!this.options.url)return new Promise((o,n)=>n("No url set"));let t=window.location.href;t.split("/").pop().includes(".")||(t+=t.endsWith("/")?"":"/");let e=new URL(this.options.url,t),i={r:Date.now()};return this.options.server&&(i[this.options.serverParams.start]=this.page-1,i[this.options.serverParams.length]=this.options.perPage,this.options.filter&&(i[this.options.serverParams.search]=this.getFilters()),i[this.options.serverParams.sort]=this.getSort()||"",i[this.options.serverParams.sortDir]=this.getSortDir(),this.meta?.[this.options.serverParams.paramsKey]&&(i=Object.assign(i,this.meta[this.options.serverParams.paramsKey]))),Q(e,i),fetch(e).then(o=>{let n=new Error(o.statusText||C.networkError);if(!o.ok)throw n.response=o,n;return o.clone().json().catch(s=>{let a=s;throw this.options.debug||(a=n),a.response=o,a})})}renderTable(){this.log("render table"),this.options.menu&&this.plugins.ContextMenu&&this.plugins.ContextMenu.createMenu();let t;this.renderHeader(),this.options.defaultSort&&(t=this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`)),t?this.sortData(t):this.renderBody(),this.renderFooter()}renderHeader(){this.log("render header");let t=this.thead;this.createColumnHeaders(t),this.createColumnFilters(t),this.options.resizable&&this.plugins.ColumnResizer&&this.plugins.ColumnResizer.renderResizer(C.resizeColumn),y(this,"headerRendered")}renderFooter(){this.log("render footer");let t=this.tfoot;if(!t)return;let e=t.querySelector("td");t.removeAttribute("hidden"),c(e,"colspan",this.columnsLength(!0)),t.style.display=""}createColumnHeaders(t){let e=this.clientWidth,i=Math.round(e/this.columnsLength(!0)*2),o=0,n;n=x("tr"),this.headerRow=n,n.setAttribute("role","row"),n.setAttribute("aria-rowindex","1"),n.setAttribute("class","dg-head-columns");let s=t?.querySelector("tr.dg-head-columns th");this.log("createColumnHeaders - sampleTh",s),s||(s=x("th"),t?.querySelector("tr").appendChild(s)),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createHeaderCol(n),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createHeaderCol(n),o=0;let a=0;this.log("createColumnHeaders - columns",this.options.columns);for(let d of this.options.columns){if(d.attr)continue;let u=o+this.startColIndex(),h=x("th");h.setAttribute("scope","col"),h.setAttribute("role","columnheader button"),h.setAttribute("aria-colindex",`${u}`),h.setAttribute("id",q("dg-col-")),this.options.sort&&h.setAttribute("aria-sort","none"),h.setAttribute("field",d.field),this.plugins.ResponsiveGrid&&this.options.responsive&&c(h,"data-responsive",d.responsive||"");let p=_(d.title,s,!0)+20;h.dataset.minWidth=`${p}`,wt(h,d),h.tabIndex=0,h.textContent=d.title;let f=0;if(this.options.autosize&&this.plugins.AutosizeColumn){let b=Math.min(e-a,i);f=this.plugins.AutosizeColumn.computeSize(h,d,Number.parseInt(h.dataset.minWidth),b)}else f=Math.max(Number.parseInt(h.dataset.minWidth),Number.parseInt(h.getAttribute("width")));c(h,"width",f),d.hidden?h.setAttribute("hidden",""):a+=f,this.options.reorder&&this.plugins.DraggableHeaders&&this.plugins.DraggableHeaders.makeHeaderDraggable(h),n.appendChild(h),o++}if(ae){this.log(`adjust width to fix size, ${t.offsetWidth} > ${e}`);let d=this.offsetWidth-this.clientWidth,u=t.offsetWidth-e-d;this.options.responsive&&this.plugins.ResponsiveGrid&&(u+=d);let h=g(n,"th[width]");for(let p of h){if(T(p,"dg-not-resizable")||u<=0)continue;let f=Number.parseInt(p.getAttribute("width")),b=p.dataset.minWidth?Number.parseInt(p.dataset.minWidth):0;if(f>b){let S=f-u;Sthis.sortData(d));this.table&&c(this.table,"aria-colcount",this.columnsLength(!0))}createColumnFilters(t){let e=0,i;i=x("tr"),this.filterRow=i,i.setAttribute("role","row"),i.setAttribute("aria-rowindex","2"),i.setAttribute("class","dg-head-filters"),this.options.filter||i.setAttribute("hidden",""),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createFilterCol(i),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createFilterCol(i),this.log("createColumnFilters - columns",this.options.columns);for(let n of this.options.columns){if(n.attr)continue;let s=e+this.startColIndex(),a=t?.querySelector(`tr.dg-head-columns th[aria-colindex="${s}"]`);if(!a){console.warn("Related th not found",s);continue}let l=x("th");l.setAttribute("aria-colindex",`${s}`);let d=this.createFilterElement(n,a);this.options.filter?d.tabIndex=0:l.tabIndex=0,n.hidden&&l.setAttribute("hidden",""),l.appendChild(d),i.appendChild(l),e++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionFilter(i),t?.replaceChild(i,t.querySelector("tr.dg-head-filters")),(typeof this.options.filterKeypressDelay!="number"||this.options.filterOnEnter)&&(this.options.filterKeypressDelay=0);let o=g(i,this._filterSelector);for(let n of o){let s=/select/i.test(n.tagName)?"change":"keyup",a=G(l=>{let d=l.keyCode||l.key,u=!this.options.filterOnEnter&&!this._excludedKeys.some(h=>h===d);(d===13||d==="Enter"||u||l.type==="change")&&this.filterData.call(this)},this.options.filterKeypressDelay);n.addEventListener(s,a)}}createFilterElement(t,e){let i=t.filterType==="select",o=i?x("select"):x("input");if(i){if(!Array.isArray(t.filterList)){let n=[...new Set((this.data??[]).map(s=>s[t.field]))].filter(s=>s).sort();t.filterList=[t.firstFilterOption||this.defaultColumn.firstFilterOption].concat(n.map(s=>({value:s,text:s})))}for(let n of t.filterList){let s=x("option");s.value=n.value,s.text=n.text,o instanceof HTMLSelectElement&&o.add(s)}}else o.type="text",o.inputMode="search",o.autocomplete="off",o.spellcheck=!1;return o.dataset.name=t.field,o.id=q("dg-filter-"),o.setAttribute("aria-labelledby",e.getAttribute("id")),o}renderBody(){this.log("render body");let t,e,i,o=x("tbody");this.data.forEach((s,a)=>{t=x("tr"),c(t,"role","row"),c(t,"hidden",""),c(t,"aria-rowindex",a+1),t.tabIndex=0,this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createDataCol(t),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createDataCol(t),this.options.expand&&(t.classList.add("dg-expandable"),A(t,"click",l=>{l.target.matches(this._excludedRowElementSelector)||(this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.blockObserver(),yt(l.currentTarget,"dg-expanded"),this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.unblockObserver())})),i=0;for(let l of this.options.columns){if(l||console.error("Empty column found!",this.options.columns),l.attr){s[l.field]&&(l.attr==="class"?E(t,s[l.field]):t.setAttribute(l.attr,s[l.field]));return}if(e=x("td"),e.setAttribute("role","gridcell"),e.setAttribute("aria-colindex",`${i}${this.startColIndex()}`),wt(e,l),e.setAttribute("data-name",l.title),e.tabIndex=-1,l.editable&&this.plugins.EditableColumn)E(e,"dg-editable-col"),this.plugins.EditableColumn.makeEditableInput(e,l,s,a);else{let d=s[l.field]??"",u;switch(l.transform){case"uppercase":u=d.toUpperCase();break;case"lowercase":u=d.toLowerCase();break;default:u=d;break}if(l.format){if(l.defaultFormatValue!==void 0&&(u===""||u===null)&&(u=`${l.defaultFormatValue}`),typeof l.format=="string"&&u)e.innerHTML=M(l.format,Object.assign({_v:d,_tv:u},s));else if(l.format instanceof Function){let h=l.format.call(this,{column:l,rowData:s,cellData:u,td:e,tr:t});e.innerHTML=h||u||d}}else e.textContent=u}t.appendChild(e),i++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionRow(t,s),o.appendChild(t),y(this,"rowRendered",{rowData:s,tr:t})}),o.setAttribute("role","rowgroup");let n=this.tbody;n&&o.setAttribute("data-empty",n.getAttribute("data-empty")),this.table?.replaceChild(o,n),this.plugins.FixedHeight&&this.plugins.FixedHeight.createFakeRow(),this.paginate(),this.plugins.SelectableRows&&this.plugins.SelectableRows.shouldSelectAll(o),this.classList.toggle("dg-empty",!this.data.length),y(this,"bodyRendered")}paginate(){this.log("paginate");let t=this.totalRecords(),e=this.page||1,i=this.tbody,o=this.tfoot;if(!i||!o)return;let n=g(i,"tr");this.pages=this.totalPages();let s,a=e*this.options.perPage,l=a-this.options.perPage+1;a>t&&(a=t),t||(l=0);for(let d of n){if(this.options.server){k(d,"hidden");continue}s=Number(D(d,"aria-rowindex")),s>a||s=this.pages,this.btnLast.disabled=this.page>=this.pages),o.querySelector(".dg-low").textContent=l.toString(),o.querySelector(".dg-high").textContent=a.toString(),o.querySelector(".dg-total").textContent=`${this.totalRecords()}`,o.toggleAttribute("hidden",this.options.autohidePager&&this.options.perPage>this.totalRecords())}totalPages(){return Math.ceil(this.totalRecords()/this.options.perPage)}totalRecords(){return this.options.server?this.meta?.[this.options.serverParams.metaFilteredKey]||0:this.data.length}},j=it;var st=class{constructor(t){this.grid=t}connected(){}disconnected(){}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}},m=st;var ot=class extends m{constructor(t){super(t),this.isResizing=!1}renderResizer(t){let e=this.grid,i=e.table,o=g(e,"thead tr.dg-head-columns th");for(let n of o){if(T(n,"dg-not-resizable"))continue;let s=document.createElement("div");E(s,"dg-resizer"),s.ariaLabel=t,n.appendChild(s);let a=0,l=0,d=0,u=0,h=f=>{if(f.clientX>u)return;let b=l+(f.clientX-a);n.dataset.minWidth&&b>Number.parseInt(n.dataset.minWidth)&&c(n,"width",b)},p=()=>{e.log("resized column"),setTimeout(()=>{this.isResizing=!1},0),W(s,"dg-resizer-active"),e.options.reorder&&(n.draggable=!0),n.style.overflow="hidden",O(document,"mousemove",h),O(document,"mouseup",p),y(e,"columnResized",{col:D(n,"field"),width:D(n,"width")})};A(s,"click",f=>{f.stopPropagation()}),A(s,"mousedown",f=>{f.stopPropagation(),this.isResizing=!0;let b=f.target,P=g(e,"dg-head-columns th").filter(v=>!v.hasAttribute("hidden")),w=P.findIndex(v=>v===b.parentNode);e.log("resize column"),E(s,"dg-resizer-active"),k(n,"draggable"),n.style.overflow="visible",s.style.height=`${i.offsetHeight-1}px`,a=f.clientX,l=n.offsetWidth,d=(P.length-w)*30,u=tt(b).left+e.offsetWidth-d,c(n,"width",l);for(let v=0;vw&&k(o[v],"width");A(document,"mousemove",h),A(document,"mouseup",p)})}}},Pt=ot;function K(r,t,e="nodeName"){let i=r;for(;i[e]!==t;)i=i.parentElement;return i}var nt=class extends m{connected(){this.menu=this.grid.querySelector(".dg-menu")}disconnected(){this.grid.headerRow&&O(this.grid.headerRow,"contextmenu",this)}attachContextMenu(){let t=this.grid;A(t.headerRow,"contextmenu",this)}onchange(t){let e=this.grid,i=t.target,o=i.dataset.name;if(i.checked)e.showColumn(o);else{if(e.visibleColumns().length<=1){i.checked=!0;return}e.hideColumn(o)}e.fixPage()}oncontextmenu(t){t.preventDefault();let e=K(t.target,"THEAD"),i=this.menu,o=e.getBoundingClientRect(),n=t.clientX-o.left,s=t.clientY-o.top;i.style.top=`${s}px`,i.style.left=`${n}px`,k(i,"hidden"),n+150>o.width&&(n-=i.offsetWidth,i.style.left=`${n}px`);let a=l=>{i.contains(l.target)||(c(i,"hidden",""),O(document,"click",a))};A(document,"click",a)}createMenu(){let t=this.grid,e=this.menu;for(;e.lastChild;)e.removeChild(e.lastChild);e.addEventListener("change",this);for(let i of t.options.columns){if(i.attr)continue;let o=document.createElement("li"),n=document.createElement("label"),s=document.createElement("input");c(s,"type","checkbox"),c(s,"data-name",i.field),i.hidden||(s.checked=!0);let a=document.createTextNode(i.title);n.appendChild(s),n.appendChild(a),o.appendChild(n),e.appendChild(o)}}},At=nt;var rt=class extends m{makeHeaderDraggable(t){let e=this.grid;t.draggable=!0,A(t,"dragstart",i=>{if(e.plugins.ColumnResizer?.isResizing&&i.preventDefault){i.preventDefault();return}e.log("reorder col"),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",i.target.getAttribute("aria-colindex"))}),A(t,"dragover",i=>(i.preventDefault&&i.preventDefault(),i.dataTransfer.dropEffect="move",!1)),A(t,"drop",i=>{i.stopPropagation&&i.stopPropagation();let o=i.target,n=K(o,"TH"),s=Number.parseInt(i.dataTransfer.getData("text/plain")),a=Number.parseInt(n.getAttribute("aria-colindex"));if(s===a){e.log("reordered col stayed the same");return}e.log(`reordered col from ${s} to ${a}`);let l=e.startColIndex(),d=e.options.columns[s-l];e.options.columns[s-l]=e.options.columns[a-l],e.options.columns[a-l]=d;let u=(h,p)=>{let f=p.parentNode.getAttribute("aria-rowindex"),b=e.querySelector(`${h} tr[aria-rowindex="${f}"] [aria-colindex="${a}"]`);c(p,"aria-colindex",a),c(b,"aria-colindex",s);let S=document.createElement("th");p.parentNode.insertBefore(S,p),b.parentNode.replaceChild(p,b),S.parentNode.replaceChild(b,S)};for(let h of g(e,`thead th[aria-colindex="${s}"]`))u("thead",h);for(let h of g(e,`tbody td[aria-colindex="${s}"]`))u("tbody",h);return e.options.columns=g(e,"thead tr.dg-head-columns th[field]").map(h=>e.options.columns.find(p=>p.field===D(h,"field"))),y(e,"columnReordered",{col:d.field,from:s,to:a}),!1})}},St=rt;var at=class extends m{constructor(t){super(t),this.touch=null}connected(){let t=this.grid;t.addEventListener("touchstart",this,{passive:!0}),t.addEventListener("touchmove",this,{passive:!0})}disconnected(){let t=this.grid;t.removeEventListener("touchstart",this),t.removeEventListener("touchmove",this)}ontouchstart(t){this.touch=t.touches[0]}ontouchmove(t){if(!this.touch)return;let e=this.grid,i=this.touch.clientX-t.touches[0].clientX,o=this.touch.clientY-t.touches[0].clientY;Math.abs(i)>Math.abs(o)&&(i>0?e.getNext():e.getPrev()),this.touch=null}},Lt=at;var H="dg-selectable",lt="dg-select-all",kt="form-check-input",dt=class extends m{#t=`tbody tr${this.visibleOnly?":not([hidden])":""} .${H} input[type=checkbox]`;#e=`tbody .${H} input`;disconnected(){this.selectAll&&this.selectAll.removeEventListener("change",this)}get isSingleSelect(){return this.grid.options.singleSelect}get visibleOnly(){return this.grid.options.selectVisibleOnly}getSelection(...t){let e=this.grid,i=[],o=g(e,`${this.#e}:checked`);for(let n of o){let s=Number.parseInt(n.dataset.id),a=e.data[s-1];if(!a){console.warn(`Item ${s} not found`);continue}t.length===0?i.push(a):t.length===1?i.push(a[t[0]]):i.push(Object.fromEntries(t.map(l=>[l,a[l]])))}return this.isSingleSelect?i[0]??{}:i}clearCheckboxes(t){if(!this.grid.options.selectVisibleOnly)return;let i=g(t,`tr[hidden] .${H} input`);for(let o of i)o.checked=!1,this.isSingleSelect&&(o.dataset.toggled="false");this.selectAll.checked=!1}colIndex(){return this.grid.startColIndex()-2}createHeaderCol(t){let e=document.createElement("th");c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0,this.selectAll=document.createElement("input"),this.selectAll.type="checkbox",this.selectAll.classList.add(lt),this.selectAll.classList.add(kt),this.selectAll.addEventListener("change",this);let i=document.createElement("label");i.hidden=this.isSingleSelect,i.appendChild(this.selectAll),e.appendChild(i),e.setAttribute("width","40"),t.appendChild(e)}createFilterCol(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H),e.tabIndex=0,t.appendChild(e)}shouldSelectAll(t){this.selectAll&&(t.addEventListener("change",this),t.dispatchEvent(new Event("change")))}createDataCol(t){let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H);let i=document.createElement("input");i.dataset.id=t.getAttribute("aria-rowindex"),i.type=this.isSingleSelect?"radio":"checkbox",i.classList.add(kt),this.isSingleSelect&&(i.name="dg-row-select",i.dataset.toggled="false");let o=document.createElement("label");o.classList.add("dg-clickable-cell"),o.appendChild(i),e.appendChild(o),o.addEventListener("click",this),t.appendChild(e)}onclick(t){if(!this.isSingleSelect)return t.stopPropagation();let e=t.target,i=e.dataset.toggled!=="true";i&&Y(`${this.#t.replace("checkbox","radio")}`,this.grid)?.forEach(o=>{o.name===e.name&&o!==e&&(o.checked=o.dataset.toggled=!1)}),e.checked=e.dataset.toggled=i,!i&&this.onchange(t)}onchange(t){let e=t.target,i=this.grid;if(T(t.target,lt))g(i,this.#e).forEach(o=>{(!this.visibleOnly||o.offsetWidth)&&(o.checked=this.selectAll.checked)});else if(e.matches(this.#t)){if(!e.closest(`.${H}`))return;let o=g(i,this.#t);this.selectAll.checked=o.every(n=>n.checked)}e.matches(`.${lt},${this.#e}`)&&y(e,"rowsSelected",{selection:i.getSelection()},!0)}},Et=dt;var ct=class extends m{constructor(t){super(t),this.hasFixedHeight=!1,t.style.height&&(t.style.overflowY="auto",this.hasFixedHeight=!0)}createFakeRow(){let e=this.grid.querySelector("tbody"),i=document.createElement("tr");c(i,"role","row"),c(i,"hidden",""),i.classList.add("dg-fake-row"),i.tabIndex=0,e?.appendChild(i)}get fakeRow(){return this.grid.querySelector(".dg-fake-row")}updateFakeRow(){let t=this.grid,e=this.fakeRow;if(!e||t.options.perPage>t.totalRecords()||t.page!==t.totalPages()||!t.options.autoheight)return;let i=t.options.perPage*t.rowHeight,o=t.querySelectorAll("tbody tr:not([hidden])").length,n=o>1?i-o*t.rowHeight:i;n>0?(c(e,"height",n),e.removeAttribute("hidden")):e.removeAttribute("height")}},Dt=ct;var ht=class extends m{computeSize(t,e,i,o){let n=this.grid;if(U(t,"width"))return D(t,"width");if(!n.data.length)return;let s=n.data[0],a=n.data[n.data.length-1],l=s[e.field]?s[e.field].toString():"",d=a[e.field]?a[e.field].toString():"";d.length>l.length&&(l=d);let u=0;return l.length<=6?u=i:l.length>50?u=o:u=_(`${l}0000`,t),u>o&&(u=o),u{let i=Number.parseInt(t.dataset.responsive)||1;return(Number.parseInt(e.dataset.responsive)||1)-i})}var Wt=G(r=>{for(let t of r){let e=t.target,i=e.table;if(e.plugins.ResponsiveGrid.observerBlocked)return;let o=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize,n=Number.parseInt(o.inlineSize),s=i.offsetWidth,a=g(e.headerRow,"th").reduce((P,w)=>P+w.offsetWidth,0),l=(a||s)-n-1,d=50,u=e.plugins.ResponsiveGrid.prevAction,h=Ft(g(e.headerRow,"th[field]").reverse().filter(P=>P.dataset.responsive!=="0")),p=!1;if(e.log(`table is ${s}/${a} and available size is ${n}. Diff: ${l}`),l>0){if(u==="show")return;e.plugins.ResponsiveGrid.prevAction="hide";let P=l,w=h.filter(v=>!v.hasAttribute("hidden")&&v.hasAttribute("data-responsive"));if(w.length===0&&(w=h.filter(v=>!v.hasAttribute("hidden")),w.length===1))return;for(let v of w){if(P<0)continue;let $=v.offsetWidth,R=v.getAttribute("field");R&&(v.dataset.baseWidth=`${v.offsetWidth}`,e.hideColumn(R,!1),e.setColProp(R,"responsiveHidden",!0),p=!0,P-=$,P=Math.round(P))}}else{if(u==="hide")return;e.plugins.ResponsiveGrid.prevAction="show";let P=h.filter($=>!$.hasAttribute("hidden")).reduce(($,R)=>{let z=R.dataset.minWidth?Number.parseInt(R.dataset.minWidth):R.offsetWidth;return $+z},0)+d,w=n-P,v=h.slice().reverse().filter($=>$.hasAttribute("hidden"));for(let $ of v){if(ww){w=-1;continue}let z=$.getAttribute("field");z&&(e.showColumn(z,!1),e.setColProp(z,"responsiveHidden",!1),p=!0,w-=R,w=Math.round(w))}}let f=N(e.table,"tfoot"),b=g(e.table,".dg-footer > div").reduce((P,w)=>P+w.offsetWidth,0),S=f.offsetWidth-b;b>n?E(f,"dg-footer-compact"):S>250&&W(f,"dg-footer-compact"),p&&e.renderTable(),setTimeout(()=>{e.plugins.ResponsiveGrid.prevAction=null},1e3),e.table.style.visibility="visible"}},100),Rt=new ResizeObserver(Wt),gt=class extends m{constructor(t){super(t),this.observerBlocked=!1,this.prevAction=null}connected(){this.grid.options.responsive&&this.observe()}disconnected(){this.unobserve()}observe(){this.grid.options.responsive&&(Rt.observe(this.grid),this.grid.style.display="block",this.grid.style.overflowX="hidden")}unobserve(){Rt.unobserve(this.grid),this.grid.style.display="unset",this.grid.style.overflowX="unset"}blockObserver(){this.observerBlocked=!0,ut&&clearTimeout(ut)}unblockObserver(){ut=setTimeout(()=>{this.observerBlocked=!1},200)}hasHiddenColumns(){let t=!1;for(let e of this.grid.options.columns)e.responsiveHidden&&(t=!0);return t}colIndex(){return this.grid.startColIndex()-1}createHeaderCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),c(e,"width","40"),e.classList.add(`${L}-toggle`,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0}createFilterCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.tabIndex=0}createDataCol(t){if(!this.grid.options.responsiveToggle)return;let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.innerHTML=`
+`}get labels(){return C}static getLabels(){return C}static setLabels(t){C=Object.assign(C,t)}get noData(){return this.options.noData||this.labels.noData}#t(t){!this.hasDataError&&t.getAttribute("data-empty")!==this.noData&&t.setAttribute("data-empty",this.noData)}get defaultColumn(){return{field:"",title:"",width:0,class:"",attr:"",hidden:!1,editable:!1,noSort:!1,responsive:1,responsiveHidden:!1,format:"",transform:"",filterType:"text",firstFilterOption:{value:"",text:""}}}get defaultOptions(){return{id:null,url:"",perPage:10,debug:!1,filter:!1,menu:!1,sort:!1,server:!1,serverParams:{start:"start",length:"length",search:"search",sort:"sort",sortDir:"sortDir",dataKey:"data",metaKey:"meta",metaTotalKey:"total",metaFilteredKey:"filtered",optionsKey:"options",paramsKey:"params"},defaultSort:"",reorder:!1,dir:"ltr",perPageValues:[10,25,50,100,250],hidePerPage:!1,columns:[],actions:[],collapseActions:!1,selectable:!1,selectVisibleOnly:!0,singleSelect:!1,defaultPage:1,resizable:!1,autosize:!0,expand:!1,autoheight:!0,autohidePager:!1,responsive:!1,responsiveToggle:!0,filterOnEnter:!0,filterKeypressDelay:500,spinnerClass:"",saveState:!1,errorMessage:"",noData:""}}get isInit(){return this.classList.contains("dg-initialized")}get hasDataError(){return this.classList.contains("dg-network-error")}static registerPlugins(t){B=t}static unregisterPlugins(t=null){t===null?B={}:delete B[t]}static registeredPlugins(){return B}convertColumns(t){let e=[];if(typeof t=="object"&&!Array.isArray(t))for(let i of Object.keys(t)){let o=Object.assign({},this.defaultColumn);o.title=t[i],o.field=i,e.push(o)}else for(let i of t){let o=Object.assign({},this.defaultColumn);typeof i=="string"?(o.title=i,o.field=i):typeof i=="object"?(o=Object.assign(o,i),o.field||console.error("Invalid column definition",i),o.title||(o.title=o.field)):console.error("Column definition must be a string or an object"),e.push(o)}return e}static get observedAttributes(){return["page","data-filter","data-sort","data-debug","data-reorder","data-menu","data-selectable","data-single-select","data-url","data-per-page","data-responsive"]}get transformAttributes(){return{columns:t=>this.convertColumns(X(t)),actions:t=>X(t),defaultPage:t=>Number.parseInt(t),perPage:t=>Number.parseInt(t)}}get thead(){return I("thead",this)}get tbody(){return I("tbody",this)}get tfoot(){return I("tfoot",this)}get page(){return Number.parseInt(this.getAttribute("page"))}set page(t){c(this,"page",this.constrainPageValue(t))}urlChanged(t=!1){return t&&!this.isInit?this:(this.reconfig(),this.loadData().then(()=>this.configureUi()))}reconfig(){let t=this.options.columns;return this.options.columns=[],this.configureUi(),this.options.columns=t,this}constrainPageValue(t){let e=t;return this.pages1&&this.page*this.options.perPage>this.totalRecords();)t--;t!==this.page?this.page=t:this.reload(()=>{(!this.plugins.FixedHeight||!this.plugins.FixedHeight.hasFixedHeight)&&this.selectPerPage.scrollIntoView()})}dirChanged(){c(this,"dir",this.options.dir)}defaultSortChanged(){this.sortChanged()}perPageValuesChanged(){if(this.selectPerPage){for(;this.selectPerPage.lastChild;)this.selectPerPage.removeChild(this.selectPerPage.lastChild);for(let t of this.options.perPageValues)Z(this.selectPerPage,t,t,t===this.options.perPage)}}async _connected(){this.table=this.querySelector("table"),this.btnFirst=this.querySelector(".dg-btn-first"),this.btnPrev=this.querySelector(".dg-btn-prev"),this.btnNext=this.querySelector(".dg-btn-next"),this.btnLast=this.querySelector(".dg-btn-last"),this.selectPerPage=this.querySelector(".dg-select-per-page"),this.inputPage=this.querySelector(".dg-input-page"),this.getFirst=this.getFirst.bind(this),this.getPrev=this.getPrev.bind(this),this.getNext=this.getNext.bind(this),this.getLast=this.getLast.bind(this),this.changePerPage=this.changePerPage.bind(this),this.gotoPage=this.gotoPage.bind(this),this.btnFirst.addEventListener("click",this.getFirst),this.btnPrev.addEventListener("click",this.getPrev),this.btnNext.addEventListener("click",this.getNext),this.btnLast.addEventListener("click",this.getLast),this.selectPerPage.addEventListener("change",this.changePerPage),this.selectPerPage.toggleAttribute("hidden",this.options.hidePerPage),this.inputPage.addEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))await t.connected();this.dirChanged(),this.perPageValuesChanged(),await this.init()}_disconnected(){this.btnFirst?.removeEventListener("click",this.getFirst),this.btnPrev?.removeEventListener("click",this.getPrev),this.btnNext?.removeEventListener("click",this.getNext),this.btnLast?.removeEventListener("click",this.getLast),this.selectPerPage?.removeEventListener("change",this.changePerPage),this.inputPage?.removeEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))t.disconnected()}init(){return this.loadData().finally(()=>{this.configureUi(),this.sortChanged(),this.classList.add("dg-initialized"),this.filterChanged(),this.reorderChanged(),this.dirChanged(),this.perPageValuesChanged(),this.pageChanged(),this.fireEvents=!0,this.log("initialized")})}getCol(t){let e=null;for(let i of this.options.columns)i.field===t&&(e=i);return e}getColProp(t,e){let i=this.getCol(t);return i?i[e]:null}setColProp(t,e,i){let o=this.getCol(t);o&&(o[e]=i)}visibleColumns(){return this.options.columns.filter(t=>!t.hidden)}hiddenColumns(){return this.options.columns.filter(t=>t.hidden===!0)}showColumn(t,e=!0){this.setColProp(t,"hidden",!1),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"visible"})}hideColumn(t,e=!0){this.setColProp(t,"hidden",!0),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"hidden"})}startColIndex(){let t=1;return this.options.selectable&&this.plugins.SelectableRows&&t++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&t++,t}isSticky(){return this.hasAttribute("sticky")}columnsLength(t=!1){let e=0;for(let i of this.options.columns)t&&i.hidden||i.attr||e++;return this.options.selectable&&this.plugins.SelectableRows&&e++,this.options.actions.length&&this.plugins.RowActions&&e++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&e++,e}configureUi(){if(!this.table)return this;if(this.table.style.visibility="hidden",this.renderTable(),this.options.responsive&&this.plugins.ResponsiveGrid||(this.table.style.visibility="visible"),!this.rowHeight){let t=N(this,"tbody tr")||N(this,"table tr");t&&(this.rowHeight=t.offsetHeight)}return this.#t(this.tbody),this.fixPage()}filterChanged(){let t=this.querySelector("thead tr.dg-head-filters");this.options.filter?k(t,"hidden"):(this.clearFilters(),c(t,"hidden",""))}reorderChanged(){let t=g(this,"thead tr.dg-head-columns th");for(let e of t)e.classList.contains("dg-selectable")||e.classList.contains("dg-actions")||(this.options.reorder&&this.plugins.DraggableHeaders?e.draggable=!0:e.removeAttribute("draggable"))}sortChanged(){this.log("toggle sort");let t=g(this,"thead tr.dg-head-columns th");for(let e of t){let i=e.getAttribute("field");if(e.classList.contains("dg-not-sortable")||!this.fireEvents&&i===this.options.defaultSort)return;this.options.sort&&!this.getColProp(i,"noSort")?c(e,"aria-sort","none"):k(e,"aria-sort")}}selectableChanged(){this.renderTable()}addRow(t){Array.isArray(this.originalData)&&(this.log("add row"),this.originalData.push(t),this.data=this.originalData.slice(),this.sortData())}removeRow(t=null,e=null){if(!Array.isArray(this.originalData))return;let i=t,o=e;o===null&&(o=this.options.columns[0].field),i===null&&(i=this.originalData[this.originalData.length-1][o]),this.log(`remove row ${o}:${i}`);for(let n=0;n{this.hasDataError||(this.options.server||e?this.renderBody():this.paginate(),typeof t=="function"&&t())}).then(()=>this)}loadData(){let t=()=>!this.data.length&&this.classList.add("dg-empty"),e=this.tbody;return(this.meta||this.originalData||this.isInit)&&(!this.options.server||this.options.server&&!this.fireEvents)?(this.log("skip loadData"),t(),new Promise(i=>{i()})):(this.log("loadData"),this.loading=!0,this.classList.add("dg-loading"),this.classList.remove("dg-empty","dg-network-error"),this.fetchData().then(i=>{if(Array.isArray(i))this.data=i;else{if(!i[this.options.serverParams.dataKey]){console.error("Invalid response, it should contain a data key with an array or be a plain array",i),this.options.url=null;return}this.options=Object.assign(this.options,i[this.options.serverParams.optionsKey]??{}),this.meta=i[this.options.serverParams.metaKey]??{},this.data=i[this.options.serverParams.dataKey]}this.originalData=this.data.slice(),this.fixPage(),this.options.columns.length===0&&this.originalData.length?this.options.columns=this.convertColumns(Object.keys(this.originalData[0])):this.options.columns=this.convertColumns(this.options.columns)}).catch(i=>{this.log(i),e.setAttribute("data-empty",this.options.errorMessage||i.message?.replace(/^\s+|\r\n|\n|\r$/g,"")||C.networkError),this.classList.add("dg-empty","dg-network-error"),y(this,"loadDataFailed",i)}).finally(()=>{t(),this.#t(e),this.classList.remove("dg-loading"),c(this.table,"aria-rowcount",this.data.length),this.loading=!1}))}getFirst(){this.loading||(this.page=1)}getLast(){this.loading||(this.page=this.pages)}getPrev(){this.loading||(this.page=this.page-1)}getNext(){this.loading||(this.page=this.page+1)}gotoPage(t){if(t.type==="keypress"){let e=t.keyCode||t.key;if(e===13||e==="Enter")t.preventDefault();else return}this.page=Number.parseInt(this.inputPage.value)}getSort(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t?t.getAttribute("field"):this.options.defaultSort}getSortDir(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t&&t.getAttribute("aria-sort")||""}getFilters(){let t=[],e=g(this,this._filterSelector);for(let i of e)t[i.dataset.name]=i.value;return t}clearFilters(){let t=g(this,this._filterSelector);for(let e of t)e.value="";this.filterData()}filterData(){if(this.log("filter data"),this.page=1,this.options.server)this.reload();else{this.data=this.originalData?.slice()??[];let t=g(this,this._filterSelector);for(let i of t){let o=i.value;if(o){let n=i.dataset.name;this.data=this.data.filter(s=>`${s[n]}`.toLowerCase().indexOf(o.toLowerCase())!==-1)}}this.pageChanged();let e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");this.options.sort&&e?this.sortData():this.renderBody()}}sortData(t=null){this.log("sort data");let e=t;if(e&&this.getColProp(e.getAttribute("field"),"noSort")){this.log("sorting prevented because column is not sortable");return}if(this.plugins.ColumnResizer?.isResizing){this.log("sorting prevented because resizing");return}if(this.loading){this.log("sorting prevented because loading");return}if(e!==null){let i=n=>["dg-selectable","dg-actions","dg-responsive-toggle"].includes(n),o=g(this,"thead tr:first-child th");for(let n of o)[...n.classList].some(i)||!n.hasAttribute("aria-sort")||n!==e&&n.setAttribute("aria-sort","none");!e.hasAttribute("aria-sort")||e.getAttribute("aria-sort")==="none"?e.setAttribute("aria-sort","ascending"):e.getAttribute("aria-sort")==="ascending"?e.setAttribute("aria-sort","descending"):e.getAttribute("aria-sort")==="descending"&&e.setAttribute("aria-sort","none")}else e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");if(this.options.server)this.loadData().finally(()=>{this.renderBody()});else{let i=e?e.getAttribute("aria-sort"):"none";if(i==="none"){let o=[];this.originalData?.some(n=>(this.data.some(s=>JSON.stringify(n)===JSON.stringify(s)?(o.push(s),!0):!1),o.length===this.data.length)),this.data=o}else{let o=e.getAttribute("field");this.data.sort((n,s)=>{if(!isNaN(n[o])&&!isNaN(s[o]))return i==="ascending"?n[o]-s[o]:s[o]-n[o];let a=i==="ascending"?n[o].toUpperCase():s[o].toUpperCase(),l=i==="ascending"?s[o].toUpperCase():n[o].toUpperCase();switch(!0){case a>l:return 1;case athis._sort(t,"ascending");sortDesc=t=>this._sort(t,"descending");sortNone=t=>this._sort(t,"none");fetchData(){if(!this.options.url)return new Promise((o,n)=>n("No url set"));let t=window.location.href;t.split("/").pop().includes(".")||(t+=t.endsWith("/")?"":"/");let e=new URL(this.options.url,t),i={r:Date.now()};return this.options.server&&(i[this.options.serverParams.start]=this.page-1,i[this.options.serverParams.length]=this.options.perPage,this.options.filter&&(i[this.options.serverParams.search]=this.getFilters()),i[this.options.serverParams.sort]=this.getSort()||"",i[this.options.serverParams.sortDir]=this.getSortDir(),this.meta?.[this.options.serverParams.paramsKey]&&(i=Object.assign(i,this.meta[this.options.serverParams.paramsKey]))),Q(e,i),fetch(e).then(o=>{let n=new Error(o.statusText||C.networkError);if(!o.ok)throw n.response=o,n;return o.clone().json().catch(s=>{let a=s;throw this.options.debug||(a=n),a.response=o,a})})}renderTable(){this.log("render table"),this.options.menu&&this.plugins.ContextMenu&&this.plugins.ContextMenu.createMenu();let t;this.renderHeader(),this.options.defaultSort&&(t=this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`)),t?this.sortData(t):this.renderBody(),this.renderFooter()}renderHeader(){this.log("render header");let t=this.thead;this.createColumnHeaders(t),this.createColumnFilters(t),this.options.resizable&&this.plugins.ColumnResizer&&this.plugins.ColumnResizer.renderResizer(C.resizeColumn),y(this,"headerRendered")}renderFooter(){this.log("render footer");let t=this.tfoot;if(!t)return;let e=t.querySelector("td");t.removeAttribute("hidden"),c(e,"colspan",this.columnsLength(!0)),t.style.display=""}createColumnHeaders(t){let e=this.clientWidth,i=Math.round(e/this.columnsLength(!0)*2),o=0,n;n=x("tr"),this.headerRow=n,n.setAttribute("role","row"),n.setAttribute("aria-rowindex","1"),n.setAttribute("class","dg-head-columns");let s=t?.querySelector("tr.dg-head-columns th");this.log("createColumnHeaders - sampleTh",s),s||(s=x("th"),t?.querySelector("tr").appendChild(s)),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createHeaderCol(n),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createHeaderCol(n),o=0;let a=0;this.log("createColumnHeaders - columns",this.options.columns);for(let d of this.options.columns){if(d.attr)continue;let h=o+this.startColIndex(),u=x("th");u.setAttribute("scope","col"),u.setAttribute("role","columnheader button"),u.setAttribute("aria-colindex",`${h}`),u.setAttribute("id",q("dg-col-")),this.options.sort&&u.setAttribute("aria-sort","none"),u.setAttribute("field",d.field),this.plugins.ResponsiveGrid&&this.options.responsive&&c(u,"data-responsive",d.responsive||"");let p=_(d.title,s,!0)+20;u.dataset.minWidth=`${p}`,wt(u,d),u.tabIndex=0,u.textContent=d.title;let f=0;if(this.options.autosize&&this.plugins.AutosizeColumn){let b=Math.min(e-a,i);f=this.plugins.AutosizeColumn.computeSize(u,d,Number.parseInt(u.dataset.minWidth),b)}else f=Math.max(Number.parseInt(u.dataset.minWidth),Number.parseInt(u.getAttribute("width")));c(u,"width",f),d.hidden?u.setAttribute("hidden",""):a+=f,this.options.reorder&&this.plugins.DraggableHeaders&&this.plugins.DraggableHeaders.makeHeaderDraggable(u),n.appendChild(u),o++}if(ae){this.log(`adjust width to fix size, ${t.offsetWidth} > ${e}`);let d=this.offsetWidth-this.clientWidth,h=t.offsetWidth-e-d;this.options.responsive&&this.plugins.ResponsiveGrid&&(h+=d);let u=g(n,"th[width]");for(let p of u){if(T(p,"dg-not-resizable")||h<=0)continue;let f=Number.parseInt(p.getAttribute("width")),b=p.dataset.minWidth?Number.parseInt(p.dataset.minWidth):0;if(f>b){let A=f-h;Athis.sortData(d));this.table&&c(this.table,"aria-colcount",this.columnsLength(!0))}createColumnFilters(t){let e=0,i;i=x("tr"),this.filterRow=i,i.setAttribute("role","row"),i.setAttribute("aria-rowindex","2"),i.setAttribute("class","dg-head-filters"),this.options.filter||i.setAttribute("hidden",""),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createFilterCol(i),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createFilterCol(i),this.log("createColumnFilters - columns",this.options.columns);for(let n of this.options.columns){if(n.attr)continue;let s=e+this.startColIndex(),a=t?.querySelector(`tr.dg-head-columns th[aria-colindex="${s}"]`);if(!a){console.warn("Related th not found",s);continue}let l=x("th");l.setAttribute("aria-colindex",`${s}`);let d=this.createFilterElement(n,a);this.options.filter?d.tabIndex=0:l.tabIndex=0,n.hidden&&l.setAttribute("hidden",""),l.appendChild(d),i.appendChild(l),e++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionFilter(i),t?.replaceChild(i,t.querySelector("tr.dg-head-filters")),(typeof this.options.filterKeypressDelay!="number"||this.options.filterOnEnter)&&(this.options.filterKeypressDelay=0);let o=g(i,this._filterSelector);for(let n of o){let s=/select/i.test(n.tagName),a=s?"change":"keyup",l=G(d=>{let h=d.keyCode||d.key,u=!this.options.filterOnEnter&&!this._excludedKeys.some(p=>p===h);(h===13||h==="Enter"||u||d.type==="change"||d.type==="paste")&&this.filterData.call(this)},this.options.filterKeypressDelay);n.addEventListener(a,l),s||n.addEventListener("paste",l)}}createFilterElement(t,e){let i=t.filterType==="select",o=i?x("select"):x("input");if(i){if(!Array.isArray(t.filterList)){let n=[...new Set((this.data??[]).map(s=>s[t.field]))].filter(s=>s).sort();t.filterList=[t.firstFilterOption||this.defaultColumn.firstFilterOption].concat(n.map(s=>({value:s,text:s})))}for(let n of t.filterList){let s=x("option");s.value=n.value,s.text=n.text,o instanceof HTMLSelectElement&&o.add(s)}}else o.type="text",o.inputMode="search",o.autocomplete="off",o.spellcheck=!1;return o.dataset.name=t.field,o.id=q("dg-filter-"),o.setAttribute("aria-labelledby",e.getAttribute("id")),o}renderBody(){this.log("render body");let t,e,i,o=x("tbody");this.data.forEach((s,a)=>{t=x("tr"),c(t,"role","row"),c(t,"hidden",""),c(t,"aria-rowindex",a+1),t.tabIndex=0,this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createDataCol(t),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createDataCol(t),this.options.expand&&(t.classList.add("dg-expandable"),S(t,"click",l=>{l.target.matches(this._excludedRowElementSelector)||(this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.blockObserver(),yt(l.currentTarget,"dg-expanded"),this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.unblockObserver())})),i=0;for(let l of this.options.columns){if(l||console.error("Empty column found!",this.options.columns),l.attr){s[l.field]&&(l.attr==="class"?E(t,s[l.field]):t.setAttribute(l.attr,s[l.field]));return}if(e=x("td"),e.setAttribute("role","gridcell"),e.setAttribute("aria-colindex",`${i}${this.startColIndex()}`),wt(e,l),e.setAttribute("data-name",l.title),e.tabIndex=-1,l.editable&&this.plugins.EditableColumn)E(e,"dg-editable-col"),this.plugins.EditableColumn.makeEditableInput(e,l,s,a);else{let d=s[l.field]??"",h;switch(l.transform){case"uppercase":h=d.toUpperCase();break;case"lowercase":h=d.toLowerCase();break;default:h=d;break}if(l.format){if(l.defaultFormatValue!==void 0&&(h===""||h===null)&&(h=`${l.defaultFormatValue}`),typeof l.format=="string"&&h)e.innerHTML=M(l.format,Object.assign({_v:d,_tv:h},s));else if(l.format instanceof Function){let u=l.format.call(this,{column:l,rowData:s,cellData:h,td:e,tr:t});e.innerHTML=u||h||d}}else e.textContent=h}t.appendChild(e),i++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionRow(t,s),o.appendChild(t),y(this,"rowRendered",{rowData:s,tr:t})}),o.setAttribute("role","rowgroup");let n=this.tbody;n&&o.setAttribute("data-empty",n.getAttribute("data-empty")),this.table?.replaceChild(o,n),this.plugins.FixedHeight&&this.plugins.FixedHeight.createFakeRow(),this.paginate(),this.plugins.SelectableRows&&this.plugins.SelectableRows.shouldSelectAll(o),this.classList.toggle("dg-empty",!this.data.length),y(this,"bodyRendered")}paginate(){this.log("paginate");let t=this.totalRecords(),e=this.page||1,i=this.tbody,o=this.tfoot;if(!i||!o)return;let n=g(i,"tr");this.pages=this.totalPages();let s,a=e*this.options.perPage,l=a-this.options.perPage+1;a>t&&(a=t),t||(l=0);for(let d of n){if(this.options.server){k(d,"hidden");continue}s=Number(D(d,"aria-rowindex")),s>a||s=this.pages,this.btnLast.disabled=this.page>=this.pages),o.querySelector(".dg-low").textContent=l.toString(),o.querySelector(".dg-high").textContent=a.toString(),o.querySelector(".dg-total").textContent=`${this.totalRecords()}`,o.toggleAttribute("hidden",this.options.autohidePager&&this.options.perPage>this.totalRecords())}totalPages(){return Math.ceil(this.totalRecords()/this.options.perPage)}totalRecords(){return this.options.server?this.meta?.[this.options.serverParams.metaFilteredKey]||0:this.data.length}},j=it;var st=class{constructor(t){this.grid=t}connected(){}disconnected(){}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}},m=st;var ot=class extends m{constructor(t){super(t),this.isResizing=!1}renderResizer(t){let e=this.grid,i=e.table,o=g(e,"thead tr.dg-head-columns th");for(let n of o){if(T(n,"dg-not-resizable"))continue;let s=document.createElement("div");E(s,"dg-resizer"),s.ariaLabel=t,n.appendChild(s);let a=0,l=0,d=0,h=0,u=f=>{if(f.clientX>h)return;let b=l+(f.clientX-a);n.dataset.minWidth&&b>Number.parseInt(n.dataset.minWidth)&&c(n,"width",b)},p=()=>{e.log("resized column"),setTimeout(()=>{this.isResizing=!1},0),W(s,"dg-resizer-active"),e.options.reorder&&(n.draggable=!0),n.style.overflow="hidden",O(document,"mousemove",u),O(document,"mouseup",p),y(e,"columnResized",{col:D(n,"field"),width:D(n,"width")})};S(s,"click",f=>{f.stopPropagation()}),S(s,"mousedown",f=>{f.stopPropagation(),this.isResizing=!0;let b=f.target,P=g(e,"dg-head-columns th").filter(v=>!v.hasAttribute("hidden")),w=P.findIndex(v=>v===b.parentNode);e.log("resize column"),E(s,"dg-resizer-active"),k(n,"draggable"),n.style.overflow="visible",s.style.height=`${i.offsetHeight-1}px`,a=f.clientX,l=n.offsetWidth,d=(P.length-w)*30,h=tt(b).left+e.offsetWidth-d,c(n,"width",l);for(let v=0;vw&&k(o[v],"width");S(document,"mousemove",u),S(document,"mouseup",p)})}}},Pt=ot;function K(r,t,e="nodeName"){let i=r;for(;i[e]!==t;)i=i.parentElement;return i}var nt=class extends m{connected(){this.menu=this.grid.querySelector(".dg-menu")}disconnected(){this.grid.headerRow&&O(this.grid.headerRow,"contextmenu",this)}attachContextMenu(){let t=this.grid;S(t.headerRow,"contextmenu",this)}onchange(t){let e=this.grid,i=t.target,o=i.dataset.name;if(i.checked)e.showColumn(o);else{if(e.visibleColumns().length<=1){i.checked=!0;return}e.hideColumn(o)}e.fixPage()}oncontextmenu(t){t.preventDefault();let e=K(t.target,"THEAD"),i=this.menu,o=e.getBoundingClientRect(),n=t.clientX-o.left,s=t.clientY-o.top;i.style.top=`${s}px`,i.style.left=`${n}px`,k(i,"hidden"),n+150>o.width&&(n-=i.offsetWidth,i.style.left=`${n}px`);let a=l=>{i.contains(l.target)||(c(i,"hidden",""),O(document,"click",a))};S(document,"click",a)}createMenu(){let t=this.grid,e=this.menu;for(;e.lastChild;)e.removeChild(e.lastChild);e.addEventListener("change",this);for(let i of t.options.columns){if(i.attr)continue;let o=document.createElement("li"),n=document.createElement("label"),s=document.createElement("input");c(s,"type","checkbox"),c(s,"data-name",i.field),i.hidden||(s.checked=!0);let a=document.createTextNode(i.title);n.appendChild(s),n.appendChild(a),o.appendChild(n),e.appendChild(o)}}},St=nt;var rt=class extends m{makeHeaderDraggable(t){let e=this.grid;t.draggable=!0,S(t,"dragstart",i=>{if(e.plugins.ColumnResizer?.isResizing&&i.preventDefault){i.preventDefault();return}e.log("reorder col"),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",i.target.getAttribute("aria-colindex"))}),S(t,"dragover",i=>(i.preventDefault&&i.preventDefault(),i.dataTransfer.dropEffect="move",!1)),S(t,"drop",i=>{i.stopPropagation&&i.stopPropagation();let o=i.target,n=K(o,"TH"),s=Number.parseInt(i.dataTransfer.getData("text/plain")),a=Number.parseInt(n.getAttribute("aria-colindex"));if(s===a){e.log("reordered col stayed the same");return}e.log(`reordered col from ${s} to ${a}`);let l=e.startColIndex(),d=e.options.columns[s-l];e.options.columns[s-l]=e.options.columns[a-l],e.options.columns[a-l]=d;let h=(u,p)=>{let f=p.parentNode.getAttribute("aria-rowindex"),b=e.querySelector(`${u} tr[aria-rowindex="${f}"] [aria-colindex="${a}"]`);c(p,"aria-colindex",a),c(b,"aria-colindex",s);let A=document.createElement("th");p.parentNode.insertBefore(A,p),b.parentNode.replaceChild(p,b),A.parentNode.replaceChild(b,A)};for(let u of g(e,`thead th[aria-colindex="${s}"]`))h("thead",u);for(let u of g(e,`tbody td[aria-colindex="${s}"]`))h("tbody",u);return e.options.columns=g(e,"thead tr.dg-head-columns th[field]").map(u=>e.options.columns.find(p=>p.field===D(u,"field"))),y(e,"columnReordered",{col:d.field,from:s,to:a}),!1})}},At=rt;var at=class extends m{constructor(t){super(t),this.touch=null}connected(){let t=this.grid;t.addEventListener("touchstart",this,{passive:!0}),t.addEventListener("touchmove",this,{passive:!0})}disconnected(){let t=this.grid;t.removeEventListener("touchstart",this),t.removeEventListener("touchmove",this)}ontouchstart(t){this.touch=t.touches[0]}ontouchmove(t){if(!this.touch)return;let e=this.grid,i=this.touch.clientX-t.touches[0].clientX,o=this.touch.clientY-t.touches[0].clientY;Math.abs(i)>Math.abs(o)&&(i>0?e.getNext():e.getPrev()),this.touch=null}},Lt=at;var H="dg-selectable",lt="dg-select-all",kt="form-check-input",dt=class extends m{#t=`tbody tr${this.visibleOnly?":not([hidden])":""} .${H} input[type=checkbox]`;#e=`tbody .${H} input`;disconnected(){this.selectAll&&this.selectAll.removeEventListener("change",this)}get isSingleSelect(){return this.grid.options.singleSelect}get visibleOnly(){return this.grid.options.selectVisibleOnly}getSelection(...t){let e=this.grid,i=[],o=g(e,`${this.#e}:checked`);for(let n of o){let s=Number.parseInt(n.dataset.id),a=e.data[s-1];if(!a){console.warn(`Item ${s} not found`);continue}t.length===0?i.push(a):t.length===1?i.push(a[t[0]]):i.push(Object.fromEntries(t.map(l=>[l,a[l]])))}return this.isSingleSelect?i[0]??{}:i}clearCheckboxes(t){if(!this.grid.options.selectVisibleOnly)return;let i=g(t,`tr[hidden] .${H} input`);for(let o of i)o.checked=!1,this.isSingleSelect&&(o.dataset.toggled="false");this.selectAll.checked=!1}colIndex(){return this.grid.startColIndex()-2}createHeaderCol(t){let e=document.createElement("th");c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0,this.selectAll=document.createElement("input"),this.selectAll.type="checkbox",this.selectAll.classList.add(lt),this.selectAll.classList.add(kt),this.selectAll.addEventListener("change",this);let i=document.createElement("label");i.hidden=this.isSingleSelect,i.appendChild(this.selectAll),e.appendChild(i),e.setAttribute("width","40"),t.appendChild(e)}createFilterCol(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H),e.tabIndex=0,t.appendChild(e)}shouldSelectAll(t){this.selectAll&&(t.addEventListener("change",this),t.dispatchEvent(new Event("change")))}createDataCol(t){let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H);let i=document.createElement("input");i.dataset.id=t.getAttribute("aria-rowindex"),i.type=this.isSingleSelect?"radio":"checkbox",i.classList.add(kt),this.isSingleSelect&&(i.name="dg-row-select",i.dataset.toggled="false");let o=document.createElement("label");o.classList.add("dg-clickable-cell"),o.appendChild(i),e.appendChild(o),o.addEventListener("click",this),t.appendChild(e)}onclick(t){if(!this.isSingleSelect)return t.stopPropagation();let e=t.target,i=e.dataset.toggled!=="true";i&&Y(`${this.#t.replace("checkbox","radio")}`,this.grid)?.forEach(o=>{o.name===e.name&&o!==e&&(o.checked=o.dataset.toggled=!1)}),e.checked=e.dataset.toggled=i,!i&&this.onchange(t)}onchange(t){let e=t.target,i=this.grid;if(T(t.target,lt))g(i,this.#e).forEach(o=>{(!this.visibleOnly||o.offsetWidth)&&(o.checked=this.selectAll.checked)});else if(e.matches(this.#t)){if(!e.closest(`.${H}`))return;let o=g(i,this.#t);this.selectAll.checked=o.every(n=>n.checked)}e.matches(`.${lt},${this.#e}`)&&y(e,"rowsSelected",{selection:i.getSelection()},!0)}},Et=dt;var ct=class extends m{constructor(t){super(t),this.hasFixedHeight=!1,t.style.height&&(t.style.overflowY="auto",this.hasFixedHeight=!0)}createFakeRow(){let e=this.grid.querySelector("tbody"),i=document.createElement("tr");c(i,"role","row"),c(i,"hidden",""),i.classList.add("dg-fake-row"),i.tabIndex=0,e?.appendChild(i)}get fakeRow(){return this.grid.querySelector(".dg-fake-row")}updateFakeRow(){let t=this.grid,e=this.fakeRow;if(!e||t.options.perPage>t.totalRecords()||t.page!==t.totalPages()||!t.options.autoheight)return;let i=t.options.perPage*t.rowHeight,o=t.querySelectorAll("tbody tr:not([hidden])").length,n=o>1?i-o*t.rowHeight:i;n>0?(c(e,"height",n),e.removeAttribute("hidden")):e.removeAttribute("height")}},Dt=ct;var ht=class extends m{computeSize(t,e,i,o){let n=this.grid;if(U(t,"width"))return D(t,"width");if(!n.data.length)return;let s=n.data[0],a=n.data[n.data.length-1],l=s[e.field]?s[e.field].toString():"",d=a[e.field]?a[e.field].toString():"";d.length>l.length&&(l=d);let h=0;return l.length<=6?h=i:l.length>50?h=o:h=_(`${l}0000`,t),h>o&&(h=o),h{let i=Number.parseInt(t.dataset.responsive)||1;return(Number.parseInt(e.dataset.responsive)||1)-i})}var Wt=G(r=>{for(let t of r){let e=t.target,i=e.table;if(e.plugins.ResponsiveGrid.observerBlocked)return;let o=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize,n=Number.parseInt(o.inlineSize),s=i.offsetWidth,a=g(e.headerRow,"th").reduce((P,w)=>P+w.offsetWidth,0),l=(a||s)-n-1,d=50,h=e.plugins.ResponsiveGrid.prevAction,u=Ft(g(e.headerRow,"th[field]").reverse().filter(P=>P.dataset.responsive!=="0")),p=!1;if(e.log(`table is ${s}/${a} and available size is ${n}. Diff: ${l}`),l>0){if(h==="show")return;e.plugins.ResponsiveGrid.prevAction="hide";let P=l,w=u.filter(v=>!v.hasAttribute("hidden")&&v.hasAttribute("data-responsive"));if(w.length===0&&(w=u.filter(v=>!v.hasAttribute("hidden")),w.length===1))return;for(let v of w){if(P<0)continue;let $=v.offsetWidth,R=v.getAttribute("field");R&&(v.dataset.baseWidth=`${v.offsetWidth}`,e.hideColumn(R,!1),e.setColProp(R,"responsiveHidden",!0),p=!0,P-=$,P=Math.round(P))}}else{if(h==="hide")return;e.plugins.ResponsiveGrid.prevAction="show";let P=u.filter($=>!$.hasAttribute("hidden")).reduce(($,R)=>{let z=R.dataset.minWidth?Number.parseInt(R.dataset.minWidth):R.offsetWidth;return $+z},0)+d,w=n-P,v=u.slice().reverse().filter($=>$.hasAttribute("hidden"));for(let $ of v){if(ww){w=-1;continue}let z=$.getAttribute("field");z&&(e.showColumn(z,!1),e.setColProp(z,"responsiveHidden",!1),p=!0,w-=R,w=Math.round(w))}}let f=N(e.table,"tfoot"),b=g(e.table,".dg-footer > div").reduce((P,w)=>P+w.offsetWidth,0),A=f.offsetWidth-b;b>n?E(f,"dg-footer-compact"):A>250&&W(f,"dg-footer-compact"),p&&e.renderTable(),setTimeout(()=>{e.plugins.ResponsiveGrid.prevAction=null},1e3),e.table.style.visibility="visible"}},100),Rt=new ResizeObserver(Wt),gt=class extends m{constructor(t){super(t),this.observerBlocked=!1,this.prevAction=null}connected(){this.grid.options.responsive&&this.observe()}disconnected(){this.unobserve()}observe(){this.grid.options.responsive&&(Rt.observe(this.grid),this.grid.style.display="block",this.grid.style.overflowX="hidden")}unobserve(){Rt.unobserve(this.grid),this.grid.style.display="unset",this.grid.style.overflowX="unset"}blockObserver(){this.observerBlocked=!0,ut&&clearTimeout(ut)}unblockObserver(){ut=setTimeout(()=>{this.observerBlocked=!1},200)}hasHiddenColumns(){let t=!1;for(let e of this.grid.options.columns)e.responsiveHidden&&(t=!0);return t}colIndex(){return this.grid.startColIndex()-1}createHeaderCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),c(e,"width","40"),e.classList.add(`${L}-toggle`,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0}createFilterCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.tabIndex=0}createDataCol(t){if(!this.grid.options.responsiveToggle)return;let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.innerHTML=`
`,t.appendChild(e),e.addEventListener("click",this),e.addEventListener("mousedown",this)}computeLabelWidth(){let t=0,e=0;for(;t<120;){e++;let i=N(this.grid,`.dg-head-columns th[aria-colindex="${e}"]`);if(i)t+=i.offsetWidth;else break}return t}onmousedown(t){t.preventDefault()}onclick(t){t.stopPropagation();let e=t.currentTarget,i=e.parentElement,o=N(e,`.${L}-open`),n=N(e,`.${L}-close`);if(this.blockObserver(),T(i,`${L}-expanded`)){W(i,`${L}-expanded`),o.style.display="unset",n.style.display="none";let a=i.nextElementSibling,l=g(a,`.${L}-hidden`);for(let d of l)i.appendChild(d),c(d,"hidden");a.parentElement.removeChild(a)}else{E(i,`${L}-expanded`),o.style.display="none",n.style.display="unset";let a=x("tr");xt(a,i),E(a,`${L}-child-row`);let l=x("td",a);c(l,"colspan",this.grid.columnsLength(!0));let d=x("table",l);E(d,`${L}-table`);let u=g(i,`.${L}-hidden`),h=this.computeLabelWidth();for(let p of u){let f=x("tr",d),b=p.dataset.name,S=x("th",f);S.style.width=`${h}px`,S.innerHTML=b,f.appendChild(p),k(p,"hidden")}}this.unblockObserver()}},It=gt;var pt=class extends m{hasActions(){return this.grid.options.actions.length>0}makeActionHeader(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions","dg-not-sortable","dg-not-resizable",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionFilter(t){let e=document.createElement("th");e.setAttribute("role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionRow(t,e){let i=this.grid.labels,o=document.createElement("td");c(o,"role","gridcell"),c(o,"aria-colindex",this.grid.columnsLength(!0)),o.classList.add("dg-actions",this.actionClass),o.tabIndex=0;let n=document.createElement("button");n.classList.add("dg-actions-toggle"),n.innerHTML="\u2630",o.appendChild(n),A(n,"click",s=>{s.stopPropagation(),s.target.parentElement.classList.toggle("dg-actions-expand")});for(let s of this.grid.options.actions){let a=document.createElement("button");s.html?a.innerHTML=s.html:a.innerText=s.title??s.name,s.title&&(a.title=s.title),s.url&&(a.type="submit",a.formAction=M(s.url,e)),s.class&&a.classList.add(...s.class.split(" "));let l=d=>{if(d.stopPropagation(),s.confirm&&!confirm(i.areYouSure)){d.preventDefault();return}y(this.grid,"action",{data:e,action:s.name})};a.addEventListener("click",l),o.appendChild(a),s.default&&(t.classList.add("dg-actionable"),t.addEventListener("click",l))}t.appendChild(o)}get actionClass(){return this.grid.options.actions.length<3&&!this.grid.options.collapseActions?`dg-actions-${this.grid.options.actions.length}`:"dg-actions-more"}},Tt=pt;var ft=class extends m{makeEditableInput(t,e,i,o){let n=this.grid.getAttribute("id"),s=document.createElement("input");s.type=e.editableType||"text",s.type==="email"&&(s.inputMode="email"),s.type==="decimal"&&(s.type="text",s.inputMode="decimal"),s.autocomplete="off",s.spellcheck=!1,s.tabIndex=0,s.classList.add("dg-editable"),s.name=`${n.replace("-","_")}[${o+1}][${e.field}]`,s.value=i[e.field],s.dataset.field=e.field,s.addEventListener("click",a=>a.stopPropagation()),s.addEventListener("keypress",a=>{if(a.type==="keypress"){let l=a.keyCode||a.key;(l===13||l==="Enter")&&(s.blur(),a.preventDefault())}}),s.addEventListener("blur",()=>{s.value!==i[s.dataset.field]&&(i[s.dataset.field]=s.value,y(this.grid,"edit",{data:i,value:s.value}))}),t.appendChild(s)}},Nt=ft;var mt=class extends m{connected(){this.grid.options.spinnerClass&&this.grid.plugins.SpinnerSupport&&this.add()}add(){let t=this.grid,e=t.options.spinnerClass;if(!e)return;let i=e.split(" ").map(n=>`.${n}`).join(""),o=` +
`,t.appendChild(e),e.addEventListener("click",this),e.addEventListener("mousedown",this)}computeLabelWidth(){let t=0,e=0;for(;t<120;){e++;let i=N(this.grid,`.dg-head-columns th[aria-colindex="${e}"]`);if(i)t+=i.offsetWidth;else break}return t}onmousedown(t){t.preventDefault()}onclick(t){t.stopPropagation();let e=t.currentTarget,i=e.parentElement,o=N(e,`.${L}-open`),n=N(e,`.${L}-close`);if(this.blockObserver(),T(i,`${L}-expanded`)){W(i,`${L}-expanded`),o.style.display="unset",n.style.display="none";let a=i.nextElementSibling,l=g(a,`.${L}-hidden`);for(let d of l)i.appendChild(d),c(d,"hidden");a.parentElement.removeChild(a)}else{E(i,`${L}-expanded`),o.style.display="none",n.style.display="unset";let a=x("tr");xt(a,i),E(a,`${L}-child-row`);let l=x("td",a);c(l,"colspan",this.grid.columnsLength(!0));let d=x("table",l);E(d,`${L}-table`);let h=g(i,`.${L}-hidden`),u=this.computeLabelWidth();for(let p of h){let f=x("tr",d),b=p.dataset.name,A=x("th",f);A.style.width=`${u}px`,A.innerHTML=b,f.appendChild(p),k(p,"hidden")}}this.unblockObserver()}},It=gt;var pt=class extends m{hasActions(){return this.grid.options.actions.length>0}makeActionHeader(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions","dg-not-sortable","dg-not-resizable",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionFilter(t){let e=document.createElement("th");e.setAttribute("role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionRow(t,e){let i=this.grid.labels,o=document.createElement("td");c(o,"role","gridcell"),c(o,"aria-colindex",this.grid.columnsLength(!0)),o.classList.add("dg-actions",this.actionClass),o.tabIndex=0;let n=document.createElement("button");n.classList.add("dg-actions-toggle"),n.innerHTML="\u2630",o.appendChild(n),S(n,"click",s=>{s.stopPropagation(),s.target.parentElement.classList.toggle("dg-actions-expand")});for(let s of this.grid.options.actions){let a=document.createElement("button");s.html?a.innerHTML=s.html:a.innerText=s.title??s.name,s.title&&(a.title=s.title),s.url&&(a.type="submit",a.formAction=M(s.url,e)),s.class&&a.classList.add(...s.class.split(" "));let l=d=>{if(d.stopPropagation(),s.confirm&&!confirm(i.areYouSure)){d.preventDefault();return}y(this.grid,"action",{data:e,action:s.name})};a.addEventListener("click",l),o.appendChild(a),s.default&&(t.classList.add("dg-actionable"),t.addEventListener("click",l))}t.appendChild(o)}get actionClass(){return this.grid.options.actions.length<3&&!this.grid.options.collapseActions?`dg-actions-${this.grid.options.actions.length}`:"dg-actions-more"}},Tt=pt;var ft=class extends m{makeEditableInput(t,e,i,o){let n=this.grid.getAttribute("id"),s=document.createElement("input");s.type=e.editableType||"text",s.type==="email"&&(s.inputMode="email"),s.type==="decimal"&&(s.type="text",s.inputMode="decimal"),s.autocomplete="off",s.spellcheck=!1,s.tabIndex=0,s.classList.add("dg-editable"),s.name=`${n.replace("-","_")}[${o+1}][${e.field}]`,s.value=i[e.field],s.dataset.field=e.field,s.addEventListener("click",a=>a.stopPropagation()),s.addEventListener("keypress",a=>{if(a.type==="keypress"){let l=a.keyCode||a.key;(l===13||l==="Enter")&&(s.blur(),a.preventDefault())}}),s.addEventListener("blur",()=>{s.value!==i[s.dataset.field]&&(i[s.dataset.field]=s.value,y(this.grid,"edit",{data:i,value:s.value}))}),t.appendChild(s)}},Nt=ft;var mt=class extends m{connected(){this.grid.options.spinnerClass&&this.grid.plugins.SpinnerSupport&&this.add()}add(){let t=this.grid,e=t.options.spinnerClass;if(!e)return;let i=e.split(" ").map(n=>`.${n}`).join(""),o=` -`;if(!I("#dg-styles")){let n=I("head")??I("body"),s=/head/i.test(n.tagName)?"beforeend":"afterbegin";n.insertAdjacentHTML(s,o)}!I(`i${i}`,t)&&t.insertAdjacentHTML("afterbegin",``)}},Ht=mt;var bt=class extends m{constructor(t){super(t),this.cachedState=null,this.isFilterSortSet=!1,this.isDataLoaded=!1,this.isScrolled=!1,this.log("Init")}async connected(){this.log("connected");let t=this.grid;if(this.log(t.options),!t.options.saveState){this.log("disabled");return}this.log("enabled");let e=this._getState();if(e){let n=async()=>{if(!t.options.server)return;let a=500,l=Date.now(),d;for(;(d=!t.options.columns?.length)&&Date.now()-lrequestAnimationFrame(u));d&&this.log("Timeout waiting for columns.")};await(async()=>{await n(),this.log("hide columns");for(let a of e.columns)if(a.hidden){let l=t.options.columns.find(d=>d.field===a.field);l.hidden=!0}this.log("set: meta, pages"),t.options.perPage=e.perPage,t.options.server&&(t.meta=e.meta,t.pages=e.pages,t.page=e.page)})()}this.cachedState=e,this.log("cachedState",this.cachedState);let i=t.loadData;t.loadData=function(...n){return i.apply(this,n).finally(()=>{let s=this.plugins.SaveState;if(s.log("loadData",this.options.columns),!t.classList.contains("dg-initialized")){s.log("not init, loadData skipped");return}if(s.log("loadData finished, set param controls",this.options.columns),s.cachedState&&!s.isFilterSortSet){s.log("set sort and filters");let d=g(t,"thead tr.dg-head-columns th[aria-sort]");for(let h of d)h.setAttribute("aria-sort","none");t.querySelector(`thead tr.dg-head-columns th[field='${s.cachedState.sort}']`)?.setAttribute("aria-sort",s.cachedState.sortDir);let u=g(t.filterRow,"[id^=dg-filter]");s.log("filters",u);for(let h of u)h.value=s?.cachedState?.filters?.[h.dataset.name]??"",s.log({name:h.dataset.name,val:h.value,saveState:s});s.isFilterSortSet=!0}let a={meta:t.meta,pages:t.pages,page:t.page,perPage:t.options.perPage,filters:{},columns:t.options.columns.map(d=>({field:d.field,hidden:d.hidden})),sort:t.getSort(),sortDir:t.getSortDir(),scrollTo:window.scrollY},l=t.getFilters();s.log("filters",l);for(let d of Object.keys(l))a.filters[d]=l[d]??"",s.log({key:d,val:l[d],newState:a,filters:l});s.log("store new state",a),s._setState(a),!t.options.server&&s.cachedState&&!s.isDataLoaded&&(s.isDataLoaded=!0,t.filterData(),t.page=s.cachedState.page,t.pageChanged(),s.log("data loaded"))})};let o=()=>{let n=t.plugins.SaveState,s=n._getState();s&&(s.columns=t.options.columns.map(a=>({field:a.field,hidden:a.hidden})),s.sort=t.getSort(),s.sortDir=t.getSortDir(),s.scrollTo=window.scrollY,n._setState(s))};document.addEventListener("scrollend",o),t.addEventListener("headerRendered",o),t.addEventListener("bodyRendered",n=>{if(!t.classList.contains("dg-initialized")||t.classList.contains("dg-loading"))return;t.options.server||o();let s=t.plugins.SaveState;!s.cachedState||!s.isFilterSortSet||(s.isDataLoaded?s.isScrolled||(s.isScrolled=!0,window.scrollTo({top:s.cachedState.scrollTo,left:0,behavior:"instant"})):(s.isDataLoaded=!0,t.reload(),s.log("***grid reloaded")))})}log(...t){this.grid.log("[Save-State] ",...t)}_getState(){let t;try{t=JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`))}catch{}return t}_setState(t){sessionStorage.setItem(`gridSaveState_${this.grid.id}`,JSON.stringify(t))}},Ot=bt;j.registerPlugins({ColumnResizer:Pt,ContextMenu:At,DraggableHeaders:St,TouchSupport:Lt,SelectableRows:Et,FixedHeight:Dt,AutosizeColumn:$t,ResponsiveGrid:It,RowActions:Tt,EditableColumn:Nt,SpinnerSupport:Ht,SaveState:Ot});customElements.get("data-grid")||customElements.define("data-grid",j);var xi=j,Mt=typeof globalThis<"u"?globalThis:self;Mt.DataGrid=j;export{xi as default}; +`;if(!I("#dg-styles")){let n=I("head")??I("body"),s=/head/i.test(n.tagName)?"beforeend":"afterbegin";n.insertAdjacentHTML(s,o)}!I(`i${i}`,t)&&t.insertAdjacentHTML("afterbegin",``)}},Ht=mt;var bt=class extends m{constructor(t){super(t),this.cachedState=null,this.isFilterSortSet=!1,this.isDataLoaded=!1,this.isScrolled=!1,this.log("Init")}async connected(){this.log("connected");let t=this.grid;if(this.log(t.options),!t.options.saveState){this.log("disabled");return}this.log("enabled");let e=this._getState();if(e){let n=async()=>{if(!t.options.server)return;let a=500,l=Date.now(),d;for(;(d=!t.options.columns?.length)&&Date.now()-lrequestAnimationFrame(h));d&&this.log("Timeout waiting for columns.")};await(async()=>{await n(),this.log("hide columns");for(let a of e.columns)if(a.hidden){let l=t.options.columns.find(d=>d.field===a.field);l.hidden=!0}this.log("set: meta, pages"),t.options.perPage=e.perPage,t.options.server&&(t.meta=e.meta,t.pages=e.pages,t.page=e.page)})()}this.cachedState=e,this.log("cachedState",this.cachedState);let i=t.loadData;t.loadData=function(...n){return i.apply(this,n).finally(()=>{let s=this.plugins.SaveState;if(s.log("loadData",this.options.columns),!t.classList.contains("dg-initialized")){s.log("not init, loadData skipped");return}if(s.log("loadData finished, set param controls",this.options.columns),s.cachedState&&!s.isFilterSortSet){s.log("set sort and filters");let d=g(t,"thead tr.dg-head-columns th[aria-sort]");for(let u of d)u.setAttribute("aria-sort","none");t.querySelector(`thead tr.dg-head-columns th[field='${s.cachedState.sort}']`)?.setAttribute("aria-sort",s.cachedState.sortDir);let h=g(t.filterRow,"[id^=dg-filter]");s.log("filters",h);for(let u of h)u.value=s?.cachedState?.filters?.[u.dataset.name]??"",s.log({name:u.dataset.name,val:u.value,saveState:s});s.isFilterSortSet=!0}let a={meta:t.meta,pages:t.pages,page:t.page,perPage:t.options.perPage,filters:{},columns:t.options.columns.map(d=>({field:d.field,hidden:d.hidden})),sort:t.getSort(),sortDir:t.getSortDir(),scrollTo:window.scrollY},l=t.getFilters();s.log("filters",l);for(let d of Object.keys(l))a.filters[d]=l[d]??"",s.log({key:d,val:l[d],newState:a,filters:l});s.log("store new state",a),s._setState(a),!t.options.server&&s.cachedState&&!s.isDataLoaded&&(s.isDataLoaded=!0,t.filterData(),t.page=s.cachedState.page,t.pageChanged(),s.log("data loaded"))})};let o=()=>{let n=t.plugins.SaveState,s=n._getState();s&&(s.columns=t.options.columns.map(a=>({field:a.field,hidden:a.hidden})),s.sort=t.getSort(),s.sortDir=t.getSortDir(),s.scrollTo=window.scrollY,n._setState(s))};document.addEventListener("scrollend",o),t.addEventListener("headerRendered",o),t.addEventListener("bodyRendered",n=>{if(!t.classList.contains("dg-initialized")||t.classList.contains("dg-loading"))return;t.options.server||o();let s=t.plugins.SaveState;!s.cachedState||!s.isFilterSortSet||(s.isDataLoaded?s.isScrolled||(s.isScrolled=!0,window.scrollTo({top:s.cachedState.scrollTo,left:0,behavior:"instant"})):(s.isDataLoaded=!0,t.reload(),s.log("***grid reloaded")))})}log(...t){this.grid.log("[Save-State] ",...t)}_getState(){let t;try{t=JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`))}catch{}return t}_setState(t){sessionStorage.setItem(`gridSaveState_${this.grid.id}`,JSON.stringify(t))}},Ot=bt;j.registerPlugins({ColumnResizer:Pt,ContextMenu:St,DraggableHeaders:At,TouchSupport:Lt,SelectableRows:Et,FixedHeight:Dt,AutosizeColumn:$t,ResponsiveGrid:It,RowActions:Tt,EditableColumn:Nt,SpinnerSupport:Ht,SaveState:Ot});customElements.get("data-grid")||customElements.define("data-grid",j);var xi=j,Mt=typeof globalThis<"u"?globalThis:self;Mt.DataGrid=j;export{xi as default}; /** * Data Grid custom element * https://github.com/lekoala/data-grid/ diff --git a/dist/data-grid.min.js.map b/dist/data-grid.min.js.map index 69c1308..1f7e219 100644 --- a/dist/data-grid.min.js.map +++ b/dist/data-grid.min.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/utils/camelize.js", "../src/utils/normalizeData.js", "../src/utils/shortcuts.js", "../src/core/base-element.js", "../src/utils/addSelectOption.js", "../src/utils/appendParamsToUrl.js", "../src/utils/convertArray.js", "../src/utils/elementOffset.js", "../src/utils/interpolate.js", "../src/utils/getTextWidth.js", "../src/utils/randstr.js", "../src/utils/debounce.js", "../src/data-grid.js", "../src/core/base-plugin.js", "../src/plugins/column-resizer.js", "../src/utils/getParentElement.js", "../src/plugins/context-menu.js", "../src/plugins/draggable-headers.js", "../src/plugins/touch-support.js", "../src/plugins/selectable-rows.js", "../src/plugins/fixed-height.js", "../src/plugins/autosize-column.js", "../src/plugins/responsive-grid.js", "../src/plugins/row-actions.js", "../src/plugins/editable-column.js", "../src/plugins/spinner-support.js", "../src/plugins/save-state.js", "../data-grid.js"], - "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], - "mappings": "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", - "names": ["camelize", "str", "m", "chr", "normalizeData", "v", "val", "supportedPassiveTypes", "passiveOpts", "type", "getAttribute", "el", "name", "hasAttribute", "setAttribute", "v", "check", "removeAttribute", "on", "listener", "off", "dispatch", "el", "name", "data", "bubbles", "opts", "hasClass", "addClass", "removeClass", "toggleClass", "$", "selector", "base", "$$", "find", "findAll", "ce", "tagName", "parent", "el", "insertAfter", "newNode", "existingNode", "BaseElement", "options", "opt", "v", "setAttribute", "jsonConfig", "data", "key", "normalizeData", "getAttribute", "event", "template", "dispatch", "attributeName", "oldValue", "newValue", "isOption", "transformer", "attr", "camelize", "base_element_default", "addSelectOption", "el", "value", "label", "checked", "opt", "appendParamsToUrl", "url", "params", "key", "k", "convertArray", "v", "bv", "elementOffset", "el", "rect", "scrollLeft", "scrollTop", "interpolate", "str", "data", "$1", "$2", "canvas", "getTextWidth", "text", "el", "withPadding", "styles", "fontWeight", "fontSize", "fontFamily", "padding", "paddingLeft", "paddingRight", "context", "metrics", "randstr", "prefix", "debounce", "handler", "timeout", "timer", "args", "plugins", "labels", "applyColumnDefinition", "el", "column", "setAttribute", "addClass", "DataGrid", "_DataGrid", "base_element_default", "randstr", "pluginName", "pluginClass", "attr", "camelize", "v", "#setNoData", "tbody", "list", "plugin", "columns", "cols", "key", "col", "item", "convertArray", "$", "val", "initOnly", "pv", "updatePage", "addSelectOption", "field", "found", "prop", "c", "render", "dispatch", "start", "visibleOnly", "len", "tr", "find", "row", "removeAttribute", "headers", "findAll", "th", "fieldName", "value", "k", "i", "keys", "force", "data", "metaKey", "dataKey", "callbackOrUrl", "needRender", "flagEmpty", "resolve", "response", "err", "event", "filters", "inputs", "input", "name", "baseCol", "haveClasses", "sort", "stack", "itemA", "itemB", "a", "b", "valA", "valB", "columnName", "sortDir", "dir", "reject", "base", "url", "params", "appendParamsToUrl", "newError", "error", "sortedColumn", "thead", "tfoot", "td", "availableWidth", "colMaxWidth", "idx", "ce", "sampleTh", "totalWidth", "colIdx", "computedWidth", "getTextWidth", "w", "colAvailableWidth", "visibleCols", "lastCol", "scrollbarWidth", "diff", "thWithWidth", "hasClass", "actualWidth", "minWidth", "newWidth", "rowsWithSort", "sortableRow", "relatedTh", "filter", "filteredRows", "eventName", "eventHandler", "debounce", "e", "isKeyPressFilter", "isSelect", "uniqueValues", "opt", "on", "ev", "toggleClass", "tv", "interpolate", "prev", "total", "p", "bodyRows", "index", "high", "low", "getAttribute", "data_grid_default", "BasePlugin", "grid", "event", "base_plugin_default", "ColumnResizer", "base_plugin_default", "grid", "resizeLabel", "table", "cols", "findAll", "col", "hasClass", "resizer", "addClass", "startX", "startW", "remainingSpace", "max", "mouseMoveHandler", "e", "newWidth", "setAttribute", "mouseUpHandler", "removeClass", "off", "dispatch", "getAttribute", "on", "target", "visibleCols", "columnIndex", "column", "removeAttribute", "elementOffset", "j", "column_resizer_default", "getParentElement", "el", "type", "prop", "parent", "ContextMenu", "base_plugin_default", "off", "grid", "on", "e", "t", "field", "target", "getParentElement", "menu", "rect", "x", "y", "removeAttribute", "documentClickHandler", "setAttribute", "col", "li", "label", "checkbox", "text", "context_menu_default", "DraggableHeaders", "base_plugin_default", "th", "grid", "on", "e", "t", "target", "getParentElement", "index", "targetIndex", "offset", "tmp", "swapNodes", "selector", "el1", "rowIndex", "el2", "setAttribute", "newNode", "findAll", "c", "getAttribute", "dispatch", "draggable_headers_default", "TouchSupport", "base_plugin_default", "grid", "e", "xDiff", "yDiff", "touch_support_default", "SELECTABLE_CLASS", "SELECT_ALL_CLASS", "CHECKBOX_CLASS", "SelectableRows", "base_plugin_default", "#cbSelector", "#inputSelector", "keys", "grid", "selectedData", "inputs", "findAll", "checkbox", "idx", "item", "k", "tbody", "input", "tr", "th", "setAttribute", "label", "td", "e", "el", "unchecked", "$$", "r", "hasClass", "cb", "totalCheckboxes", "dispatch", "selectable_rows_default", "FixedHeight", "base_plugin_default", "grid", "tbody", "tr", "setAttribute", "fakeRow", "max", "visibleRows", "fakeHeight", "fixed_height_default", "AutosizeColumn", "base_plugin_default", "th", "column", "min", "max", "grid", "hasAttribute", "getAttribute", "firstVal", "lastVal", "v", "v2", "width", "getTextWidth", "setAttribute", "autosize_column_default", "RESPONSIVE_CLASS", "obsTo", "sortByPriority", "list", "a", "b", "v1", "callback", "debounce", "entries", "entry", "grid", "table", "contentBoxSize", "size", "tableWidth", "realTableWidth", "findAll", "result", "th", "diff", "minWidth", "prevAction", "headerCols", "col", "changed", "remaining", "cols", "colWidth", "field", "requiredWidth", "width", "filteredHeaderCols", "footer", "find", "realFooterWidth", "div", "availableFooterWidth", "addClass", "removeClass", "resizeObserver", "ResponsiveGrid", "base_plugin_default", "flag", "tr", "ce", "setAttribute", "td", "idealWidth", "consideredCol", "hCol", "ev", "open", "close", "hasClass", "childRow", "hiddenCols", "insertAfter", "childRowTd", "childTable", "childTableRow", "label", "labelCol", "removeAttribute", "responsive_grid_default", "RowActions", "base_plugin_default", "tr", "actionsTh", "setAttribute", "item", "labels", "td", "actionsToggle", "on", "ev", "action", "button", "interpolate", "actionHandler", "dispatch", "row_actions_default", "EditableColumn", "base_plugin_default", "td", "column", "item", "i", "gridId", "input", "ev", "key", "dispatch", "editable_column_default", "SpinnerSupport", "base_plugin_default", "grid", "classes", "cls", "e", "template", "$", "styleParent", "position", "spinner_support_default", "SaveState", "base_plugin_default", "grid", "cachedState", "waitForColumns", "timeout", "start", "colAbsent", "resolve", "col", "hideCol", "c", "dgLoadData", "args", "saveState", "sortableHeaders", "findAll", "el", "filters", "newState", "key", "updateState", "state", "ev", "data", "save_state_default", "data_grid_default", "column_resizer_default", "context_menu_default", "draggable_headers_default", "touch_support_default", "selectable_rows_default", "fixed_height_default", "autosize_column_default", "responsive_grid_default", "row_actions_default", "editable_column_default", "spinner_support_default", "save_state_default", "global"] + "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const isSelect = /select/i.test(el.tagName);\r\n const eventName = isSelect ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\" || e.type === \"paste\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n if (!isSelect) { // Add paste event support for text input filters\r\n el.addEventListener(\"paste\", eventHandler);\r\n }\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], + "mappings": "AAIe,SAARA,EAA0BC,EAAK,CAClC,OAAOA,EAAI,YAAY,EAAE,QAAQ,oBAAqB,CAACC,EAAGC,IAAQA,EAAI,YAAY,CAAC,CACvF,CCDe,SAARC,EAA+BC,EAAG,CAErC,GAAIA,IAAM,OACN,MAAO,GAEX,GAAIA,IAAM,QACN,MAAO,GAGX,GAAIA,IAAM,IAAMA,IAAM,OAClB,OAAO,KAGX,GAAIA,IAAM,OAAOA,CAAC,EAAE,SAAS,EACzB,OAAO,OAAOA,CAAC,EAGnB,GAAIA,GAAK,OAAOA,EAAE,WAAc,YAAc,CAAC,IAAK,GAAG,EAAE,SAASA,EAAE,UAAU,EAAG,CAAC,CAAC,EAC/E,GAAI,CAEA,IAAIC,EAAMD,EACV,OAAIC,EAAI,QAAQ,GAAG,IAAM,KACrBA,EAAMA,EAAI,QAAQ,KAAM,GAAG,GAExB,KAAK,MAAM,mBAAmBA,CAAG,CAAC,CAC7C,MAAQ,CACJ,eAAQ,MAAM,mBAAmBD,CAAC,EAAE,EAC7B,CAAC,CACZ,CAEJ,OAAOA,CACX,CCSA,IAAME,GAAwB,CAC1B,SACA,QACA,aACA,YACA,aACA,WACA,aACA,WACA,aACA,UACA,YACA,YACA,aACA,aACA,WACJ,EAOA,SAASC,GAAYC,EAAM,CACvB,OAAIF,GAAsB,SAASE,CAAI,EAC5B,CAAE,QAAS,EAAK,EAEpB,CAAC,CACZ,CAOO,SAASC,EAAaC,EAAIC,EAAM,CACnC,OAAOD,EAAG,aAAaC,CAAI,CAC/B,CAOO,SAASC,EAAaF,EAAIC,EAAM,CACnC,OAAOD,EAAG,aAAaC,CAAI,CAC/B,CAQO,SAASE,EAAaH,EAAIC,EAAMG,EAAI,GAAIC,EAAQ,GAAO,CACtDA,GAASH,EAAaF,EAAIC,CAAI,GAClCD,EAAG,aAAaC,EAAM,GAAGG,CAAC,EAAE,CAChC,CAMO,SAASE,EAAgBN,EAAIC,EAAM,CAClCC,EAAaF,EAAIC,CAAI,GACrBD,EAAG,gBAAgBC,CAAI,CAE/B,CAOO,SAASM,EAAGP,EAAIF,EAAMU,EAAU,CACnCR,EAAG,iBAAiBF,EAAMU,EAAUX,GAAYC,CAAI,CAAC,CACzD,CAOO,SAASW,EAAIT,EAAIF,EAAMU,EAAU,CACpCR,EAAG,oBAAoBF,EAAMU,EAAUX,GAAYC,CAAI,CAAC,CAC5D,CAmBO,SAASY,EAASC,EAAIC,EAAMC,EAAO,CAAC,EAAGC,EAAU,GAAO,CAC3D,IAAMC,EAAO,CAAC,EACVD,IACAC,EAAK,QAAU,IAEfF,IACAE,EAAK,OAASF,GAElBF,EAAG,cAAc,IAAI,YAAYC,EAAMG,CAAI,CAAC,CAChD,CAOO,SAASC,EAASL,EAAIC,EAAM,CAC/B,OAAOD,EAAG,UAAU,SAASC,CAAI,CACrC,CAMO,SAASK,EAASN,EAAIC,EAAM,CAC/BD,EAAG,UAAU,IAAI,GAAGC,EAAK,MAAM,GAAG,CAAC,CACvC,CAMO,SAASM,EAAYP,EAAIC,EAAM,CAClCD,EAAG,UAAU,OAAO,GAAGC,EAAK,MAAM,GAAG,CAAC,CAC1C,CAMO,SAASO,GAAYR,EAAIC,EAAM,CAClCD,EAAG,UAAU,OAAOC,CAAI,CAC5B,CAOO,SAASQ,EAAEC,EAAUC,EAAO,SAAU,CACzC,OAAID,aAAoB,YACbA,EAEJC,EAAK,cAAcD,CAAQ,CACtC,CAOO,SAASE,EAAGF,EAAUC,EAAO,SAAU,CAC1C,OAAO,MAAM,KAAKA,EAAK,iBAAiBD,CAAQ,CAAC,CACrD,CASO,SAASG,EAAKb,EAAIU,EAAU,CAC/B,OAAOD,EAAEC,EAAUV,CAAE,CACzB,CASO,SAASc,EAAQd,EAAIU,EAAU,CAClC,OAAOE,EAAGF,EAAUV,CAAE,CAC1B,CAgBO,SAASe,EAAGC,EAASC,EAAS,KAAM,CACvC,IAAMC,EAAK,SAAS,cAAcF,CAAO,EACzC,OAAIC,GACAA,EAAO,YAAYC,CAAE,EAElBA,CACX,CAMO,SAASC,GAAYC,EAASC,EAAc,CAC/CA,EAAa,WAAW,aAAaD,EAASC,EAAa,WAAW,CAC1E,CC9PA,IAAMC,EAAN,cAA0B,WAAY,CAIlC,YAAYC,EAAU,CAAC,EAAG,CACtB,MAAM,EAGN,KAAK,QAAU,OAAO,OAAO,CAAC,EAAG,KAAK,eAAgB,KAAK,kBAAmBA,CAAO,EAErF,KAAK,IAAI,aAAa,EAEtB,KAAK,MAAQ,GACb,KAAK,WAAa,GAClB,KAAK,OAAO,EAEZ,KAAK,IAAI,OAAO,CACpB,CAEA,IAAI,gBAAiB,CACjB,MAAO,CAAC,CACZ,CAMA,UAAUC,EAAK,CACX,OAAO,KAAK,QAAQA,CAAG,CAC3B,CAMA,UAAUA,EAAKC,EAAG,CACdC,EAAa,KAAM,QAAQF,CAAG,GAAIC,CAAC,CACvC,CAKA,aAAaD,EAAK,CACdE,EAAa,KAAM,QAAQF,CAAG,GAAI,CAAC,KAAK,UAAUA,CAAG,CAAC,CAC1D,CAEA,IAAI,mBAAoB,CACpB,IAAMG,EAAa,KAAK,QAAQ,OAAS,KAAK,MAAM,KAAK,QAAQ,MAAM,EAAI,CAAC,EACtEC,EAAO,CAAE,GAAG,KAAK,OAAQ,EAC/B,QAAWC,KAAOD,EACVC,IAAQ,UAAY,CAACD,EAAK,eAAeC,CAAG,GAAK,OAAOD,EAAKC,CAAG,GAAM,aAG1ED,EAAKC,CAAG,EAAIC,EAAcF,EAAKC,CAAG,CAAC,GAGvC,cAAO,OAAOD,EAAMD,CAAU,EACvBC,CACX,CAKA,OAAO,UAAW,CACd,MAAO,EACX,CAKA,QAAS,CAAC,CAKV,OAAOA,EAAM,CACL,KAAK,QAAQ,OACb,QAAQ,IAAI,IAAIG,EAAa,KAAM,IAAI,CAAC,KAAM,GAAGH,CAAI,CAE7D,CAOA,YAAYI,EAAO,CACX,KAAK,KAAKA,EAAM,IAAI,EAAE,GACtB,KAAK,KAAKA,EAAM,IAAI,EAAE,EAAEA,CAAK,CAErC,CAKA,YAAa,CAAC,CAEd,mBAAoB,CAEZ,KAAK,QAGT,KAAK,MAAQ,GAEb,WAAW,SAAY,CACnB,KAAK,IAAI,mBAAmB,EAI5B,IAAMC,EAAW,SAAS,cAAc,UAAU,EAElDA,EAAS,UAAY,KAAK,YAAY,SAAS,EAC/C,KAAK,YAAYA,EAAS,QAAQ,UAAU,EAAI,CAAC,EAEjD,MAAM,KAAK,WAAW,EAGtBC,EAAS,KAAM,WAAW,CAC9B,EAAG,CAAC,EACR,CAKA,eAAgB,CAAC,CAKjB,sBAAuB,CACnB,WAAW,IAAM,CACT,CAAC,KAAK,aAAe,KAAK,QAC1B,KAAK,IAAI,sBAAsB,EAC/B,KAAK,cAAc,EAEnBA,EAAS,KAAM,cAAc,EAC7B,KAAK,MAAQ,GAErB,EAAG,CAAC,CACR,CAMA,IAAI,qBAAsB,CACtB,MAAO,CAAC,CACZ,CAUA,yBAAyBC,EAAeC,EAAUC,EAAU,CAExD,GAAID,IAAaC,EACb,OAGJ,KAAK,IAAI,6BAA6BF,CAAa,EAAE,EAErD,IAAIG,EAAW,GACTC,EAAc,KAAK,oBAAoBJ,CAAa,GAAKL,EAE3DU,EAAOL,EAEPK,EAAK,QAAQ,OAAO,IAAM,IAC1BA,EAAOA,EAAK,MAAM,CAAC,EACnBF,EAAW,IAEfE,EAAOC,EAASD,CAAI,EAChBF,EACA,KAAK,QAAQE,CAAI,EAAID,EAAYF,CAAQ,EAEzC,KAAKG,CAAI,EAAID,EAAYF,CAAQ,EAIjC,KAAK,YAAc,KAAK,GAAGG,CAAI,SAAS,GACxC,KAAK,GAAGA,CAAI,SAAS,EAAE,CAE/B,CACJ,EAEOE,GAAQpB,EChMA,SAARqB,EAAiCC,EAAIC,EAAOC,EAAOC,EAAU,GAAO,CACvE,IAAMC,EAAM,SAAS,cAAc,QAAQ,EAC3CA,EAAI,MAAQ,GAAGH,CAAK,GAChBE,IACAC,EAAI,SAAW,IAEnBA,EAAI,MAAQF,EACZF,EAAG,YAAYI,CAAG,CACtB,CCVe,SAARC,EAAmCC,EAAKC,EAAS,CAAC,EAAG,CACxD,QAAWC,KAAO,OAAO,KAAKD,CAAM,EAChC,GAAI,MAAM,QAAQA,EAAOC,CAAG,CAAC,EACzB,QAAWC,KAAK,OAAO,KAAKF,EAAOC,CAAG,CAAC,EAEnCF,EAAI,aAAa,OAAO,MAAMG,CAAC,EAAI,GAAGD,CAAG,IAAIC,CAAC,IAAMD,EAAKD,EAAOC,CAAG,EAAEC,CAAC,CAAC,OAG3EH,EAAI,aAAa,OAAOE,EAAKD,EAAOC,CAAG,CAAC,CAGpD,CCVe,SAARE,EAA8BC,EAAG,CACpC,GAAI,OAAOA,GAAM,SAAU,CACvB,GAAIA,EAAE,CAAC,IAAM,IAAK,CAEd,IAAIC,EAAKD,EACT,OAAIC,EAAG,QAAQ,GAAG,IAAM,KACpBA,EAAKA,EAAG,QAAQ,KAAM,GAAG,GAEtB,KAAK,MAAMA,CAAE,CACxB,CAEA,OAAOD,EAAE,MAAM,GAAG,CACtB,CACA,OAAK,MAAM,QAAQA,CAAC,EAIbA,GAHH,QAAQ,MAAM,gBAAiBA,CAAC,EACzB,CAAC,EAGhB,CCnBe,SAARE,GAA+BC,EAAI,CACtC,IAAMC,EAAOD,EAAG,sBAAsB,EAChCE,EAAa,OAAO,aAAe,SAAS,gBAAgB,WAC5DC,EAAY,OAAO,aAAe,SAAS,gBAAgB,UACjE,MAAO,CAAE,IAAKF,EAAK,IAAME,EAAW,KAAMF,EAAK,KAAOC,CAAW,CACrE,CCHe,SAARE,EAA6BC,EAAKC,EAAM,CAC3C,OAAOD,EAAI,QAAQ,gBAAiB,CAACE,EAAIC,IAAOF,EAAKE,CAAE,CAAC,CAC5D,CCRA,IAAIC,GAWW,SAARC,EAA8BC,EAAMC,EAAK,SAAS,KAAMC,EAAc,GAAO,CAChF,IAAMC,EAAS,OAAO,iBAAiBF,GAAM,SAAS,cAAc,KAAK,CAAC,EACpEG,EAAaD,EAAO,iBAAiB,aAAa,GAAK,SACvDE,EAAWF,EAAO,iBAAiB,WAAW,GAAK,OACnDG,EAAaH,EAAO,iBAAiB,aAAa,GAAK,QAEzDI,EAAU,EACd,GAAIL,EAAa,CACb,IAAMM,EAAcL,EAAO,iBAAiB,cAAc,GAAK,IACzDM,EAAeN,EAAO,iBAAiB,eAAe,GAAK,IACjEI,EAAU,OAAO,SAASC,CAAW,EAAI,OAAO,SAASC,CAAY,CACzE,CAGKX,KACDA,GAAS,SAAS,cAAc,QAAQ,GAE5C,IAAMY,EAAUZ,GAAO,WAAW,IAAI,EACtCY,EAAQ,KAAO,GAAGN,CAAU,IAAIC,CAAQ,IAAIC,CAAU,GACtD,IAAMK,EAAUD,EAAQ,YAAYV,CAAI,EACxC,OAAO,OAAO,SAASW,EAAQ,KAAK,EAAIJ,CAC5C,CC5Be,SAARK,EAAyBC,EAAQ,CACpC,OAAO,KAAK,OAAO,EACd,SAAS,EAAE,EACX,QAAQ,KAAMA,GAAU,EAAE,CACnC,CCEe,SAARC,EAA0BC,EAASC,EAAU,IAAK,CACrD,IAAIC,EAAQ,KACZ,MAAO,IAAIC,IAAS,CAChB,aAAaD,CAAK,EAClBA,EAAQ,WAAW,IAAM,CACrBA,EAAQ,KACRF,EAAQ,GAAGG,CAAI,CACnB,EAAGF,CAAO,CACd,CACJ,CC2JA,IAAIG,EAAU,CAAC,EAKXC,EAAS,CACT,aAAc,iBACd,SAAU,aACV,cAAe,mBACf,aAAc,sBACd,aAAc,kBACd,aAAc,kBACd,GAAI,KACJ,MAAO,QACP,aAAc,gBACd,OAAQ,UACR,WAAY,gBACZ,aAAc,wBAClB,EAOA,SAASC,GAAsBC,EAAIC,EAAQ,CACnCA,EAAO,OACPC,EAAaF,EAAI,QAASC,EAAO,KAAK,EAEtCA,EAAO,OACPE,EAASH,EAAIC,EAAO,KAAK,EAEzBA,EAAO,SACPC,EAAaF,EAAI,SAAU,EAAE,EACzBC,EAAO,kBACPE,EAASH,EAAI,sBAAsB,EAG/C,CAIA,IAAMI,GAAN,MAAMC,UAAiBC,EAAY,CAC/B,gBAAkB,kBAClB,4BAA8B,iCAC9B,cAAgB,CACZ,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,IACA,IACA,YACA,aACA,UACA,YACA,SACA,OACA,MACA,SACA,WACA,SACA,WACA,QACA,UACA,OACA,MACA,cACA,UACA,cACJ,EAEA,QAAS,CACLJ,EAAa,KAAM,KAAM,KAAK,QAAQ,IAAMK,EAAQ,KAAK,EAAG,EAAI,EAMhE,KAAK,KAAO,CAAC,EAKb,KAAK,aAML,KAAK,QAAU,KAAK,SAAW,KAAK,eAChC,KAAK,QAAQ,eAAc,KAAK,QAAQ,WAAa,IAGzD,KAAK,WAAa,GAClB,KAAK,KAAO,KAAK,QAAQ,aAAe,EACxC,KAAK,MAAQ,EACb,KAAK,KAIL,KAAK,QAAU,CAAC,EAEhB,OAAW,CAACC,EAAYC,CAAW,IAAK,OAAO,QAAQZ,CAAO,EAE1D,KAAK,QAAQW,CAAU,EAAI,IAAIC,EAAY,IAAI,EAKnD,QAAWC,KAAQL,EAAS,mBACpBK,EAAK,QAAQ,OAAO,IAAM,GAC1BR,EAAa,KAAMQ,EAAM,KAAK,QAAQC,EAASD,EAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAG1E,CAEA,OAAO,UAAW,CACd,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAM0BZ,EAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mEAMaA,EAAO,YAAY;AAAA;AAAA;AAAA,gFAGNA,EAAO,aAAa,iBAAiBA,EAAO,aAAa;AAAA;AAAA;AAAA,+EAG1DA,EAAO,YAAY,iBAAiBA,EAAO,YAAY;AAAA;AAAA;AAAA,sGAGhCA,EAAO,QAAQ;AAAA,qEAChDA,EAAO,YAAY,iBAAiBA,EAAO,YAAY;AAAA;AAAA;AAAA,qEAGvDA,EAAO,YAAY,iBAAiBA,EAAO,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,mFAKzCA,EAAO,EAAE,oCAAoCA,EAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CASxI,CAKA,IAAI,QAAS,CACT,OAAOA,CACX,CAKA,OAAO,WAAY,CACf,OAAOA,CACX,CAKA,OAAO,UAAUc,EAAG,CAChBd,EAAS,OAAO,OAAOA,EAAQc,CAAC,CACpC,CAGA,IAAI,QAAS,CACT,OAAO,KAAK,QAAQ,QAAU,KAAK,OAAO,MAC9C,CAKAC,GAAWC,EAAO,CACV,CAAC,KAAK,cAAgBA,EAAM,aAAa,YAAY,IAAM,KAAK,QAChEA,EAAM,aAAa,aAAc,KAAK,MAAM,CAEpD,CAKA,IAAI,eAAgB,CAChB,MAAO,CACH,MAAO,GACP,MAAO,GACP,MAAO,EACP,MAAO,GACP,KAAM,GACN,OAAQ,GACR,SAAU,GACV,OAAQ,GACR,WAAY,EACZ,iBAAkB,GAClB,OAAQ,GACR,UAAW,GACX,WAAY,OACZ,kBAAmB,CAAE,MAAO,GAAI,KAAM,EAAG,CAC7C,CACJ,CAKA,IAAI,gBAAiB,CACjB,MAAO,CACH,GAAI,KACJ,IAAK,GACL,QAAS,GACT,MAAO,GACP,OAAQ,GACR,KAAM,GACN,KAAM,GACN,OAAQ,GACR,aAAc,CACV,MAAO,QACP,OAAQ,SACR,OAAQ,SACR,KAAM,OACN,QAAS,UACT,QAAS,OACT,QAAS,OACT,aAAc,QACd,gBAAiB,WACjB,WAAY,UACZ,UAAW,QACf,EACA,YAAa,GACb,QAAS,GACT,IAAK,MACL,cAAe,CAAC,GAAI,GAAI,GAAI,IAAK,GAAG,EACpC,YAAa,GACb,QAAS,CAAC,EACV,QAAS,CAAC,EACV,gBAAiB,GACjB,WAAY,GACZ,kBAAmB,GACnB,aAAc,GACd,YAAa,EACb,UAAW,GACX,SAAU,GACV,OAAQ,GACR,WAAY,GACZ,cAAe,GACf,WAAY,GACZ,iBAAkB,GAClB,cAAe,GACf,oBAAqB,IACrB,aAAc,GACd,UAAW,GACX,aAAc,GACd,OAAQ,EACZ,CACJ,CAMA,IAAI,QAAS,CACT,OAAO,KAAK,UAAU,SAAS,gBAAgB,CACnD,CAMA,IAAI,cAAe,CACf,OAAO,KAAK,UAAU,SAAS,kBAAkB,CACrD,CAKA,OAAO,gBAAgBC,EAAM,CACzBlB,EAAUkB,CACd,CAKA,OAAO,kBAAkBC,EAAS,KAAM,CAChCA,IAAW,KACXnB,EAAU,CAAC,EAEX,OAAOA,EAAQmB,CAAM,CAE7B,CAKA,OAAO,mBAAoB,CACvB,OAAOnB,CACX,CAMA,eAAeoB,EAAS,CACpB,IAAMC,EAAO,CAAC,EAEd,GAAI,OAAOD,GAAY,UAAY,CAAC,MAAM,QAAQA,CAAO,EACrD,QAAWE,KAAO,OAAO,KAAKF,CAAO,EAAG,CACpC,IAAMG,EAAM,OAAO,OAAO,CAAC,EAAG,KAAK,aAAa,EAChDA,EAAI,MAAQH,EAAQE,CAAG,EACvBC,EAAI,MAAQD,EACZD,EAAK,KAAKE,CAAG,CACjB,KAEA,SAAWC,KAAQJ,EAAS,CACxB,IAAIG,EAAM,OAAO,OAAO,CAAC,EAAG,KAAK,aAAa,EAC1C,OAAOC,GAAS,UAChBD,EAAI,MAAQC,EACZD,EAAI,MAAQC,GACL,OAAOA,GAAS,UACvBD,EAAM,OAAO,OAAOA,EAAKC,CAAI,EACxBD,EAAI,OACL,QAAQ,MAAM,4BAA6BC,CAAI,EAE9CD,EAAI,QACLA,EAAI,MAAQA,EAAI,QAGpB,QAAQ,MAAM,iDAAiD,EAEnEF,EAAK,KAAKE,CAAG,CACjB,CAEJ,OAAOF,CACX,CAMA,WAAW,oBAAqB,CAC5B,MAAO,CACH,OACA,cACA,YACA,aACA,eACA,YACA,kBACA,qBACA,WACA,gBACA,iBACJ,CACJ,CAEA,IAAI,qBAAsB,CACtB,MAAO,CACH,QAAUN,GAAM,KAAK,eAAeU,EAAaV,CAAC,CAAC,EACnD,QAAUA,GAAMU,EAAaV,CAAC,EAC9B,YAAcA,GAAM,OAAO,SAASA,CAAC,EACrC,QAAUA,GAAM,OAAO,SAASA,CAAC,CACrC,CACJ,CAGA,IAAI,OAAQ,CAER,OAAOW,EAAE,QAAS,IAAI,CAC1B,CAGA,IAAI,OAAQ,CAER,OAAOA,EAAE,QAAS,IAAI,CAC1B,CAGA,IAAI,OAAQ,CAER,OAAOA,EAAE,QAAS,IAAI,CAC1B,CAEA,IAAI,MAAO,CACP,OAAO,OAAO,SAAS,KAAK,aAAa,MAAM,CAAC,CACpD,CAEA,IAAI,KAAKC,EAAK,CACVtB,EAAa,KAAM,OAAQ,KAAK,mBAAmBsB,CAAG,CAAC,CAC3D,CAMA,WAAWC,EAAW,GAAO,CACzB,OAAIA,GAAY,CAAC,KAAK,OAAe,MACrC,KAAK,SAAS,EACP,KAAK,SAAS,EAAE,KAAK,IAAM,KAAK,YAAY,CAAC,EACxD,CAKA,UAAW,CACP,IAAMP,EAAO,KAAK,QAAQ,QAC1B,YAAK,QAAQ,QAAU,CAAC,EACxB,KAAK,YAAY,EACV,KAAK,QAAQ,QAAUA,EAAM,IACxC,CAEA,mBAAmBN,EAAG,CAClB,IAAIc,EAAKd,EACT,OAAI,KAAK,MAAQc,IACbA,EAAK,KAAK,QAEVA,EAAK,GAAK,CAACA,KACXA,EAAK,GAEFA,CACX,CAEA,SAAU,CACN,OAAK,KAAK,WACV,KAAK,MAAQ,KAAK,WAAW,EAC7B,KAAK,KAAO,KAAK,mBAAmB,KAAK,IAAI,EAG7CxB,EAAa,KAAK,UAAW,MAAO,KAAK,KAAK,EAC9C,KAAK,UAAU,MAAQ,GAAG,KAAK,IAAI,GAC5B,KAAK,UAAU,SAAW,KAAK,MAAQ,EAAG,MAPrB,IAQhC,CAEA,aAAc,CACV,KAAK,OAAO,CAChB,CAEA,mBAAoB,CACX,KAAK,QAAQ,iBAGd,KAAK,QAAQ,WACb,KAAK,QAAQ,eAAe,QAAQ,EAEpC,KAAK,QAAQ,eAAe,UAAU,EAE9C,CAEA,aAAc,CACV,KAAK,aAAa,CACtB,CAKA,eAAgB,CACZ,KAAK,QAAQ,QAAU,OAAO,SAAS,KAAK,cAAc,QAAQ,KAAK,cAAc,aAAa,EAAE,KAAK,EACzG,KAAK,eAAe,CACxB,CAKA,gBAAiB,CAGT,KAAK,QAAQ,UAAY,OAAO,SAAS,KAAK,cAAc,QAAQ,KAAK,cAAc,aAAa,EAAE,KAAK,GAE3G,KAAK,qBAAqB,EAG9B,IAAIyB,EAAa,KAAK,KACtB,KAAOA,EAAa,GAAK,KAAK,KAAO,KAAK,QAAQ,QAAU,KAAK,aAAa,GAC1EA,IAEAA,IAAe,KAAK,KAEpB,KAAK,KAAOA,EAGZ,KAAK,OAAO,IAAM,EAEV,CAAC,KAAK,QAAQ,aAAe,CAAC,KAAK,QAAQ,YAAY,iBACvD,KAAK,cAAc,eAAe,CAE1C,CAAC,CAET,CAEA,YAAa,CACTzB,EAAa,KAAM,MAAO,KAAK,QAAQ,GAAG,CAC9C,CAEA,oBAAqB,CACjB,KAAK,YAAY,CACrB,CAKA,sBAAuB,CACnB,GAAK,KAAK,cAGV,MAAO,KAAK,cAAc,WACtB,KAAK,cAAc,YAAY,KAAK,cAAc,SAAS,EAE/D,QAAWU,KAAK,KAAK,QAAQ,cACzBgB,EAAgB,KAAK,cAAehB,EAAGA,EAAGA,IAAM,KAAK,QAAQ,OAAO,EAE5E,CAEA,MAAM,YAAa,CAIf,KAAK,MAAQ,KAAK,cAAc,OAAO,EAIvC,KAAK,SAAW,KAAK,cAAc,eAAe,EAIlD,KAAK,QAAU,KAAK,cAAc,cAAc,EAIhD,KAAK,QAAU,KAAK,cAAc,cAAc,EAIhD,KAAK,QAAU,KAAK,cAAc,cAAc,EAIhD,KAAK,cAAgB,KAAK,cAAc,qBAAqB,EAI7D,KAAK,UAAY,KAAK,cAAc,gBAAgB,EAEpD,KAAK,SAAW,KAAK,SAAS,KAAK,IAAI,EACvC,KAAK,QAAU,KAAK,QAAQ,KAAK,IAAI,EACrC,KAAK,QAAU,KAAK,QAAQ,KAAK,IAAI,EACrC,KAAK,QAAU,KAAK,QAAQ,KAAK,IAAI,EACrC,KAAK,cAAgB,KAAK,cAAc,KAAK,IAAI,EACjD,KAAK,SAAW,KAAK,SAAS,KAAK,IAAI,EAEvC,KAAK,SAAS,iBAAiB,QAAS,KAAK,QAAQ,EACrD,KAAK,QAAQ,iBAAiB,QAAS,KAAK,OAAO,EACnD,KAAK,QAAQ,iBAAiB,QAAS,KAAK,OAAO,EACnD,KAAK,QAAQ,iBAAiB,QAAS,KAAK,OAAO,EACnD,KAAK,cAAc,iBAAiB,SAAU,KAAK,aAAa,EAChE,KAAK,cAAc,gBAAgB,SAAU,KAAK,QAAQ,WAAW,EACrE,KAAK,UAAU,iBAAiB,QAAS,KAAK,QAAQ,EAEtD,QAAWI,KAAU,OAAO,OAAO,KAAK,OAAO,EAC3C,MAAMA,EAAO,UAAU,EAI3B,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAE1B,MAAM,KAAK,KAAK,CACpB,CAEA,eAAgB,CACZ,KAAK,UAAU,oBAAoB,QAAS,KAAK,QAAQ,EACzD,KAAK,SAAS,oBAAoB,QAAS,KAAK,OAAO,EACvD,KAAK,SAAS,oBAAoB,QAAS,KAAK,OAAO,EACvD,KAAK,SAAS,oBAAoB,QAAS,KAAK,OAAO,EACvD,KAAK,eAAe,oBAAoB,SAAU,KAAK,aAAa,EACpE,KAAK,WAAW,oBAAoB,QAAS,KAAK,QAAQ,EAE1D,QAAWA,KAAU,OAAO,OAAO,KAAK,OAAO,EAC3CA,EAAO,aAAa,CAE5B,CAEA,MAAO,CACH,OAAO,KAAK,SAAS,EAAE,QAAQ,IAAM,CACjC,KAAK,YAAY,EAEjB,KAAK,YAAY,EACjB,KAAK,UAAU,IAAI,gBAAgB,EAEnC,KAAK,cAAc,EACnB,KAAK,eAAe,EAEpB,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAEjB,KAAK,WAAa,GAElB,KAAK,IAAI,aAAa,CAC1B,CAAC,CACL,CAMA,OAAOa,EAAO,CACV,IAAIC,EAAQ,KAEZ,QAAWV,KAAO,KAAK,QAAQ,QACvBA,EAAI,QAAUS,IACdC,EAAQV,GAGhB,OAAOU,CACX,CAEA,WAAWD,EAAOE,EAAM,CACpB,IAAMC,EAAI,KAAK,OAAOH,CAAK,EAC3B,OAAOG,EAAIA,EAAED,CAAI,EAAI,IACzB,CAEA,WAAWF,EAAOE,EAAMP,EAAK,CACzB,IAAMQ,EAAI,KAAK,OAAOH,CAAK,EACvBG,IACAA,EAAED,CAAI,EAAIP,EAElB,CAEA,gBAAiB,CACb,OAAO,KAAK,QAAQ,QAAQ,OAAQJ,GACzB,CAACA,EAAI,MACf,CACL,CAEA,eAAgB,CACZ,OAAO,KAAK,QAAQ,QAAQ,OAAQA,GACzBA,EAAI,SAAW,EACzB,CACL,CAEA,WAAWS,EAAOI,EAAS,GAAM,CAC7B,KAAK,WAAWJ,EAAO,SAAU,EAAK,EAGlCI,GAAQ,KAAK,YAAY,EAE7BC,EAAS,KAAM,mBAAoB,CAC/B,IAAKL,EACL,WAAY,SAChB,CAAC,CACL,CAEA,WAAWA,EAAOI,EAAS,GAAM,CAC7B,KAAK,WAAWJ,EAAO,SAAU,EAAI,EAGjCI,GAAQ,KAAK,YAAY,EAE7BC,EAAS,KAAM,mBAAoB,CAC/B,IAAKL,EACL,WAAY,QAChB,CAAC,CACL,CAMA,eAAgB,CACZ,IAAIM,EAAQ,EACZ,OAAI,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBACxCA,IAEA,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBAAkB,KAAK,QAAQ,eAAe,iBAAiB,GACvGA,IAEGA,CACX,CAKA,UAAW,CACP,OAAO,KAAK,aAAa,QAAQ,CACrC,CAMA,cAAcC,EAAc,GAAO,CAC/B,IAAIC,EAAM,EAEV,QAAWjB,KAAO,KAAK,QAAQ,QACvBgB,GAAehB,EAAI,QAGlBA,EAAI,MACLiB,IAIR,OAAI,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBACxCA,IAGA,KAAK,QAAQ,QAAQ,QAAU,KAAK,QAAQ,YAC5CA,IAGA,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBAAkB,KAAK,QAAQ,eAAe,iBAAiB,GACvGA,IAEGA,CACX,CAMA,aAAc,CACV,GAAI,CAAC,KAAK,MAAO,OAAO,KAUxB,GATA,KAAK,MAAM,MAAM,WAAa,SAC9B,KAAK,YAAY,EACb,KAAK,QAAQ,YAAc,KAAK,QAAQ,iBAGxC,KAAK,MAAM,MAAM,WAAa,WAI9B,CAAC,KAAK,UAAW,CACjB,IAAMC,EAAKC,EAAK,KAAM,UAAU,GAAKA,EAAK,KAAM,UAAU,EACtDD,IACA,KAAK,UAAYA,EAAG,aAE5B,CACA,YAAKzB,GAAW,KAAK,KAAK,EACnB,KAAK,QAAQ,CACxB,CAEA,eAAgB,CACZ,IAAM2B,EAAM,KAAK,cAAc,0BAA0B,EACrD,KAAK,QAAQ,OACbC,EAAgBD,EAAK,QAAQ,GAE7B,KAAK,aAAa,EAClBtC,EAAasC,EAAK,SAAU,EAAE,EAEtC,CAEA,gBAAiB,CACb,IAAME,EAAUC,EAAQ,KAAM,6BAA6B,EAC3D,QAAWC,KAAMF,EACTE,EAAG,UAAU,SAAS,eAAe,GAAKA,EAAG,UAAU,SAAS,YAAY,IAG5E,KAAK,QAAQ,SAAW,KAAK,QAAQ,iBACrCA,EAAG,UAAY,GAEfA,EAAG,gBAAgB,WAAW,EAG1C,CAEA,aAAc,CACV,KAAK,IAAI,aAAa,EAEtB,IAAMF,EAAUC,EAAQ,KAAM,6BAA6B,EAC3D,QAAWC,KAAMF,EAAS,CACtB,IAAMG,EAAYD,EAAG,aAAa,OAAO,EACzC,GACIA,EAAG,UAAU,SAAS,iBAAiB,GACtC,CAAC,KAAK,YAAcC,IAAc,KAAK,QAAQ,YAEhD,OAEA,KAAK,QAAQ,MAAQ,CAAC,KAAK,WAAWA,EAAW,QAAQ,EACzD3C,EAAa0C,EAAI,YAAa,MAAM,EAEpCH,EAAgBG,EAAI,WAAW,CAEvC,CACJ,CAEA,mBAAoB,CAChB,KAAK,YAAY,CACrB,CAEA,OAAOJ,EAAK,CACH,MAAM,QAAQ,KAAK,YAAY,IAGpC,KAAK,IAAI,SAAS,EAClB,KAAK,aAAa,KAAKA,CAAG,EAC1B,KAAK,KAAO,KAAK,aAAa,MAAM,EACpC,KAAK,SAAS,EAClB,CAMA,UAAUM,EAAQ,KAAM3B,EAAM,KAAM,CAChC,GAAI,CAAC,MAAM,QAAQ,KAAK,YAAY,EAChC,OAGJ,IAAIP,EAAIkC,EACJC,EAAI5B,EACJ4B,IAAM,OACNA,EAAI,KAAK,QAAQ,QAAQ,CAAC,EAAE,OAE5BnC,IAAM,OACNA,EAAI,KAAK,aAAa,KAAK,aAAa,OAAS,CAAC,EAAEmC,CAAC,GAEzD,KAAK,IAAI,cAAcA,CAAC,IAAInC,CAAC,EAAE,EAC/B,QAASoC,EAAI,EAAGA,EAAI,KAAK,aAAa,OAAQA,IAC1C,GAAI,KAAK,aAAaA,CAAC,EAAED,CAAC,IAAMnC,EAAG,CAC/B,KAAK,aAAa,OAAOoC,EAAG,CAAC,EAC7B,KACJ,CAEJ,KAAK,KAAO,KAAK,aAAa,MAAM,EACpC,KAAK,SAAS,CAClB,CAWA,gBAAgBC,EAAM,CAClB,OAAK,KAAK,QAAQ,eAGX,KAAK,QAAQ,eAAe,aAAa,GAAGA,CAAI,EAF5C,CAAC,CAGhB,CAEA,SAAU,CACN,OAAO,KAAK,YAChB,CAEA,UAAUC,EAAQ,GAAO,CAEjB,CAACA,GAAS,KAAK,KAAK,SAAW,IAGnC,KAAK,UAAU,OAAO,WAAY,kBAAkB,EACpD,KAAK,OAAO,aAAa,aAAc,KAAK,MAAM,EAClD,KAAK,KAAO,KAAK,aAAe,CAAC,EACjC,KAAK,WAAW,EACpB,CAOA,QAAQC,EAAM,CACV,IAAMC,EAAU,KAAK,QAAQ,aAAa,QACpCC,EAAU,KAAK,QAAQ,aAAa,QACtCF,IAAOC,CAAO,IACd,KAAK,KAAOD,EAAKC,CAAO,GAExBD,IAAOE,CAAO,IACd,KAAK,KAAO,KAAK,aAAeF,EAAKE,CAAO,EAEpD,CAOA,QAAQC,EAAgB,KAAM,CAC1B,YAAK,KAAO,KAAK,aAAe,CAAC,EAC1B,KAAK,OAAOA,CAAa,CACpC,CAOA,OAAOA,EAAgB,KAAM,CACzB,KAAK,IAAI,QAAQ,EACb,OAAOA,GAAkB,WACzB,KAAK,QAAQ,IAAMA,GAGvB,IAAMC,EAAa,CAAC,KAAK,cAAc,OACvC,YAAK,QAAQ,EAEN,KAAK,SAAS,EAAE,QAAQ,IAAM,CAC7B,KAAK,eAGT,KAAK,QAAQ,QAAUA,EAAa,KAAK,WAAW,EAAI,KAAK,SAAS,EAClE,OAAOD,GAAkB,YACzBA,EAAc,EAEtB,CAAC,EAAE,KAAK,IAAM,IAAI,CACtB,CAKA,UAAW,CACP,IAAME,EAAY,IAAM,CAAC,KAAK,KAAK,QAAU,KAAK,UAAU,IAAI,UAAU,EACpE1C,EAAQ,KAAK,MAGnB,OAAI,KAAK,MAAQ,KAAK,cAAgB,KAAK,UAEnC,CAAC,KAAK,QAAQ,QAAW,KAAK,QAAQ,QAAU,CAAC,KAAK,aACtD,KAAK,IAAI,eAAe,EACxB0C,EAAU,EACH,IAAI,QAASC,GAAY,CAC5BA,EAAQ,CACZ,CAAC,IAGT,KAAK,IAAI,UAAU,EACnB,KAAK,QAAU,GACf,KAAK,UAAU,IAAI,YAAY,EAC/B,KAAK,UAAU,OAAO,WAAY,kBAAkB,EAEhD,KAAK,UAAU,EACV,KAAMC,GAAa,CAEhB,GAAI,MAAM,QAAQA,CAAQ,EACtB,KAAK,KAAOA,MACT,CAEH,GAAI,CAACA,EAAS,KAAK,QAAQ,aAAa,OAAO,EAAG,CAC9C,QAAQ,MACJ,mFACAA,CACJ,EACA,KAAK,QAAQ,IAAM,KACnB,MACJ,CAGA,KAAK,QAAU,OAAO,OAClB,KAAK,QACLA,EAAS,KAAK,QAAQ,aAAa,UAAU,GAAK,CAAC,CACvD,EAEA,KAAK,KAAOA,EAAS,KAAK,QAAQ,aAAa,OAAO,GAAK,CAAC,EAC5D,KAAK,KAAOA,EAAS,KAAK,QAAQ,aAAa,OAAO,CAC1D,CACA,KAAK,aAAe,KAAK,KAAK,MAAM,EACpC,KAAK,QAAQ,EAGT,KAAK,QAAQ,QAAQ,SAAW,GAAK,KAAK,aAAa,OACvD,KAAK,QAAQ,QAAU,KAAK,eAAe,OAAO,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,EAE5E,KAAK,QAAQ,QAAU,KAAK,eAAe,KAAK,QAAQ,OAAO,CAEvE,CAAC,EACA,MAAOC,GAAQ,CACZ,KAAK,IAAIA,CAAG,EACZ7C,EAAM,aACF,aACA,KAAK,QAAQ,cACT6C,EAAI,SAAS,QAAQ,oBAAqB,EAAE,GAC5C7D,EAAO,YACf,EACA,KAAK,UAAU,IAAI,WAAY,kBAAkB,EACjDoC,EAAS,KAAM,iBAAkByB,CAAG,CACxC,CAAC,EAEA,QAAQ,IAAM,CACXH,EAAU,EACV,KAAK3C,GAAWC,CAAK,EACrB,KAAK,UAAU,OAAO,YAAY,EAClCZ,EAAa,KAAK,MAAO,gBAAiB,KAAK,KAAK,MAAM,EAC1D,KAAK,QAAU,EACnB,CAAC,EAEb,CAEA,UAAW,CACH,KAAK,UAGT,KAAK,KAAO,EAChB,CAEA,SAAU,CACF,KAAK,UAGT,KAAK,KAAO,KAAK,MACrB,CAEA,SAAU,CACF,KAAK,UAGT,KAAK,KAAO,KAAK,KAAO,EAC5B,CAEA,SAAU,CACF,KAAK,UAGT,KAAK,KAAO,KAAK,KAAO,EAC5B,CAEA,SAAS0D,EAAO,CACZ,GAAIA,EAAM,OAAS,WAAY,CAC3B,IAAMzC,EAAMyC,EAAM,SAAWA,EAAM,IACnC,GAAIzC,IAAQ,IAAMA,IAAQ,QACtByC,EAAM,eAAe,MAErB,OAER,CACA,KAAK,KAAO,OAAO,SAAS,KAAK,UAAU,KAAK,CACpD,CAEA,SAAU,CACN,IAAMxC,EAAM,KAAK,cAAc,oDAAoD,EACnF,OAAIA,EACOA,EAAI,aAAa,OAAO,EAE5B,KAAK,QAAQ,WACxB,CAEA,YAAa,CACT,IAAMA,EAAM,KAAK,cAAc,oDAAoD,EACnF,OAAIA,GACOA,EAAI,aAAa,WAAW,GAAK,EAGhD,CAEA,YAAa,CACT,IAAMyC,EAAU,CAAC,EACXC,EAASnB,EAAQ,KAAM,KAAK,eAAe,EACjD,QAAWoB,KAASD,EAChBD,EAAQE,EAAM,QAAQ,IAAI,EAAIA,EAAM,MAExC,OAAOF,CACX,CAEA,cAAe,CACX,IAAMC,EAASnB,EAAQ,KAAM,KAAK,eAAe,EACjD,QAAWoB,KAASD,EAChBC,EAAM,MAAQ,GAElB,KAAK,WAAW,CACpB,CAEA,YAAa,CAKT,GAJA,KAAK,IAAI,aAAa,EAEtB,KAAK,KAAO,EAER,KAAK,QAAQ,OACb,KAAK,OAAO,MACT,CACH,KAAK,KAAO,KAAK,cAAc,MAAM,GAAK,CAAC,EAG3C,IAAMD,EAASnB,EAAQ,KAAM,KAAK,eAAe,EACjD,QAAWoB,KAASD,EAAQ,CACxB,IAAMhB,EAAQiB,EAAM,MACpB,GAAIjB,EAAO,CACP,IAAMkB,EAAOD,EAAM,QAAQ,KAC3B,KAAK,KAAO,KAAK,KAAK,OAAQ1C,GACd,GAAGA,EAAK2C,CAAI,CAAC,GACd,YAAY,EAAE,QAAQlB,EAAM,YAAY,CAAC,IAAM,EAC7D,CACL,CACJ,CACA,KAAK,YAAY,EAEjB,IAAM1B,EAAM,KAAK,cAAc,oDAAoD,EAC/E,KAAK,QAAQ,MAAQA,EACrB,KAAK,SAAS,EAEd,KAAK,WAAW,CAExB,CACJ,CAMA,SAAS6C,EAAU,KAAM,CACrB,KAAK,IAAI,WAAW,EAEpB,IAAI7C,EAAM6C,EAGV,GAAI7C,GAAO,KAAK,WAAWA,EAAI,aAAa,OAAO,EAAG,QAAQ,EAAG,CAC7D,KAAK,IAAI,kDAAkD,EAC3D,MACJ,CACA,GAAI,KAAK,QAAQ,eAAe,WAAY,CACxC,KAAK,IAAI,oCAAoC,EAC7C,MACJ,CACA,GAAI,KAAK,QAAS,CACd,KAAK,IAAI,mCAAmC,EAC5C,MACJ,CAGA,GAAIA,IAAQ,KAAM,CAEd,IAAM8C,EAAelC,GAAM,CAAC,gBAAiB,aAAc,sBAAsB,EAAE,SAASA,CAAC,EAEvFU,EAAUC,EAAQ,KAAM,yBAAyB,EACvD,QAAWC,KAAMF,EAET,CAAC,GAAGE,EAAG,SAAS,EAAE,KAAKsB,CAAW,GAAK,CAACtB,EAAG,aAAa,WAAW,GAGnEA,IAAOxB,GACPwB,EAAG,aAAa,YAAa,MAAM,EAKvC,CAACxB,EAAI,aAAa,WAAW,GAAKA,EAAI,aAAa,WAAW,IAAM,OACpEA,EAAI,aAAa,YAAa,WAAW,EAClCA,EAAI,aAAa,WAAW,IAAM,YACzCA,EAAI,aAAa,YAAa,YAAY,EACnCA,EAAI,aAAa,WAAW,IAAM,cACzCA,EAAI,aAAa,YAAa,MAAM,CAE5C,MAEIA,EAAM,KAAK,cAAc,oDAAoD,EAGjF,GAAI,KAAK,QAAQ,OAEb,KAAK,SAAS,EAAE,QAAQ,IAAM,CAC1B,KAAK,WAAW,CACpB,CAAC,MACE,CACH,IAAM+C,EAAO/C,EAAMA,EAAI,aAAa,WAAW,EAAI,OACnD,GAAI+C,IAAS,OAAQ,CACjB,IAAMC,EAAQ,CAAC,EAGf,KAAK,cAAc,KAAMC,IACrB,KAAK,KAAK,KAAMC,GACR,KAAK,UAAUD,CAAK,IAAM,KAAK,UAAUC,CAAK,GAC9CF,EAAM,KAAKE,CAAK,EACT,IAEJ,EACV,EACMF,EAAM,SAAW,KAAK,KAAK,OACrC,EAED,KAAK,KAAOA,CAChB,KAAO,CACH,IAAMvC,EAAQT,EAAI,aAAa,OAAO,EACtC,KAAK,KAAK,KAAK,CAACmD,EAAGC,IAAM,CACrB,GAAI,CAAC,MAAMD,EAAE1C,CAAK,CAAC,GAAK,CAAC,MAAM2C,EAAE3C,CAAK,CAAC,EACnC,OAAOsC,IAAS,YAAcI,EAAE1C,CAAK,EAAI2C,EAAE3C,CAAK,EAAI2C,EAAE3C,CAAK,EAAI0C,EAAE1C,CAAK,EAE1E,IAAM4C,EAAON,IAAS,YAAcI,EAAE1C,CAAK,EAAE,YAAY,EAAI2C,EAAE3C,CAAK,EAAE,YAAY,EAC5E6C,EAAOP,IAAS,YAAcK,EAAE3C,CAAK,EAAE,YAAY,EAAI0C,EAAE1C,CAAK,EAAE,YAAY,EAElF,OAAQ,GAAM,CACV,KAAK4C,EAAOC,EACR,MAAO,GACX,KAAKD,EAAOC,EACR,MAAO,GACX,KAAKD,IAASC,EACV,MAAO,EACf,CACJ,CAAC,CACL,CACA,KAAK,WAAW,CACpB,CACJ,CAEA,MAAMC,EAAYC,EAAS,CACvB,IAAMxD,EAAM,KAAK,cAAc,6BAA6BuD,CAAU,GAAG,EACnEE,EAAMD,IAAY,YAAc,OAASA,IAAY,aAAe,YAAc,aACxFxD,GAAK,aAAa,YAAayD,CAAG,EAClC,KAAK,SAASzD,CAAG,CACrB,CAEA,QAAWuD,GAAe,KAAK,MAAMA,EAAY,WAAW,EAC5D,SAAYA,GAAe,KAAK,MAAMA,EAAY,YAAY,EAC9D,SAAYA,GAAe,KAAK,MAAMA,EAAY,MAAM,EAExD,WAAY,CACR,GAAI,CAAC,KAAK,QAAQ,IACd,OAAO,IAAI,QAAQ,CAAClB,EAASqB,IAAWA,EAAO,YAAY,CAAC,EAGhE,IAAIC,EAAO,OAAO,SAAS,KAEtBA,EAAK,MAAM,GAAG,EAAE,IAAI,EAAE,SAAS,GAAG,IACnCA,GAAQA,EAAK,SAAS,GAAG,EAAI,GAAK,KAEtC,IAAMC,EAAM,IAAI,IAAI,KAAK,QAAQ,IAAKD,CAAI,EACtCE,EAAS,CACT,EAAG,KAAK,IAAI,CAChB,EACA,OAAI,KAAK,QAAQ,SAEbA,EAAO,KAAK,QAAQ,aAAa,KAAK,EAAI,KAAK,KAAO,EACtDA,EAAO,KAAK,QAAQ,aAAa,MAAM,EAAI,KAAK,QAAQ,QACpD,KAAK,QAAQ,SAAQA,EAAO,KAAK,QAAQ,aAAa,MAAM,EAAI,KAAK,WAAW,GACpFA,EAAO,KAAK,QAAQ,aAAa,IAAI,EAAI,KAAK,QAAQ,GAAK,GAC3DA,EAAO,KAAK,QAAQ,aAAa,OAAO,EAAI,KAAK,WAAW,EAGxD,KAAK,OAAO,KAAK,QAAQ,aAAa,SAAS,IAC/CA,EAAS,OAAO,OAAOA,EAAQ,KAAK,KAAK,KAAK,QAAQ,aAAa,SAAS,CAAC,IAIrFC,EAAkBF,EAAKC,CAAM,EAEtB,MAAMD,CAAG,EAAE,KAAMtB,GAAa,CACjC,IAAMyB,EAAW,IAAI,MAAMzB,EAAS,YAAc5D,EAAO,YAAY,EACrE,GAAI,CAAC4D,EAAS,GAEV,MAAAyB,EAAS,SAAWzB,EACdyB,EAEV,OAAOzB,EACF,MAAM,EACN,KAAK,EACL,MAAOC,GAAQ,CACZ,IAAIyB,EAAQzB,EACZ,MAAK,KAAK,QAAQ,QACdyB,EAAQD,GAEZC,EAAM,SAAW1B,EACX0B,CACV,CAAC,CACT,CAAC,CACL,CAEA,aAAc,CACV,KAAK,IAAI,cAAc,EAEnB,KAAK,QAAQ,MAAQ,KAAK,QAAQ,aAClC,KAAK,QAAQ,YAAY,WAAW,EAGxC,IAAIC,EAEJ,KAAK,aAAa,EACd,KAAK,QAAQ,cAEbA,EAAe,KAAK,cAAc,sCAAsC,KAAK,QAAQ,WAAW,IAAI,GAGpGA,EACA,KAAK,SAASA,CAAY,EAE1B,KAAK,WAAW,EAGpB,KAAK,aAAa,CACtB,CAOA,cAAe,CACX,KAAK,IAAI,eAAe,EAExB,IAAMC,EAAQ,KAAK,MACnB,KAAK,oBAAoBA,CAAK,EAC9B,KAAK,oBAAoBA,CAAK,EAE1B,KAAK,QAAQ,WAAa,KAAK,QAAQ,eACvC,KAAK,QAAQ,cAAc,cAAcxF,EAAO,YAAY,EAGhEoC,EAAS,KAAM,gBAAgB,CACnC,CAEA,cAAe,CACX,KAAK,IAAI,eAAe,EAExB,IAAMqD,EAAQ,KAAK,MACnB,GAAI,CAACA,EAAO,OACZ,IAAMC,EAAKD,EAAM,cAAc,IAAI,EACnCA,EAAM,gBAAgB,QAAQ,EAC9BrF,EAAasF,EAAI,UAAW,KAAK,cAAc,EAAI,CAAC,EACpDD,EAAM,MAAM,QAAU,EAC1B,CAMA,oBAAoBD,EAAO,CAEvB,IAAMG,EAAiB,KAAK,YACtBC,EAAc,KAAK,MAAOD,EAAiB,KAAK,cAAc,EAAI,EAAK,CAAC,EAE1EE,EAAM,EACNrD,EAGJA,EAAKsD,EAAG,IAAI,EACZ,KAAK,UAAYtD,EACjBA,EAAG,aAAa,OAAQ,KAAK,EAC7BA,EAAG,aAAa,gBAAiB,GAAG,EACpCA,EAAG,aAAa,QAAS,iBAAiB,EAG1C,IAAIuD,EAAWP,GAAO,cAAc,uBAAuB,EAC3D,KAAK,IAAI,iCAAkCO,CAAQ,EAC9CA,IACDA,EAAWD,EAAG,IAAI,EAClBN,GAAO,cAAc,IAAI,EAAE,YAAYO,CAAQ,GAG/C,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBACxC,KAAK,QAAQ,eAAe,gBAAgBvD,CAAE,EAE9C,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBAAkB,KAAK,QAAQ,eAAe,iBAAiB,GACvG,KAAK,QAAQ,eAAe,gBAAgBA,CAAE,EAIlDqD,EAAM,EACN,IAAIG,EAAa,EACjB,KAAK,IAAI,gCAAiC,KAAK,QAAQ,OAAO,EAE9D,QAAW7F,KAAU,KAAK,QAAQ,QAAS,CACvC,GAAIA,EAAO,KACP,SAEJ,IAAM8F,EAASJ,EAAM,KAAK,cAAc,EAClC/C,EAAKgD,EAAG,IAAI,EAClBhD,EAAG,aAAa,QAAS,KAAK,EAC9BA,EAAG,aAAa,OAAQ,qBAAqB,EAC7CA,EAAG,aAAa,gBAAiB,GAAGmD,CAAM,EAAE,EAC5CnD,EAAG,aAAa,KAAMrC,EAAQ,SAAS,CAAC,EACpC,KAAK,QAAQ,MACbqC,EAAG,aAAa,YAAa,MAAM,EAEvCA,EAAG,aAAa,QAAS3C,EAAO,KAAK,EACjC,KAAK,QAAQ,gBAAkB,KAAK,QAAQ,YAC5CC,EAAa0C,EAAI,kBAAmB3C,EAAO,YAAc,EAAE,EAG/D,IAAM+F,EAAgBC,EAAahG,EAAO,MAAO4F,EAAU,EAAI,EAAI,GACnEjD,EAAG,QAAQ,SAAW,GAAGoD,CAAa,GACtCjG,GAAsB6C,EAAI3C,CAAM,EAChC2C,EAAG,SAAW,EACdA,EAAG,YAAc3C,EAAO,MAExB,IAAIiG,EAAI,EAGR,GAAI,KAAK,QAAQ,UAAY,KAAK,QAAQ,eAAgB,CACtD,IAAMC,EAAoB,KAAK,IAAIV,EAAiBK,EAAYJ,CAAW,EAC3EQ,EAAI,KAAK,QAAQ,eAAe,YAC5BtD,EACA3C,EACA,OAAO,SAAS2C,EAAG,QAAQ,QAAQ,EACnCuD,CACJ,CACJ,MACID,EAAI,KAAK,IAAI,OAAO,SAAStD,EAAG,QAAQ,QAAQ,EAAG,OAAO,SAASA,EAAG,aAAa,OAAO,CAAC,CAAC,EAGhG1C,EAAa0C,EAAI,QAASsD,CAAC,EACvBjG,EAAO,OACP2C,EAAG,aAAa,SAAU,EAAE,EAE5BkD,GAAcI,EAId,KAAK,QAAQ,SAAW,KAAK,QAAQ,kBACrC,KAAK,QAAQ,iBAAiB,oBAAoBtD,CAAE,EAGxDN,EAAG,YAAYM,CAAE,EACjB+C,GACJ,CAGA,GAAIG,EAAaL,EAAgB,CAC7B,IAAMW,EAAczD,EAAQL,EAAI,oCAAoC,EACpE,GAAI8D,EAAY,OAAQ,CACpB,IAAMC,EAAUD,EAAYA,EAAY,OAAS,CAAC,EAClD3D,EAAgB4D,EAAS,OAAO,CACpC,CACJ,CAUA,GAPI,KAAK,QAAQ,QAAQ,QAAU,KAAK,QAAQ,YAC5C,KAAK,QAAQ,WAAW,iBAAiB/D,CAAE,EAG/CgD,GAAO,aAAahD,EAAIgD,EAAM,cAAc,oBAAoB,CAAC,EAG7DA,GAASA,EAAM,YAAcG,EAAgB,CAC7C,KAAK,IAAI,6BAA6BH,EAAM,WAAW,MAAMG,CAAc,EAAE,EAC7E,IAAMa,EAAiB,KAAK,YAAc,KAAK,YAC3CC,EAAOjB,EAAM,YAAcG,EAAiBa,EAC5C,KAAK,QAAQ,YAAc,KAAK,QAAQ,iBACxCC,GAAQD,GAGZ,IAAME,EAAc7D,EAAQL,EAAI,WAAW,EAE3C,QAAWM,KAAM4D,EAAa,CAI1B,GAHIC,EAAS7D,EAAI,kBAAkB,GAG/B2D,GAAQ,EACR,SAEJ,IAAMG,EAAc,OAAO,SAAS9D,EAAG,aAAa,OAAO,CAAC,EACtD+D,EAAW/D,EAAG,QAAQ,SAAW,OAAO,SAASA,EAAG,QAAQ,QAAQ,EAAI,EAC9E,GAAI8D,EAAcC,EAAU,CACxB,IAAIC,EAAWF,EAAcH,EACzBK,EAAWD,IACXC,EAAWD,GAEfJ,GAAQG,EAAcE,EACtB1G,EAAa0C,EAAI,QAASgE,CAAQ,CACtC,CACJ,CACJ,CAGI,KAAK,QAAQ,MAAQ,KAAK,QAAQ,aAClC,KAAK,QAAQ,YAAY,kBAAkB,EAI/C,IAAMC,EAAelE,EAAQL,EAAI,aAAa,EAC9C,QAAWwE,KAAeD,EACtBC,EAAY,iBAAiB,QAAS,IAAM,KAAK,SAASA,CAAW,CAAC,EAG1E,KAAK,OAAS5G,EAAa,KAAK,MAAO,gBAAiB,KAAK,cAAc,EAAI,CAAC,CACpF,CAEA,oBAAoBoF,EAAO,CACvB,IAAIK,EAAM,EACNrD,EAGJA,EAAKsD,EAAG,IAAI,EACZ,KAAK,UAAYtD,EACjBA,EAAG,aAAa,OAAQ,KAAK,EAC7BA,EAAG,aAAa,gBAAiB,GAAG,EACpCA,EAAG,aAAa,QAAS,iBAAiB,EACrC,KAAK,QAAQ,QACdA,EAAG,aAAa,SAAU,EAAE,EAG5B,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBACxC,KAAK,QAAQ,eAAe,gBAAgBA,CAAE,EAE9C,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBAAkB,KAAK,QAAQ,eAAe,iBAAiB,GACvG,KAAK,QAAQ,eAAe,gBAAgBA,CAAE,EAGlD,KAAK,IAAI,gCAAiC,KAAK,QAAQ,OAAO,EAC9D,QAAWrC,KAAU,KAAK,QAAQ,QAAS,CACvC,GAAIA,EAAO,KACP,SAEJ,IAAM8F,EAASJ,EAAM,KAAK,cAAc,EAClCoB,EAAYzB,GAAO,cAAc,wCAAwCS,CAAM,IAAI,EACzF,GAAI,CAACgB,EAAW,CACZ,QAAQ,KAAK,uBAAwBhB,CAAM,EAC3C,QACJ,CACA,IAAMnD,EAAKgD,EAAG,IAAI,EAClBhD,EAAG,aAAa,gBAAiB,GAAGmD,CAAM,EAAE,EAE5C,IAAMiB,EAAS,KAAK,oBAAoB/G,EAAQ8G,CAAS,EACpD,KAAK,QAAQ,OAGdC,EAAO,SAAW,EAFlBpE,EAAG,SAAW,EAKd3C,EAAO,QACP2C,EAAG,aAAa,SAAU,EAAE,EAGhCA,EAAG,YAAYoE,CAAM,EACrB1E,EAAG,YAAYM,CAAE,EACjB+C,GACJ,CAGI,KAAK,QAAQ,QAAQ,QAAU,KAAK,QAAQ,YAC5C,KAAK,QAAQ,WAAW,iBAAiBrD,CAAE,EAG/CgD,GAAO,aAAahD,EAAIgD,EAAM,cAAc,oBAAoB,CAAC,GAE7D,OAAO,KAAK,QAAQ,qBAAwB,UAAY,KAAK,QAAQ,iBACrE,KAAK,QAAQ,oBAAsB,GAGvC,IAAM2B,EAAetE,EAAQL,EAAI,KAAK,eAAe,EACrD,QAAWtC,KAAMiH,EAAc,CAC3B,IAAMC,EAAW,UAAU,KAAKlH,EAAG,OAAO,EACpCmH,EAAYD,EAAW,SAAW,QAClCE,EAAeC,EAAUC,GAAM,CACjC,IAAMnG,EAAMmG,EAAE,SAAWA,EAAE,IACrBC,EAAmB,CAAC,KAAK,QAAQ,eAAiB,CAAC,KAAK,cAAc,KAAMxE,GAAMA,IAAM5B,CAAG,GAC7FA,IAAQ,IAAMA,IAAQ,SAAWoG,GAAoBD,EAAE,OAAS,UAAYA,EAAE,OAAS,UACvF,KAAK,WAAW,KAAK,IAAI,CAEjC,EAAG,KAAK,QAAQ,mBAAmB,EACnCtH,EAAG,iBAAiBmH,EAAWC,CAAY,EACtCF,GACDlH,EAAG,iBAAiB,QAASoH,CAAY,CAEjD,CACJ,CAEA,oBAAoBnH,EAAQ8G,EAAW,CACnC,IAAMG,EAAWjH,EAAO,aAAe,SACjC+G,EAASE,EAAWtB,EAAG,QAAQ,EAAIA,EAAG,OAAO,EACnD,GAAIsB,EAAU,CACV,GAAI,CAAC,MAAM,QAAQjH,EAAO,UAAU,EAAG,CAEnC,IAAMuH,EAAe,CAAC,GAAG,IAAI,KAAK,KAAK,MAAQ,CAAC,GAAG,IAAKF,GAAMA,EAAErH,EAAO,KAAK,CAAC,CAAC,CAAC,EAC1E,OAAQW,GAAMA,CAAC,EACf,KAAK,EACVX,EAAO,WAAa,CAACA,EAAO,mBAAqB,KAAK,cAAc,iBAAiB,EAAE,OACnFuH,EAAa,IAAKF,IAAO,CAAE,MAAOA,EAAG,KAAMA,CAAE,EAAE,CACnD,CACJ,CAEA,QAAWA,KAAKrH,EAAO,WAAY,CAC/B,IAAMwH,EAAM7B,EAAG,QAAQ,EACvB6B,EAAI,MAAQH,EAAE,MACdG,EAAI,KAAOH,EAAE,KAETN,aAAkB,mBAClBA,EAAO,IAAIS,CAAG,CAEtB,CACJ,MAEIT,EAAO,KAAO,OACdA,EAAO,UAAY,SACnBA,EAAO,aAAe,MACtBA,EAAO,WAAa,GAGxB,OAAAA,EAAO,QAAQ,KAAO/G,EAAO,MAC7B+G,EAAO,GAAKzG,EAAQ,YAAY,EAEhCyG,EAAO,aAAa,kBAAmBD,EAAU,aAAa,IAAI,CAAC,EAC5DC,CACX,CAMA,YAAa,CACT,KAAK,IAAI,aAAa,EACtB,IAAI1E,EACAkD,EACAG,EACE7E,EAAQ8E,EAAG,OAAO,EAExB,KAAK,KAAK,QAAQ,CAACvE,EAAM2B,IAAM,CAC3BV,EAAKsD,EAAG,IAAI,EACZ1F,EAAaoC,EAAI,OAAQ,KAAK,EAC9BpC,EAAaoC,EAAI,SAAU,EAAE,EAC7BpC,EAAaoC,EAAI,gBAAiBU,EAAI,CAAC,EACvCV,EAAG,SAAW,EAEV,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBACxC,KAAK,QAAQ,eAAe,cAAcA,CAAE,EAG5C,KAAK,QAAQ,YACb,KAAK,QAAQ,gBACb,KAAK,QAAQ,eAAe,iBAAiB,GAE7C,KAAK,QAAQ,eAAe,cAAcA,CAAE,EAI5C,KAAK,QAAQ,SACbA,EAAG,UAAU,IAAI,eAAe,EAEhCoF,EAAGpF,EAAI,QAAUqF,GAAO,CAChBA,EAAG,OAAO,QAAQ,KAAK,2BAA2B,IAClD,KAAK,QAAQ,gBACb,KAAK,QAAQ,eAAe,cAAc,EAE9CC,GAAYD,EAAG,cAAe,aAAa,EACvC,KAAK,QAAQ,gBACb,KAAK,QAAQ,eAAe,gBAAgB,EAEpD,CAAC,GAGLhC,EAAM,EAEN,QAAW1F,KAAU,KAAK,QAAQ,QAAS,CAKvC,GAJKA,GACD,QAAQ,MAAM,sBAAuB,KAAK,QAAQ,OAAO,EAGzDA,EAAO,KAAM,CACToB,EAAKpB,EAAO,KAAK,IAEbA,EAAO,OAAS,QAChBE,EAASmC,EAAIjB,EAAKpB,EAAO,KAAK,CAAC,EAE/BqC,EAAG,aAAarC,EAAO,KAAMoB,EAAKpB,EAAO,KAAK,CAAC,GAGvD,MACJ,CAUA,GATAuF,EAAKI,EAAG,IAAI,EACZJ,EAAG,aAAa,OAAQ,UAAU,EAClCA,EAAG,aAAa,gBAAiB,GAAGG,CAAG,GAAG,KAAK,cAAc,CAAC,EAAE,EAChE5F,GAAsByF,EAAIvF,CAAM,EAEhCuF,EAAG,aAAa,YAAavF,EAAO,KAAK,EACzCuF,EAAG,SAAW,GAGVvF,EAAO,UAAY,KAAK,QAAQ,eAChCE,EAASqF,EAAI,iBAAiB,EAC9B,KAAK,QAAQ,eAAe,kBAAkBA,EAAIvF,EAAQoB,EAAM2B,CAAC,MAC9D,CAEH,IAAMpC,EAAIS,EAAKpB,EAAO,KAAK,GAAK,GAC5B4H,EAEJ,OAAQ5H,EAAO,UAAW,CACtB,IAAK,YACD4H,EAAKjH,EAAE,YAAY,EACnB,MACJ,IAAK,YACDiH,EAAKjH,EAAE,YAAY,EACnB,MACJ,QACIiH,EAAKjH,EACL,KACR,CACA,GAAIX,EAAO,QAKP,GAHIA,EAAO,qBAAuB,SAAc4H,IAAO,IAAMA,IAAO,QAChEA,EAAK,GAAG5H,EAAO,kBAAkB,IAEjC,OAAOA,EAAO,QAAW,UAAY4H,EACrCrC,EAAG,UAAYsC,EAEX7H,EAAO,OACP,OAAO,OACH,CACI,GAAIW,EACJ,IAAKiH,CACT,EACAxG,CACJ,CACJ,UACOpB,EAAO,kBAAkB,SAAU,CAC1C,IAAMuB,EAAMvB,EAAO,OAAO,KAAK,KAAM,CAAE,OAAAA,EAAQ,QAASoB,EAAM,SAAUwG,EAAI,GAAArC,EAAI,GAAAlD,CAAG,CAAC,EACpFkD,EAAG,UAAYhE,GAAOqG,GAAMjH,CAChC,OAEA4E,EAAG,YAAcqC,CAEzB,CACAvF,EAAG,YAAYkD,CAAE,EACjBG,GACJ,CAGI,KAAK,QAAQ,QAAQ,QAAU,KAAK,QAAQ,YAC5C,KAAK,QAAQ,WAAW,cAAcrD,EAAIjB,CAAI,EAGlDP,EAAM,YAAYwB,CAAE,EAEpBJ,EAAS,KAAM,cAAe,CAAE,QAASb,EAAM,GAAAiB,CAAG,CAAC,CACvD,CAAC,EAEDxB,EAAM,aAAa,OAAQ,UAAU,EAGrC,IAAMiH,EAAO,KAAK,MAClBA,GAAQjH,EAAM,aAAa,aAAciH,EAAK,aAAa,YAAY,CAAC,EACxE,KAAK,OAAO,aAAajH,EAAOiH,CAAI,EAEhC,KAAK,QAAQ,aACb,KAAK,QAAQ,YAAY,cAAc,EAG3C,KAAK,SAAS,EAEV,KAAK,QAAQ,gBACb,KAAK,QAAQ,eAAe,gBAAgBjH,CAAK,EAGrD,KAAK,UAAU,OAAO,WAAY,CAAC,KAAK,KAAK,MAAM,EAEnDoB,EAAS,KAAM,cAAc,CACjC,CAEA,UAAW,CACP,KAAK,IAAI,UAAU,EAEnB,IAAM8F,EAAQ,KAAK,aAAa,EAC1BC,EAAI,KAAK,MAAQ,EACjBnH,EAAQ,KAAK,MACbyE,EAAQ,KAAK,MACnB,GAAI,CAACzE,GAAS,CAACyE,EAAO,OACtB,IAAM2C,EAAWvF,EAAQ7B,EAAO,IAAI,EAGpC,KAAK,MAAQ,KAAK,WAAW,EAE7B,IAAIqH,EACAC,EAAOH,EAAI,KAAK,QAAQ,QACxBI,EAAMD,EAAO,KAAK,QAAQ,QAAU,EAEpCA,EAAOJ,IACPI,EAAOJ,GAENA,IACDK,EAAM,GAMV,QAAW/F,KAAM4F,EAAU,CACvB,GAAI,KAAK,QAAQ,OAAQ,CACrBzF,EAAgBH,EAAI,QAAQ,EAC5B,QACJ,CACA6F,EAAQ,OAAOG,EAAahG,EAAI,eAAe,CAAC,EAC5C6F,EAAQC,GAAQD,EAAQE,EACxBnI,EAAaoC,EAAI,SAAU,EAAE,EAE7BG,EAAgBH,EAAI,QAAQ,CAEpC,CAEI,KAAK,QAAQ,YAAc,KAAK,QAAQ,gBACxC,KAAK,QAAQ,eAAe,gBAAgBxB,CAAK,EAIjD,KAAK,QAAQ,aACb,KAAK,QAAQ,YAAY,cAAc,EAIvC,KAAK,WACL,KAAK,SAAS,SAAW,KAAK,MAAQ,EACtC,KAAK,QAAQ,SAAW,KAAK,MAAQ,EACrC,KAAK,QAAQ,SAAW,KAAK,MAAQ,KAAK,MAC1C,KAAK,QAAQ,SAAW,KAAK,MAAQ,KAAK,OAE9CyE,EAAM,cAAc,SAAS,EAAE,YAAc8C,EAAI,SAAS,EAC1D9C,EAAM,cAAc,UAAU,EAAE,YAAc6C,EAAK,SAAS,EAC5D7C,EAAM,cAAc,WAAW,EAAE,YAAc,GAAG,KAAK,aAAa,CAAC,GACrEA,EAAM,gBAAgB,SAAU,KAAK,QAAQ,eAAiB,KAAK,QAAQ,QAAU,KAAK,aAAa,CAAC,CAC5G,CAKA,YAAa,CACT,OAAO,KAAK,KAAK,KAAK,aAAa,EAAI,KAAK,QAAQ,OAAO,CAC/D,CAKA,cAAe,CACX,OAAI,KAAK,QAAQ,OACN,KAAK,OAAO,KAAK,QAAQ,aAAa,eAAe,GAAK,EAE9D,KAAK,KAAK,MACrB,CACJ,EAEOgD,EAAQnI,GC39Df,IAAMoI,GAAN,KAAiB,CAIb,YAAYC,EAAM,CACd,KAAK,KAAOA,CAChB,CAEA,WAAY,CAAC,CAEb,cAAe,CAAC,CAOhB,YAAYC,EAAO,CACX,KAAK,KAAKA,EAAM,IAAI,EAAE,GACtB,KAAK,KAAKA,EAAM,IAAI,EAAE,EAAEA,CAAK,CAErC,CACJ,EAEOC,EAAQH,GCRf,IAAMI,GAAN,cAA4BC,CAAW,CACnC,YAAYC,EAAM,CACd,MAAMA,CAAI,EACV,KAAK,WAAa,EACtB,CAKA,cAAcC,EAAa,CACvB,IAAMD,EAAO,KAAK,KACZE,EAAQF,EAAK,MACbG,EAAOC,EAAQJ,EAAM,6BAA6B,EAExD,QAAWK,KAAOF,EAAM,CACpB,GAAIG,EAASD,EAAK,kBAAkB,EAChC,SAGJ,IAAME,EAAU,SAAS,cAAc,KAAK,EAC5CC,EAASD,EAAS,YAAY,EAC9BA,EAAQ,UAAYN,EAGpBI,EAAI,YAAYE,CAAO,EAGvB,IAAIE,EAAS,EACTC,EAAS,EACTC,EAAiB,EACjBC,EAAM,EAEJC,EAAoBC,GAAM,CAC5B,GAAIA,EAAE,QAAUF,EACZ,OAEJ,IAAMG,EAAWL,GAAUI,EAAE,QAAUL,GACnCJ,EAAI,QAAQ,UAAYU,EAAW,OAAO,SAASV,EAAI,QAAQ,QAAQ,GACvEW,EAAaX,EAAK,QAASU,CAAQ,CAE3C,EAGME,EAAiB,IAAM,CACzBjB,EAAK,IAAI,gBAAgB,EAGzB,WAAW,IAAM,CACb,KAAK,WAAa,EACtB,EAAG,CAAC,EAEJkB,EAAYX,EAAS,mBAAmB,EACpCP,EAAK,QAAQ,UACbK,EAAI,UAAY,IAEpBA,EAAI,MAAM,SAAW,SAGrBc,EAAI,SAAU,YAAaN,CAAgB,EAC3CM,EAAI,SAAU,UAAWF,CAAc,EAEvCG,EAASpB,EAAM,gBAAiB,CAC5B,IAAKqB,EAAahB,EAAK,OAAO,EAC9B,MAAOgB,EAAahB,EAAK,OAAO,CACpC,CAAC,CACL,EAGAiB,EAAGf,EAAS,QAAUO,GAAM,CACxBA,EAAE,gBAAgB,CACtB,CAAC,EAEDQ,EAAGf,EAAS,YAAcO,GAAM,CAC5BA,EAAE,gBAAgB,EAElB,KAAK,WAAa,GAElB,IAAMS,EAAST,EAAE,OAEXU,EADcpB,EAAQJ,EAAM,oBAAoB,EACtB,OAAQK,GAC7B,CAACA,EAAI,aAAa,QAAQ,CACpC,EACKoB,EAAcD,EAAY,UAAWE,GAAWA,IAAWH,EAAO,UAAU,EAClFvB,EAAK,IAAI,eAAe,EAExBQ,EAASD,EAAS,mBAAmB,EAGrCoB,EAAgBtB,EAAK,WAAW,EAGhCA,EAAI,MAAM,SAAW,UAGrBE,EAAQ,MAAM,OAAS,GAAGL,EAAM,aAAe,CAAC,KAGhDO,EAASK,EAAE,QACXJ,EAASL,EAAI,YAEbM,GAAkBa,EAAY,OAASC,GAAe,GACtDb,EAAMgB,GAAcL,CAAM,EAAE,KAAOvB,EAAK,YAAcW,EAGtDK,EAAaX,EAAK,QAASK,CAAM,EACjC,QAASmB,EAAI,EAAGA,EAAIL,EAAY,OAAQK,IAChCA,EAAIJ,GACJE,EAAgBxB,EAAK0B,CAAC,EAAG,OAAO,EAKxCP,EAAG,SAAU,YAAaT,CAAgB,EAC1CS,EAAG,SAAU,UAAWL,CAAc,CAC1C,CAAC,CACL,CACJ,CACJ,EAEOa,GAAQhC,GCnIA,SAARiC,EAAkCC,EAAIC,EAAMC,EAAO,WAAY,CAClE,IAAIC,EAASH,EACb,KAAOG,EAAOD,CAAI,IAAMD,GACpBE,EAASA,EAAO,cAEpB,OAAOA,CACX,CCLA,IAAMC,GAAN,cAA0BC,CAAW,CACjC,WAAY,CAIR,KAAK,KAAO,KAAK,KAAK,cAAc,UAAU,CAClD,CACA,cAAe,CACP,KAAK,KAAK,WACVC,EAAI,KAAK,KAAK,UAAW,cAAe,IAAI,CAEpD,CAEA,mBAAoB,CAChB,IAAMC,EAAO,KAAK,KAClBC,EAAGD,EAAK,UAAW,cAAe,IAAI,CAC1C,CAEA,SAASE,EAAG,CACR,IAAMF,EAAO,KAAK,KACZG,EAAID,EAAE,OACNE,EAAQD,EAAE,QAAQ,KACxB,GAAIA,EAAE,QACFH,EAAK,WAAWI,CAAK,MAClB,CAEH,GAAIJ,EAAK,eAAe,EAAE,QAAU,EAAG,CAEnCG,EAAE,QAAU,GACZ,MACJ,CACAH,EAAK,WAAWI,CAAK,CACzB,CACAJ,EAAK,QAAQ,CACjB,CAEA,cAAcE,EAAG,CACbA,EAAE,eAAe,EACjB,IAAMG,EAASC,EAAiBJ,EAAE,OAAQ,OAAO,EAC3CK,EAAO,KAAK,KACZC,EAAOH,EAAO,sBAAsB,EACtCI,EAAIP,EAAE,QAAUM,EAAK,KACnBE,EAAIR,EAAE,QAAUM,EAAK,IAE3BD,EAAK,MAAM,IAAM,GAAGG,CAAC,KACrBH,EAAK,MAAM,KAAO,GAAGE,CAAC,KAEtBE,EAAgBJ,EAAM,QAAQ,EAC1BE,EAAI,IAAMD,EAAK,QACfC,GAAKF,EAAK,YACVA,EAAK,MAAM,KAAO,GAAGE,CAAC,MAG1B,IAAMG,EAAwBV,GAAM,CAC3BK,EAAK,SAASL,EAAE,MAAM,IACvBW,EAAaN,EAAM,SAAU,EAAE,EAC/BR,EAAI,SAAU,QAASa,CAAoB,EAEnD,EACAX,EAAG,SAAU,QAASW,CAAoB,CAC9C,CACA,YAAa,CACT,IAAMZ,EAAO,KAAK,KACZO,EAAO,KAAK,KAClB,KAAOA,EAAK,WACRA,EAAK,YAAYA,EAAK,SAAS,EAEnCA,EAAK,iBAAiB,SAAU,IAAI,EAEpC,QAAWO,KAAOd,EAAK,QAAQ,QAAS,CACpC,GAAIc,EAAI,KACJ,SAEJ,IAAMC,EAAK,SAAS,cAAc,IAAI,EAChCC,EAAQ,SAAS,cAAc,OAAO,EACtCC,EAAW,SAAS,cAAc,OAAO,EAC/CJ,EAAaI,EAAU,OAAQ,UAAU,EACzCJ,EAAaI,EAAU,YAAaH,EAAI,KAAK,EACxCA,EAAI,SACLG,EAAS,QAAU,IAEvB,IAAMC,EAAO,SAAS,eAAeJ,EAAI,KAAK,EAE9CE,EAAM,YAAYC,CAAQ,EAC1BD,EAAM,YAAYE,CAAI,EAEtBH,EAAG,YAAYC,CAAK,EACpBT,EAAK,YAAYQ,CAAE,CACvB,CACJ,CACJ,EAEOI,GAAQtB,GC5Ff,IAAMuB,GAAN,cAA+BC,CAAW,CAItC,oBAAoBC,EAAI,CACpB,IAAMC,EAAO,KAAK,KAClBD,EAAG,UAAY,GACfE,EAAGF,EAAI,YAAcG,GAAM,CACvB,GAAIF,EAAK,QAAQ,eAAe,YAAcE,EAAE,eAAgB,CAC5DA,EAAE,eAAe,EACjB,MACJ,CACAF,EAAK,IAAI,aAAa,EACtBE,EAAE,aAAa,cAAgB,OAC/BA,EAAE,aAAa,QAAQ,aAAcA,EAAE,OAAO,aAAa,eAAe,CAAC,CAC/E,CAAC,EACDD,EAAGF,EAAI,WAAaG,IACZA,EAAE,gBACFA,EAAE,eAAe,EAErBA,EAAE,aAAa,WAAa,OACrB,GACV,EACDD,EAAGF,EAAI,OAASG,GAAM,CACdA,EAAE,iBACFA,EAAE,gBAAgB,EAEtB,IAAMC,EAAID,EAAE,OACNE,EAASC,EAAiBF,EAAG,IAAI,EACjCG,EAAQ,OAAO,SAASJ,EAAE,aAAa,QAAQ,YAAY,CAAC,EAC5DK,EAAc,OAAO,SAASH,EAAO,aAAa,eAAe,CAAC,EAExE,GAAIE,IAAUC,EAAa,CACvBP,EAAK,IAAI,+BAA+B,EACxC,MACJ,CACAA,EAAK,IAAI,sBAAsBM,CAAK,OAAOC,CAAW,EAAE,EAExD,IAAMC,EAASR,EAAK,cAAc,EAC5BS,EAAMT,EAAK,QAAQ,QAAQM,EAAQE,CAAM,EAC/CR,EAAK,QAAQ,QAAQM,EAAQE,CAAM,EAAIR,EAAK,QAAQ,QAAQO,EAAcC,CAAM,EAChFR,EAAK,QAAQ,QAAQO,EAAcC,CAAM,EAAIC,EAE7C,IAAMC,EAAY,CAACC,EAAUC,IAAQ,CACjC,IAAMC,EAAWD,EAAI,WAAW,aAAa,eAAe,EACtDE,EAAMd,EAAK,cACb,GAAGW,CAAQ,sBAAsBE,CAAQ,sBAAsBN,CAAW,IAC9E,EACAQ,EAAaH,EAAK,gBAAiBL,CAAW,EAC9CQ,EAAaD,EAAK,gBAAiBR,CAAK,EACxC,IAAMU,EAAU,SAAS,cAAc,IAAI,EAC3CJ,EAAI,WAAW,aAAaI,EAASJ,CAAG,EACxCE,EAAI,WAAW,aAAaF,EAAKE,CAAG,EACpCE,EAAQ,WAAW,aAAaF,EAAKE,CAAO,CAChD,EAGA,QAAWJ,KAAOK,EAAQjB,EAAM,2BAA2BM,CAAK,IAAI,EAChEI,EAAU,QAASE,CAAG,EAE1B,QAAWA,KAAOK,EAAQjB,EAAM,2BAA2BM,CAAK,IAAI,EAChEI,EAAU,QAASE,CAAG,EAI1B,OAAAZ,EAAK,QAAQ,QAAUiB,EAAQjB,EAAM,oCAAoC,EAAE,IAAKD,GAC5EC,EAAK,QAAQ,QAAQ,KAAMkB,GAAMA,EAAE,QAAUC,EAAapB,EAAI,OAAO,CAAC,CAC1E,EAEAqB,EAASpB,EAAM,kBAAmB,CAC9B,IAAKS,EAAI,MACT,KAAMH,EACN,GAAIC,CACR,CAAC,EACM,EACX,CAAC,CACL,CACJ,EAEOc,GAAQxB,GCjFf,IAAMyB,GAAN,cAA2BC,CAAW,CAClC,YAAYC,EAAM,CACd,MAAMA,CAAI,EACV,KAAK,MAAQ,IACjB,CACA,WAAY,CACR,IAAMA,EAAO,KAAK,KAClBA,EAAK,iBAAiB,aAAc,KAAM,CAAE,QAAS,EAAK,CAAC,EAC3DA,EAAK,iBAAiB,YAAa,KAAM,CAAE,QAAS,EAAK,CAAC,CAC9D,CAEA,cAAe,CACX,IAAMA,EAAO,KAAK,KAClBA,EAAK,oBAAoB,aAAc,IAAI,EAC3CA,EAAK,oBAAoB,YAAa,IAAI,CAC9C,CAEA,aAAaC,EAAG,CACZ,KAAK,MAAQA,EAAE,QAAQ,CAAC,CAC5B,CAEA,YAAYA,EAAG,CACX,GAAI,CAAC,KAAK,MACN,OAEJ,IAAMD,EAAO,KAAK,KACZE,EAAQ,KAAK,MAAM,QAAUD,EAAE,QAAQ,CAAC,EAAE,QAC1CE,EAAQ,KAAK,MAAM,QAAUF,EAAE,QAAQ,CAAC,EAAE,QAE5C,KAAK,IAAIC,CAAK,EAAI,KAAK,IAAIC,CAAK,IAC5BD,EAAQ,EACRF,EAAK,QAAQ,EAEbA,EAAK,QAAQ,GAGrB,KAAK,MAAQ,IACjB,CACJ,EAEOI,GAAQN,GCzCf,IAAMO,EAAmB,gBACnBC,GAAmB,gBACnBC,GAAiB,mBAKjBC,GAAN,cAA6BC,CAAW,CACpCC,GAAc,WAAW,KAAK,YAAc,iBAAmB,EAAE,KAAKL,CAAgB,wBACtFM,GAAiB,UAAUN,CAAgB,SAE3C,cAAe,CACP,KAAK,WACL,KAAK,UAAU,oBAAoB,SAAU,IAAI,CAEzD,CAEA,IAAI,gBAAiB,CACjB,OAAO,KAAK,KAAK,QAAQ,YAC7B,CAEA,IAAI,aAAc,CACd,OAAO,KAAK,KAAK,QAAQ,iBAC7B,CASA,gBAAgBO,EAAM,CAClB,IAAMC,EAAO,KAAK,KACZC,EAAe,CAAC,EAEhBC,EAASC,EAAQH,EAAM,GAAG,KAAKF,EAAc,UAAU,EAE7D,QAAWM,KAAYF,EAAQ,CAC3B,IAAMG,EAAM,OAAO,SAASD,EAAS,QAAQ,EAAE,EACzCE,EAAON,EAAK,KAAKK,EAAM,CAAC,EAC9B,GAAI,CAACC,EAAM,CACP,QAAQ,KAAK,QAAQD,CAAG,YAAY,EACpC,QACJ,CACIN,EAAK,SAAW,EAChBE,EAAa,KAAKK,CAAI,EACfP,EAAK,SAAW,EACvBE,EAAa,KAAKK,EAAKP,EAAK,CAAC,CAAC,CAAC,EAE/BE,EAAa,KAAK,OAAO,YAAYF,EAAK,IAAIQ,GAAK,CAACA,EAAGD,EAAKC,CAAC,CAAC,CAAC,CAAC,CAAC,CAEzE,CACA,OAAO,KAAK,eAAiBN,EAAa,CAAC,GAAK,CAAC,EAAIA,CACzD,CAMA,gBAAgBO,EAAO,CAEnB,GAAI,CADS,KAAK,KACR,QAAQ,kBACd,OAEJ,IAAMN,EAASC,EAAQK,EAAO,eAAehB,CAAgB,QAAQ,EACrE,QAAWiB,KAASP,EAChBO,EAAM,QAAU,GACZ,KAAK,iBACLA,EAAM,QAAQ,QAAU,SAGhC,KAAK,UAAU,QAAU,EAC7B,CAEA,UAAW,CACP,OAAO,KAAK,KAAK,cAAc,EAAI,CACvC,CAKA,gBAAgBC,EAAI,CAChB,IAAMC,EAAK,SAAS,cAAc,IAAI,EACtCC,EAAaD,EAAI,QAAS,KAAK,EAC/BC,EAAaD,EAAI,OAAQ,qBAAqB,EAC9CC,EAAaD,EAAI,gBAAiB,KAAK,SAAS,CAAC,EACjDA,EAAG,UAAU,IAAQnB,EAAkB,mBAAoB,iBAAkB,EAC7EmB,EAAG,SAAW,EAEd,KAAK,UAAY,SAAS,cAAc,OAAO,EAC/C,KAAK,UAAU,KAAO,WACtB,KAAK,UAAU,UAAU,IAAIlB,EAAgB,EAC7C,KAAK,UAAU,UAAU,IAAIC,EAAc,EAC3C,KAAK,UAAU,iBAAiB,SAAU,IAAI,EAE9C,IAAMmB,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,OAAS,KAAK,eACpBA,EAAM,YAAY,KAAK,SAAS,EAEhCF,EAAG,YAAYE,CAAK,EAEpBF,EAAG,aAAa,QAAS,IAAI,EAC7BD,EAAG,YAAYC,CAAE,CACrB,CAKA,gBAAgBD,EAAI,CAChB,IAAMC,EAAK,SAAS,cAAc,IAAI,EACtCC,EAAaD,EAAI,OAAQ,qBAAqB,EAC9CC,EAAaD,EAAI,gBAAiB,KAAK,SAAS,CAAC,EACjDA,EAAG,UAAU,IAAInB,CAAgB,EACjCmB,EAAG,SAAW,EAEdD,EAAG,YAAYC,CAAE,CACrB,CAQA,gBAAgBH,EAAO,CACd,KAAK,YAIVA,EAAM,iBAAiB,SAAU,IAAI,EAErCA,EAAM,cAAc,IAAI,MAAM,QAAQ,CAAC,EAC3C,CAKA,cAAcE,EAAI,CAEd,IAAMI,EAAK,SAAS,cAAc,IAAI,EACtCF,EAAaE,EAAI,OAAQ,iBAAiB,EAC1CF,EAAaE,EAAI,gBAAiB,KAAK,SAAS,CAAC,EACjDA,EAAG,UAAU,IAAItB,CAAgB,EAGjC,IAAMiB,EAAQ,SAAS,cAAc,OAAO,EAE5CA,EAAM,QAAQ,GAAKC,EAAG,aAAa,eAAe,EAClDD,EAAM,KAAO,KAAK,eAAiB,QAAU,WAC7CA,EAAM,UAAU,IAAIf,EAAc,EAC9B,KAAK,iBACLe,EAAM,KAAO,gBACbA,EAAM,QAAQ,QAAU,SAI5B,IAAMI,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,UAAU,IAAI,mBAAmB,EAEvCA,EAAM,YAAYJ,CAAK,EACvBK,EAAG,YAAYD,CAAK,EAGpBA,EAAM,iBAAiB,QAAS,IAAI,EAEpCH,EAAG,YAAYI,CAAE,CACrB,CAKA,QAAQC,EAAG,CACP,GAAI,CAAC,KAAK,eAAgB,OAAOA,EAAE,gBAAgB,EAGnD,IAAMC,EAAKD,EAAE,OACTE,EAAYD,EAAG,QAAQ,UAAY,OACvCC,GAAaC,EAAG,GAAG,KAAKrB,GAAY,QAAQ,WAAY,OAAO,CAAC,GAAI,KAAK,IAAI,GAAG,QAAQsB,GAAK,CAErFA,EAAE,OAASH,EAAG,MAAQG,IAAMH,IAAIG,EAAE,QAAUA,EAAE,QAAQ,QAAU,GACxE,CAAC,EACDH,EAAG,QAAUA,EAAG,QAAQ,QAAUC,EAClC,CAACA,GAAa,KAAK,SAASF,CAAC,CACjC,CAMA,SAASA,EAAG,CACR,IAAMC,EAAKD,EAAE,OAAQf,EAAO,KAAK,KACjC,GAAIoB,EAASL,EAAE,OAAQtB,EAAgB,EACnCU,EAAQH,EAAM,KAAKF,EAAc,EAAE,QAAQuB,GAAM,EACzC,CAAC,KAAK,aAAeA,EAAG,eAAaA,EAAG,QAAU,KAAK,UAAU,QACzE,CAAC,UACML,EAAG,QAAQ,KAAKnB,EAAW,EAAG,CACrC,GAAI,CAACmB,EAAG,QAAQ,IAAIxB,CAAgB,EAAE,EAAG,OACzC,IAAM8B,EAAkBnB,EAAQH,EAAM,KAAKH,EAAW,EACtD,KAAK,UAAU,QAAUyB,EAAgB,MAAM,GAAK,EAAE,OAAO,CACjE,CACIN,EAAG,QAAQ,IAAIvB,EAAgB,IAAI,KAAKK,EAAc,EAAE,GACxDyB,EAASP,EAAI,eAAgB,CACzB,UAAWhB,EAAK,aAAa,CACjC,EAAG,EAAI,CAEf,CACJ,EAEOwB,GAAQ7B,GC7Mf,IAAM8B,GAAN,cAA0BC,CAAW,CACjC,YAAYC,EAAM,CACd,MAAMA,CAAI,EAEV,KAAK,eAAiB,GAElBA,EAAK,MAAM,SACXA,EAAK,MAAM,UAAY,OACvB,KAAK,eAAiB,GAE9B,CAIA,eAAgB,CAEZ,IAAMC,EADO,KAAK,KACC,cAAc,OAAO,EAClCC,EAAK,SAAS,cAAc,IAAI,EACtCC,EAAaD,EAAI,OAAQ,KAAK,EAC9BC,EAAaD,EAAI,SAAU,EAAE,EAC7BA,EAAG,UAAU,IAAI,aAAa,EAC9BA,EAAG,SAAW,EACdD,GAAO,YAAYC,CAAE,CACzB,CAEA,IAAI,SAAU,CACV,OAAO,KAAK,KAAK,cAAc,cAAc,CACjD,CAKA,eAAgB,CACZ,IAAMF,EAAO,KAAK,KACZI,EAAU,KAAK,QAarB,GAZI,CAACA,GAKDJ,EAAK,QAAQ,QAAUA,EAAK,aAAa,GAIzCA,EAAK,OAASA,EAAK,WAAW,GAG9B,CAACA,EAAK,QAAQ,WACd,OAGJ,IAAMK,EAAML,EAAK,QAAQ,QAAUA,EAAK,UAClCM,EAAcN,EAAK,iBAAiB,wBAAwB,EAAE,OAC9DO,EAAaD,EAAc,EAAID,EAAMC,EAAcN,EAAK,UAAYK,EACtEE,EAAa,GACbJ,EAAaC,EAAS,SAAUG,CAAU,EAC1CH,EAAQ,gBAAgB,QAAQ,GAEhCA,EAAQ,gBAAgB,QAAQ,CAExC,CACJ,EAEOI,GAAQV,GChEf,IAAMW,GAAN,cAA6BC,CAAW,CASpC,YAAYC,EAAIC,EAAQC,EAAKC,EAAK,CAC9B,IAAMC,EAAO,KAAK,KAClB,GAAIC,EAAaL,EAAI,OAAO,EACxB,OAAOM,EAAaN,EAAI,OAAO,EAEnC,GAAI,CAACI,EAAK,KAAK,OACX,OAEJ,IAAMG,EAAWH,EAAK,KAAK,CAAC,EACtBI,EAAUJ,EAAK,KAAKA,EAAK,KAAK,OAAS,CAAC,EAC1CK,EAAIF,EAASN,EAAO,KAAK,EAAIM,EAASN,EAAO,KAAK,EAAE,SAAS,EAAI,GAC/DS,EAAKF,EAAQP,EAAO,KAAK,EAAIO,EAAQP,EAAO,KAAK,EAAE,SAAS,EAAI,GAClES,EAAG,OAASD,EAAE,SACdA,EAAIC,GAER,IAAIC,EAAQ,EACZ,OAAIF,EAAE,QAAU,EACZE,EAAQT,EACDO,EAAE,OAAS,GAClBE,EAAQR,EAGRQ,EAAQC,EAAa,GAAGH,CAAC,OAAQT,CAAE,EAEnCW,EAAQR,IACRQ,EAAQR,GAERQ,EAAQT,IACRS,EAAQT,GAEZW,EAAab,EAAI,QAASW,CAAK,EACxBA,CACX,CACJ,EAEOG,GAAQhB,GCrCf,IAAMiB,EAAmB,gBAErBC,GAMJ,SAASC,GAAeC,EAAM,CAC1B,OAAOA,EAAK,KAAK,CAACC,EAAGC,IAAM,CACvB,IAAMC,EAAK,OAAO,SAASF,EAAE,QAAQ,UAAU,GAAK,EAEpD,OADW,OAAO,SAASC,EAAE,QAAQ,UAAU,GAAK,GACxCC,CAChB,CAAC,CACL,CAMA,IAAMC,GAAWC,EAAUC,GAAY,CACnC,QAAWC,KAASD,EAAS,CAKzB,IAAME,EAAOD,EAAM,OACbE,EAAQD,EAAK,MACnB,GAAIA,EAAK,QAAQ,eAAe,gBAC5B,OAGJ,IAAME,EAAiB,MAAM,QAAQH,EAAM,cAAc,EAAIA,EAAM,eAAe,CAAC,EAAIA,EAAM,eACvFI,EAAO,OAAO,SAASD,EAAe,UAAU,EAChDE,EAAaH,EAAM,YACnBI,EAAiBC,EAAQN,EAAK,UAAW,IAAI,EAAE,OAAO,CAACO,EAAQC,IAC1DD,EAASC,EAAG,YACpB,CAAC,EACEC,GAAQJ,GAAkBD,GAAcD,EAAO,EAC/CO,EAAW,GACXC,EAAaX,EAAK,QAAQ,eAAe,WAEzCY,EAAarB,GACfe,EAAQN,EAAK,UAAW,WAAW,EAC9B,QAAQ,EACR,OAAQa,GAEEA,EAAI,QAAQ,aAAe,GACrC,CACT,EACIC,EAAU,GAKd,GAHAd,EAAK,IAAI,YAAYI,CAAU,IAAIC,CAAc,0BAA0BF,CAAI,WAAWM,CAAI,EAAE,EAG5FA,EAAO,EAAG,CACV,GAAIE,IAAe,OACf,OAEJX,EAAK,QAAQ,eAAe,WAAa,OACzC,IAAIe,EAAYN,EACZO,EAAOJ,EAAW,OAAQC,GACnB,CAACA,EAAI,aAAa,QAAQ,GAAKA,EAAI,aAAa,iBAAiB,CAC3E,EACD,GAAIG,EAAK,SAAW,IAChBA,EAAOJ,EAAW,OAAQC,GACf,CAACA,EAAI,aAAa,QAAQ,CACpC,EAEGG,EAAK,SAAW,GAChB,OAIR,QAAWH,KAAOG,EAAM,CACpB,GAAID,EAAY,EACZ,SAGJ,IAAME,EAAWJ,EAAI,YACfK,EAAQL,EAAI,aAAa,OAAO,EACjCK,IAGLL,EAAI,QAAQ,UAAY,GAAGA,EAAI,WAAW,GAE1Cb,EAAK,WAAWkB,EAAO,EAAK,EAC5BlB,EAAK,WAAWkB,EAAO,mBAAoB,EAAI,EAC/CJ,EAAU,GAEVC,GAAaE,EACbF,EAAY,KAAK,MAAMA,CAAS,EACpC,CACJ,KAAO,CACH,GAAIJ,IAAe,OACf,OAEJX,EAAK,QAAQ,eAAe,WAAa,OAEzC,IAAMmB,EACFP,EACK,OAAQC,GACE,CAACA,EAAI,aAAa,QAAQ,CACpC,EACA,OAAO,CAACN,EAAQM,IAAQ,CACrB,IAAMO,EAAQP,EAAI,QAAQ,SAAW,OAAO,SAASA,EAAI,QAAQ,QAAQ,EAAIA,EAAI,YACjF,OAAON,EAASa,CACpB,EAAG,CAAC,EAAIV,EAGZK,EAAYZ,EAAOgB,EAEjBE,EAAqBT,EACtB,MAAM,EACN,QAAQ,EACR,OAAQC,GACEA,EAAI,aAAa,QAAQ,CACnC,EAEL,QAAWA,KAAOQ,EAAoB,CAClC,GAAIN,EAAYL,EACZ,SAEJ,IAAMO,EAAW,OAAO,SAASJ,EAAI,QAAQ,QAAQ,EAGrD,GAAII,EAAWF,EAAW,CACtBA,EAAY,GACZ,QACJ,CAEA,IAAMG,EAAQL,EAAI,aAAa,OAAO,EACjCK,IAILlB,EAAK,WAAWkB,EAAO,EAAK,EAC5BlB,EAAK,WAAWkB,EAAO,mBAAoB,EAAK,EAChDJ,EAAU,GAEVC,GAAaE,EACbF,EAAY,KAAK,MAAMA,CAAS,EACpC,CACJ,CAGA,IAAMO,EAASC,EAAKvB,EAAK,MAAO,OAAO,EACjCwB,EAAkBlB,EAAQN,EAAK,MAAO,kBAAkB,EAAE,OAAO,CAACO,EAAQkB,IACrElB,EAASkB,EAAI,YACrB,CAAC,EACEC,EAAuBJ,EAAO,YAAcE,EAC9CA,EAAkBrB,EAClBwB,EAASL,EAAQ,mBAAmB,EAC7BI,EAAuB,KAC9BE,EAAYN,EAAQ,mBAAmB,EAEvCR,GACAd,EAAK,YAAY,EAGrB,WAAW,IAAM,CACbA,EAAK,QAAQ,eAAe,WAAa,IAC7C,EAAG,GAAI,EACPA,EAAK,MAAM,MAAM,WAAa,SAClC,CACJ,EAAG,GAAG,EACA6B,GAAiB,IAAI,eAAejC,EAAQ,EAK5CkC,GAAN,cAA6BC,CAAW,CACpC,YAAY/B,EAAM,CACd,MAAMA,CAAI,EAEV,KAAK,gBAAkB,GACvB,KAAK,WAAa,IACtB,CAEA,WAAY,CACJ,KAAK,KAAK,QAAQ,YAClB,KAAK,QAAQ,CAErB,CAEA,cAAe,CACX,KAAK,UAAU,CACnB,CAEA,SAAU,CACD,KAAK,KAAK,QAAQ,aAGvB6B,GAAe,QAAQ,KAAK,IAAI,EAChC,KAAK,KAAK,MAAM,QAAU,QAC1B,KAAK,KAAK,MAAM,UAAY,SAChC,CAEA,WAAY,CACRA,GAAe,UAAU,KAAK,IAAI,EAClC,KAAK,KAAK,MAAM,QAAU,QAC1B,KAAK,KAAK,MAAM,UAAY,OAChC,CAEA,eAAgB,CACZ,KAAK,gBAAkB,GACnBvC,IACA,aAAaA,EAAK,CAE1B,CAEA,iBAAkB,CACdA,GAAQ,WAAW,IAAM,CACrB,KAAK,gBAAkB,EAC3B,EAAG,GAAG,CACV,CAKA,kBAAmB,CACf,IAAI0C,EAAO,GAEX,QAAWnB,KAAO,KAAK,KAAK,QAAQ,QAC5BA,EAAI,mBACJmB,EAAO,IAGf,OAAOA,CACX,CAEA,UAAW,CACP,OAAO,KAAK,KAAK,cAAc,EAAI,CACvC,CAKA,gBAAgBC,EAAI,CAChB,GAAI,CAAC,KAAK,KAAK,QAAQ,iBACnB,OAEJ,IAAMzB,EAAK0B,EAAG,KAAMD,CAAE,EACtBE,EAAa3B,EAAI,QAAS,KAAK,EAC/B2B,EAAa3B,EAAI,OAAQ,qBAAqB,EAC9C2B,EAAa3B,EAAI,gBAAiB,KAAK,SAAS,CAAC,EACjD2B,EAAa3B,EAAI,QAAS,IAAI,EAC9BA,EAAG,UAAU,IAAQ,GAAGnB,CAAgB,UAAW,mBAAoB,iBAAkB,EACzFmB,EAAG,SAAW,CAClB,CAKA,gBAAgByB,EAAI,CAChB,GAAI,CAAC,KAAK,KAAK,QAAQ,iBACnB,OAEJ,IAAMzB,EAAK0B,EAAG,KAAMD,CAAE,EACtBE,EAAa3B,EAAI,OAAQ,qBAAqB,EAC9C2B,EAAa3B,EAAI,gBAAiB,KAAK,SAAS,CAAC,EACjDA,EAAG,UAAU,IAAI,GAAGnB,CAAgB,SAAS,EAC7CmB,EAAG,SAAW,CAClB,CAKA,cAAcyB,EAAI,CACd,GAAI,CAAC,KAAK,KAAK,QAAQ,iBACnB,OAGJ,IAAMG,EAAK,SAAS,cAAc,IAAI,EACtCD,EAAaC,EAAI,OAAQ,iBAAiB,EAC1CD,EAAaC,EAAI,gBAAiB,KAAK,SAAS,CAAC,EACjDA,EAAG,UAAU,IAAI,GAAG/C,CAAgB,SAAS,EAG7C+C,EAAG,UAAY,8CAA8C/C,CAAgB;AAAA;AAAA;AAAA;AAAA,cAIvEA,CAAgB;AAAA;AAAA,cAGtB4C,EAAG,YAAYG,CAAE,EAEjBA,EAAG,iBAAiB,QAAS,IAAI,EACjCA,EAAG,iBAAiB,YAAa,IAAI,CACzC,CAEA,mBAAoB,CAChB,IAAIC,EAAa,EACbC,EAAgB,EACpB,KAAOD,EAAa,KAAK,CACrBC,IACA,IAAMC,EAAOhB,EAAK,KAAK,KAAM,sCAAsCe,CAAa,IAAI,EACpF,GAAIC,EACAF,GAAcE,EAAK,gBAEnB,MAER,CACA,OAAOF,CACX,CAKA,YAAYG,EAAI,CAEZA,EAAG,eAAe,CACtB,CAKA,QAAQA,EAAI,CAERA,EAAG,gBAAgB,EASnB,IAAMJ,EAAKI,EAAG,cACRP,EAAKG,EAAG,cACRK,EAAOlB,EAAKa,EAAI,IAAI/C,CAAgB,OAAO,EAC3CqD,EAAQnB,EAAKa,EAAI,IAAI/C,CAAgB,QAAQ,EAKnD,GAHA,KAAK,cAAc,EAEAsD,EAASV,EAAI,GAAG5C,CAAgB,WAAW,EAC9C,CACZuC,EAAYK,EAAI,GAAG5C,CAAgB,WAAW,EAC9CoD,EAAK,MAAM,QAAU,QACrBC,EAAM,MAAM,QAAU,OAGtB,IAAME,EAAWX,EAAG,mBACdY,EAAavC,EAAQsC,EAAU,IAAIvD,CAAgB,SAAS,EAElE,QAAWwB,KAAOgC,EAEdZ,EAAG,YAAYpB,CAAG,EAClBsB,EAAatB,EAAK,QAAQ,EAG9B+B,EAAS,cAAc,YAAYA,CAAQ,CAC/C,KAAO,CACHjB,EAASM,EAAI,GAAG5C,CAAgB,WAAW,EAC3CoD,EAAK,MAAM,QAAU,OACrBC,EAAM,MAAM,QAAU,QAGtB,IAAME,EAAWV,EAAG,IAAI,EACxBY,GAAYF,EAAUX,CAAE,EACxBN,EAASiB,EAAU,GAAGvD,CAAgB,YAAY,EAElD,IAAM0D,EAAab,EAAG,KAAMU,CAAQ,EACpCT,EAAaY,EAAY,UAAW,KAAK,KAAK,cAAc,EAAI,CAAC,EAEjE,IAAMC,EAAad,EAAG,QAASa,CAAU,EACzCpB,EAASqB,EAAY,GAAG3D,CAAgB,QAAQ,EAEhD,IAAMwD,EAAavC,EAAQ2B,EAAI,IAAI5C,CAAgB,SAAS,EACtDgD,EAAa,KAAK,kBAAkB,EAE1C,QAAWxB,KAAOgC,EAAY,CAC1B,IAAMI,EAAgBf,EAAG,KAAMc,CAAU,EAGnCE,EAAQrC,EAAI,QAAQ,KACpBsC,EAAWjB,EAAG,KAAMe,CAAa,EAEvCE,EAAS,MAAM,MAAQ,GAAGd,CAAU,KACpCc,EAAS,UAAYD,EAGrBD,EAAc,YAAYpC,CAAG,EAC7BuC,EAAgBvC,EAAK,QAAQ,CACjC,CACJ,CAEA,KAAK,gBAAgB,CACzB,CACJ,EAEOwC,GAAQvB,GC/Yf,IAAMwB,GAAN,cAAyBC,CAAW,CAIhC,YAAa,CACT,OAAO,KAAK,KAAK,QAAQ,QAAQ,OAAS,CAC9C,CAMA,iBAAiBC,EAAI,CACjB,IAAMC,EAAY,SAAS,cAAc,IAAI,EAC7CC,EAAaD,EAAW,OAAQ,qBAAqB,EACrDC,EAAaD,EAAW,gBAAiB,KAAK,KAAK,cAAc,EAAI,CAAC,EACtEA,EAAU,UAAU,IAAQ,aAAc,kBAAmB,mBAAoB,KAAK,WAAY,EAClGA,EAAU,SAAW,EACrBD,EAAG,YAAYC,CAAS,CAC5B,CAMA,iBAAiBD,EAAI,CACjB,IAAMC,EAAY,SAAS,cAAc,IAAI,EAC7CA,EAAU,aAAa,OAAQ,qBAAqB,EACpDC,EAAaD,EAAW,gBAAiB,KAAK,KAAK,cAAc,EAAI,CAAC,EACtEA,EAAU,UAAU,IAAQ,aAAc,KAAK,WAAY,EAC3DA,EAAU,SAAW,EACrBD,EAAG,YAAYC,CAAS,CAC5B,CAMA,cAAcD,EAAIG,EAAM,CACpB,IAAMC,EAAS,KAAK,KAAK,OACnBC,EAAK,SAAS,cAAc,IAAI,EACtCH,EAAaG,EAAI,OAAQ,UAAU,EACnCH,EAAaG,EAAI,gBAAiB,KAAK,KAAK,cAAc,EAAI,CAAC,EAC/DA,EAAG,UAAU,IAAQ,aAAc,KAAK,WAAY,EACpDA,EAAG,SAAW,EAGd,IAAMC,EAAgB,SAAS,cAAc,QAAQ,EACrDA,EAAc,UAAU,IAAI,mBAAmB,EAC/CA,EAAc,UAAY,SAC1BD,EAAG,YAAYC,CAAa,EAC5BC,EAAGD,EAAe,QAAUE,GAAO,CAC/BA,EAAG,gBAAgB,EACnBA,EAAG,OAAO,cAAc,UAAU,OAAO,mBAAmB,CAChE,CAAC,EAED,QAAWC,KAAU,KAAK,KAAK,QAAQ,QAAS,CAC5C,IAAMC,EAAS,SAAS,cAAc,QAAQ,EAC1CD,EAAO,KACPC,EAAO,UAAYD,EAAO,KAE1BC,EAAO,UAAYD,EAAO,OAASA,EAAO,KAE1CA,EAAO,QACPC,EAAO,MAAQD,EAAO,OAEtBA,EAAO,MACPC,EAAO,KAAO,SACdA,EAAO,WAAaC,EAAYF,EAAO,IAAKN,CAAI,GAEhDM,EAAO,OACPC,EAAO,UAAU,IAAI,GAAGD,EAAO,MAAM,MAAM,GAAG,CAAC,EAEnD,IAAMG,EAAiBJ,GAAO,CAE1B,GADAA,EAAG,gBAAgB,EACfC,EAAO,SAEH,CADM,QAAQL,EAAO,UAAU,EAC3B,CACJI,EAAG,eAAe,EAClB,MACJ,CAEJK,EAAS,KAAK,KAAM,SAAU,CAC1B,KAAMV,EACN,OAAQM,EAAO,IACnB,CAAC,CACL,EACAC,EAAO,iBAAiB,QAASE,CAAa,EAC9CP,EAAG,YAAYK,CAAM,EAGjBD,EAAO,UACPT,EAAG,UAAU,IAAI,eAAe,EAChCA,EAAG,iBAAiB,QAASY,CAAa,EAElD,CAEAZ,EAAG,YAAYK,CAAE,CACrB,CAEA,IAAI,aAAc,CACd,OAAI,KAAK,KAAK,QAAQ,QAAQ,OAAS,GAAK,CAAC,KAAK,KAAK,QAAQ,gBACpD,cAAc,KAAK,KAAK,QAAQ,QAAQ,MAAM,GAElD,iBACX,CACJ,EAEOS,GAAQhB,GC7Gf,IAAMiB,GAAN,cAA6BC,CAAW,CAQpC,kBAAkBC,EAAIC,EAAQC,EAAMC,EAAG,CACnC,IAAMC,EAAS,KAAK,KAAK,aAAa,IAAI,EACpCC,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,KAAOJ,EAAO,cAAgB,OAChCI,EAAM,OAAS,UACfA,EAAM,UAAY,SAElBA,EAAM,OAAS,YACfA,EAAM,KAAO,OACbA,EAAM,UAAY,WAEtBA,EAAM,aAAe,MACrBA,EAAM,WAAa,GACnBA,EAAM,SAAW,EACjBA,EAAM,UAAU,IAAI,aAAa,EACjCA,EAAM,KAAO,GAAGD,EAAO,QAAQ,IAAK,GAAG,CAAC,IAAID,EAAI,CAAC,KAAKF,EAAO,KAAK,IAClEI,EAAM,MAAQH,EAAKD,EAAO,KAAK,EAC/BI,EAAM,QAAQ,MAAQJ,EAAO,MAG7BI,EAAM,iBAAiB,QAAUC,GAAOA,EAAG,gBAAgB,CAAC,EAE5DD,EAAM,iBAAiB,WAAaC,GAAO,CACvC,GAAIA,EAAG,OAAS,WAAY,CACxB,IAAMC,EAAMD,EAAG,SAAWA,EAAG,KACzBC,IAAQ,IAAMA,IAAQ,WACtBF,EAAM,KAAK,EACXC,EAAG,eAAe,EAE1B,CACJ,CAAC,EAEDD,EAAM,iBAAiB,OAAQ,IAAM,CAE7BA,EAAM,QAAUH,EAAKG,EAAM,QAAQ,KAAK,IAI5CH,EAAKG,EAAM,QAAQ,KAAK,EAAIA,EAAM,MAElCG,EAAS,KAAK,KAAM,OAAQ,CACxB,KAAMN,EACN,MAAOG,EAAM,KACjB,CAAC,EACL,CAAC,EACDL,EAAG,YAAYK,CAAK,CACxB,CACJ,EAEOI,GAAQX,GCzDf,IAAMY,GAAN,cAA6BC,CAAW,CACpC,WAAY,CAEJ,KAAK,KAAK,QAAQ,cAAgB,KAAK,KAAK,QAAQ,gBACpD,KAAK,IAAI,CAEjB,CAKA,KAAM,CACF,IAAMC,EAAO,KAAK,KACZC,EAAUD,EAAK,QAAQ,aAC7B,GAAI,CAACC,EACD,OAEJ,IAAMC,EAAMD,EACP,MAAM,GAAG,EACT,IAAKE,GAAM,IAAIA,CAAC,EAAE,EAClB,KAAK,EAAE,EAENC,EAAW;AAAA;AAAA,cAEXF,CAAG;AAAA,+BACcA,CAAG;AAAA,8CACYA,CAAG;AAAA;AAAA,4BAErBA,CAAG;AAAA;AAAA;AAAA,EAIvB,GAAI,CAACG,EAAE,YAAY,EAAG,CAClB,IAAMC,EAAcD,EAAE,MAAM,GAAKA,EAAE,MAAM,EACnCE,EAAW,QAAQ,KAAKD,EAAY,OAAO,EAAI,YAAc,aACnEA,EAAY,mBAAmBC,EAAUH,CAAQ,CACrD,CACA,CAACC,EAAE,IAAIH,CAAG,GAAIF,CAAI,GAAKA,EAAK,mBAAmB,aAAc,aAAaC,CAAO,QAAQ,CAC7F,CACJ,EAEOO,GAAQV,GC/Bf,IAAMW,GAAN,cAAwBC,CAAW,CAC/B,YAAYC,EAAM,CACd,MAAMA,CAAI,EACV,KAAK,YAAc,KACnB,KAAK,gBAAkB,GACvB,KAAK,aAAe,GACpB,KAAK,WAAa,GAClB,KAAK,IAAI,MAAM,CACnB,CAEA,MAAM,WAAY,CACd,KAAK,IAAI,WAAW,EACpB,IAAMA,EAAO,KAAK,KAIlB,GAFA,KAAK,IAAIA,EAAK,OAAO,EAEjB,CAACA,EAAK,QAAQ,UAAW,CACzB,KAAK,IAAI,UAAU,EACnB,MACJ,CAEA,KAAK,IAAI,SAAS,EAElB,IAAMC,EAAc,KAAK,UAAU,EACnC,GAAIA,EAAa,CACb,IAAMC,EAAiB,SAAY,CAC/B,GAAI,CAACF,EAAK,QAAQ,OAAQ,OAC1B,IAAIG,EAAU,IACVC,EAAQ,KAAK,IAAI,EAAGC,EACxB,MAAQA,EAAY,CAACL,EAAK,QAAQ,SAAS,SAAW,KAAK,IAAI,EAAII,EAAQD,GACvE,MAAM,IAAI,QAAQG,GAAW,sBAAsBA,CAAO,CAAC,EAE/DD,GAAa,KAAK,IAAI,8BAA8B,CACxD,EAqBA,MApBqB,SAAY,CAC7B,MAAMH,EAAe,EAErB,KAAK,IAAI,cAAc,EAEvB,QAAWK,KAAON,EAAY,QAC1B,GAAIM,EAAI,OAAQ,CACZ,IAAMC,EAAUR,EAAK,QAAQ,QAAQ,KAAMS,GAAMA,EAAE,QAAUF,EAAI,KAAK,EACtEC,EAAQ,OAAS,EACrB,CAGJ,KAAK,IAAI,kBAAkB,EAC3BR,EAAK,QAAQ,QAAUC,EAAY,QAC/BD,EAAK,QAAQ,SACbA,EAAK,KAAOC,EAAY,KACxBD,EAAK,MAAQC,EAAY,MACzBD,EAAK,KAAOC,EAAY,KAEhC,GACmB,CACvB,CAEA,KAAK,YAAcA,EACnB,KAAK,IAAI,cAAe,KAAK,WAAW,EAExC,IAAMS,EAAaV,EAAK,SACxBA,EAAK,SAAW,YAAaW,EAAM,CAC/B,OAAOD,EAAW,MAAM,KAAMC,CAAI,EAAE,QAAQ,IAAM,CAC9C,IAAMC,EAAY,KAAK,QAAQ,UAG/B,GAFAA,EAAU,IAAI,WAAY,KAAK,QAAQ,OAAO,EAE1C,CAACZ,EAAK,UAAU,SAAS,gBAAgB,EAAG,CAC5CY,EAAU,IAAI,4BAA4B,EAC1C,MACJ,CAIA,GAFAA,EAAU,IAAI,wCAAyC,KAAK,QAAQ,OAAO,EAEvEA,EAAU,aAAe,CAACA,EAAU,gBAAiB,CACrDA,EAAU,IAAI,sBAAsB,EAEpC,IAAMC,EAAkBC,EAAQd,EAAM,wCAAwC,EAC9E,QAAWe,KAAMF,EACbE,EAAG,aAAa,YAAa,MAAM,EAGvCf,EAAK,cAAc,sCAAsCY,EAAU,YAAY,IAAI,IAAI,GACjF,aAAa,YAAaA,EAAU,YAAY,OAAO,EAE7D,IAAMI,EAAUF,EAAQd,EAAK,UAAW,iBAAiB,EACzDY,EAAU,IAAI,UAAWI,CAAO,EAEhC,QAAWD,KAAMC,EACbD,EAAG,MAAQH,GAAW,aAAa,UAAUG,EAAG,QAAQ,IAAI,GAAK,GACjEH,EAAU,IAAI,CAAE,KAAMG,EAAG,QAAQ,KAAM,IAAKA,EAAG,MAAO,UAAAH,CAAU,CAAC,EAErEA,EAAU,gBAAkB,EAChC,CAGA,IAAMK,EAAW,CACb,KAAMjB,EAAK,KACX,MAAOA,EAAK,MACZ,KAAMA,EAAK,KACX,QAASA,EAAK,QAAQ,QACtB,QAAS,CAAC,EACV,QAASA,EAAK,QAAQ,QAAQ,IAAKO,IAAS,CAAE,MAAOA,EAAI,MAAO,OAAQA,EAAI,MAAO,EAAE,EACrF,KAAMP,EAAK,QAAQ,EACnB,QAASA,EAAK,WAAW,EACzB,SAAU,OAAO,OACrB,EAEMgB,EAAUhB,EAAK,WAAW,EAChCY,EAAU,IAAI,UAAWI,CAAO,EAEhC,QAAWE,KAAO,OAAO,KAAKF,CAAO,EACjCC,EAAS,QAAQC,CAAG,EAAIF,EAAQE,CAAG,GAAK,GACxCN,EAAU,IAAI,CAAE,IAAAM,EAAK,IAAKF,EAAQE,CAAG,EAAG,SAAAD,EAAU,QAAAD,CAAQ,CAAC,EAG/DJ,EAAU,IAAI,kBAAmBK,CAAQ,EACzCL,EAAU,UAAUK,CAAQ,EAExB,CAACjB,EAAK,QAAQ,QAAUY,EAAU,aAAe,CAACA,EAAU,eAC5DA,EAAU,aAAe,GACzBZ,EAAK,WAAW,EAChBA,EAAK,KAAOY,EAAU,YAAY,KAClCZ,EAAK,YAAY,EACjBY,EAAU,IAAI,aAAa,EAEnC,CAAC,CACL,EAEA,IAAMO,EAAc,IAAM,CACtB,IAAMP,EAAYZ,EAAK,QAAQ,UACzBoB,EAAQR,EAAU,UAAU,EAC7BQ,IAGLA,EAAM,QAAUpB,EAAK,QAAQ,QAAQ,IAAKO,IAAS,CAAE,MAAOA,EAAI,MAAO,OAAQA,EAAI,MAAO,EAAE,EAC5Fa,EAAM,KAAOpB,EAAK,QAAQ,EAC1BoB,EAAM,QAAUpB,EAAK,WAAW,EAChCoB,EAAM,SAAW,OAAO,QACxBR,EAAU,UAAUQ,CAAK,EAC7B,EAEA,SAAS,iBAAiB,YAAaD,CAAW,EAClDnB,EAAK,iBAAiB,iBAAkBmB,CAAW,EAEnDnB,EAAK,iBAAiB,eAAiBqB,GAAO,CAC1C,GAAI,CAACrB,EAAK,UAAU,SAAS,gBAAgB,GAAKA,EAAK,UAAU,SAAS,YAAY,EAClF,OAGCA,EAAK,QAAQ,QACdmB,EAAY,EAGhB,IAAMP,EAAYZ,EAAK,QAAQ,UAC3B,CAACY,EAAU,aAAe,CAACA,EAAU,kBAIpCA,EAAU,aAIHA,EAAU,aAClBA,EAAU,WAAa,GACvB,OAAO,SAAS,CAAE,IAAKA,EAAU,YAAY,SAAU,KAAM,EAAG,SAAU,SAAU,CAAC,IALrFA,EAAU,aAAe,GACzBZ,EAAK,OAAO,EACZY,EAAU,IAAI,kBAAkB,GAKxC,CAAC,CACL,CAEA,OAAOU,EAAM,CACT,KAAK,KAAK,IAAI,gBAAiB,GAAGA,CAAI,CAC1C,CAKA,WAAY,CACR,IAAIF,EACJ,GAAI,CACAA,EAAQ,KAAK,MAAM,eAAe,QAAQ,iBAAiB,KAAK,KAAK,EAAE,EAAE,CAAC,CAC9E,MAAY,CAAC,CACb,OAAOA,CACX,CAKA,UAAUA,EAAO,CACb,eAAe,QAAQ,iBAAiB,KAAK,KAAK,EAAE,GAAI,KAAK,UAAUA,CAAK,CAAC,CACjF,CACJ,EAEOG,GAAQzB,GCxLf0B,EAAS,gBAAgB,CACvB,cAAAC,GACA,YAAAC,GACA,iBAAAC,GACA,aAAAC,GACA,eAAAC,GACA,YAAAC,GACA,eAAAC,GACA,eAAAC,GACA,WAAAC,GACA,eAAAC,GACA,eAAAC,GACA,UAAAC,EACF,CAAC,EAGI,eAAe,IAAI,WAAW,GACjC,eAAe,OAAO,YAAaZ,CAAQ,EAG7C,IAAOA,GAAQA,EAETa,GAAS,OAAO,WAAe,IAAc,WAAa,KAChEA,GAAO,SAAWb", + "names": ["camelize", "str", "m", "chr", "normalizeData", "v", "val", "supportedPassiveTypes", "passiveOpts", "type", "getAttribute", "el", "name", "hasAttribute", "setAttribute", "v", "check", "removeAttribute", "on", "listener", "off", "dispatch", "el", "name", "data", "bubbles", "opts", "hasClass", "addClass", "removeClass", "toggleClass", "$", "selector", "base", "$$", "find", "findAll", "ce", "tagName", "parent", "el", "insertAfter", "newNode", "existingNode", "BaseElement", "options", "opt", "v", "setAttribute", "jsonConfig", "data", "key", "normalizeData", "getAttribute", "event", "template", "dispatch", "attributeName", "oldValue", "newValue", "isOption", "transformer", "attr", "camelize", "base_element_default", "addSelectOption", "el", "value", "label", "checked", "opt", "appendParamsToUrl", "url", "params", "key", "k", "convertArray", "v", "bv", "elementOffset", "el", "rect", "scrollLeft", "scrollTop", "interpolate", "str", "data", "$1", "$2", "canvas", "getTextWidth", "text", "el", "withPadding", "styles", "fontWeight", "fontSize", "fontFamily", "padding", "paddingLeft", "paddingRight", "context", "metrics", "randstr", "prefix", "debounce", "handler", "timeout", "timer", "args", "plugins", "labels", "applyColumnDefinition", "el", "column", "setAttribute", "addClass", "DataGrid", "_DataGrid", "base_element_default", "randstr", "pluginName", "pluginClass", "attr", "camelize", "v", "#setNoData", "tbody", "list", "plugin", "columns", "cols", "key", "col", "item", "convertArray", "$", "val", "initOnly", "pv", "updatePage", "addSelectOption", "field", "found", "prop", "c", "render", "dispatch", "start", "visibleOnly", "len", "tr", "find", "row", "removeAttribute", "headers", "findAll", "th", "fieldName", "value", "k", "i", "keys", "force", "data", "metaKey", "dataKey", "callbackOrUrl", "needRender", "flagEmpty", "resolve", "response", "err", "event", "filters", "inputs", "input", "name", "baseCol", "haveClasses", "sort", "stack", "itemA", "itemB", "a", "b", "valA", "valB", "columnName", "sortDir", "dir", "reject", "base", "url", "params", "appendParamsToUrl", "newError", "error", "sortedColumn", "thead", "tfoot", "td", "availableWidth", "colMaxWidth", "idx", "ce", "sampleTh", "totalWidth", "colIdx", "computedWidth", "getTextWidth", "w", "colAvailableWidth", "visibleCols", "lastCol", "scrollbarWidth", "diff", "thWithWidth", "hasClass", "actualWidth", "minWidth", "newWidth", "rowsWithSort", "sortableRow", "relatedTh", "filter", "filteredRows", "isSelect", "eventName", "eventHandler", "debounce", "e", "isKeyPressFilter", "uniqueValues", "opt", "on", "ev", "toggleClass", "tv", "interpolate", "prev", "total", "p", "bodyRows", "index", "high", "low", "getAttribute", "data_grid_default", "BasePlugin", "grid", "event", "base_plugin_default", "ColumnResizer", "base_plugin_default", "grid", "resizeLabel", "table", "cols", "findAll", "col", "hasClass", "resizer", "addClass", "startX", "startW", "remainingSpace", "max", "mouseMoveHandler", "e", "newWidth", "setAttribute", "mouseUpHandler", "removeClass", "off", "dispatch", "getAttribute", "on", "target", "visibleCols", "columnIndex", "column", "removeAttribute", "elementOffset", "j", "column_resizer_default", "getParentElement", "el", "type", "prop", "parent", "ContextMenu", "base_plugin_default", "off", "grid", "on", "e", "t", "field", "target", "getParentElement", "menu", "rect", "x", "y", "removeAttribute", "documentClickHandler", "setAttribute", "col", "li", "label", "checkbox", "text", "context_menu_default", "DraggableHeaders", "base_plugin_default", "th", "grid", "on", "e", "t", "target", "getParentElement", "index", "targetIndex", "offset", "tmp", "swapNodes", "selector", "el1", "rowIndex", "el2", "setAttribute", "newNode", "findAll", "c", "getAttribute", "dispatch", "draggable_headers_default", "TouchSupport", "base_plugin_default", "grid", "e", "xDiff", "yDiff", "touch_support_default", "SELECTABLE_CLASS", "SELECT_ALL_CLASS", "CHECKBOX_CLASS", "SelectableRows", "base_plugin_default", "#cbSelector", "#inputSelector", "keys", "grid", "selectedData", "inputs", "findAll", "checkbox", "idx", "item", "k", "tbody", "input", "tr", "th", "setAttribute", "label", "td", "e", "el", "unchecked", "$$", "r", "hasClass", "cb", "totalCheckboxes", "dispatch", "selectable_rows_default", "FixedHeight", "base_plugin_default", "grid", "tbody", "tr", "setAttribute", "fakeRow", "max", "visibleRows", "fakeHeight", "fixed_height_default", "AutosizeColumn", "base_plugin_default", "th", "column", "min", "max", "grid", "hasAttribute", "getAttribute", "firstVal", "lastVal", "v", "v2", "width", "getTextWidth", "setAttribute", "autosize_column_default", "RESPONSIVE_CLASS", "obsTo", "sortByPriority", "list", "a", "b", "v1", "callback", "debounce", "entries", "entry", "grid", "table", "contentBoxSize", "size", "tableWidth", "realTableWidth", "findAll", "result", "th", "diff", "minWidth", "prevAction", "headerCols", "col", "changed", "remaining", "cols", "colWidth", "field", "requiredWidth", "width", "filteredHeaderCols", "footer", "find", "realFooterWidth", "div", "availableFooterWidth", "addClass", "removeClass", "resizeObserver", "ResponsiveGrid", "base_plugin_default", "flag", "tr", "ce", "setAttribute", "td", "idealWidth", "consideredCol", "hCol", "ev", "open", "close", "hasClass", "childRow", "hiddenCols", "insertAfter", "childRowTd", "childTable", "childTableRow", "label", "labelCol", "removeAttribute", "responsive_grid_default", "RowActions", "base_plugin_default", "tr", "actionsTh", "setAttribute", "item", "labels", "td", "actionsToggle", "on", "ev", "action", "button", "interpolate", "actionHandler", "dispatch", "row_actions_default", "EditableColumn", "base_plugin_default", "td", "column", "item", "i", "gridId", "input", "ev", "key", "dispatch", "editable_column_default", "SpinnerSupport", "base_plugin_default", "grid", "classes", "cls", "e", "template", "$", "styleParent", "position", "spinner_support_default", "SaveState", "base_plugin_default", "grid", "cachedState", "waitForColumns", "timeout", "start", "colAbsent", "resolve", "col", "hideCol", "c", "dgLoadData", "args", "saveState", "sortableHeaders", "findAll", "el", "filters", "newState", "key", "updateState", "state", "ev", "data", "save_state_default", "data_grid_default", "column_resizer_default", "context_menu_default", "draggable_headers_default", "touch_support_default", "selectable_rows_default", "fixed_height_default", "autosize_column_default", "responsive_grid_default", "row_actions_default", "editable_column_default", "spinner_support_default", "save_state_default", "global"] } diff --git a/src/data-grid.js b/src/data-grid.js index 18fb51d..97b0cc1 100644 --- a/src/data-grid.js +++ b/src/data-grid.js @@ -1,1029 +1,1029 @@ -/** - * Data Grid Web component - * - * Credits for inspiration - * @link https://github.com/riverside/zino-grid - */ - -import BaseElement from "./core/base-element.js"; -import addSelectOption from "./utils/addSelectOption.js"; -import appendParamsToUrl from "./utils/appendParamsToUrl.js"; -import camelize from "./utils/camelize.js"; -import convertArray from "./utils/convertArray.js"; -import elementOffset from "./utils/elementOffset.js"; -import interpolate from "./utils/interpolate.js"; -import getTextWidth from "./utils/getTextWidth.js"; -import randstr from "./utils/randstr.js"; -import debounce from "./utils/debounce.js"; -import { - $, - $$, - dispatch, - find, - findAll, - hasClass, - removeAttribute, - getAttribute, - setAttribute, - addClass, - toggleClass, - on, - ce, -} from "./utils/shortcuts.js"; - -/** - * Column definition - * @typedef Column - * @property {String} field - the key in the data - * @property {String} title - the title to display in the header (defaults to "field" if not set) - * @property {Number} [width] - the width of the column (auto otherwise) - * @property {String} [class] - class to set on the column (target body or header with th.class or td.class) - * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field - * @property {Boolean} [hidden] - hide the column - * @property {Boolean} [noSort] - allow disabling sort for a given column - * @property {String | Function} [format] - custom data formatting - * @property {String} [defaultFormatValue] - default value to use for formatting - * @property {String} [transform] - custom value transformation - * @property {Boolean} [editable] - replace with input (EditableColumn module) - * @property {String} [editableType] - type of input (EditableColumn module) - * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module) - * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module) - * @property {String} [filterType] - defines a filter field type ("text" or "select" - defaults to "text") - * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: "", text: ""},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records. - * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: "", text: ""} - */ - -/** - * Row action - * @typedef Action - * @property {String} title - the title of the button - * @property {String} name - the name of the action - * @property {String} class - the class for the button - * @property {String} url - link for the action - * @property {String} html - custom button data - * @property {Boolean} [confirm] - needs confirmation - * @property {Boolean} default - is the default row action - */ - -// Import definitions without importing the actual file -/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */ -/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */ -/** @typedef {import('./plugins/context-menu').default} ContextMenu */ -/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */ -/** @typedef {import('./plugins/editable-column').default} EditableColumn */ -/** @typedef {import('./plugins/fixed-height').default} FixedHeight */ -/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */ -/** @typedef {import('./plugins/row-actions').default} RowActions */ -/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */ -/** @typedef {import('./plugins/touch-support').default} TouchSupport */ -/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */ -/** @typedef {import('./plugins/save-state').default} SaveState */ - -/** - * These plugins are all optional - * @typedef {Object} Plugins - * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers - * @property {ContextMenu} [ContextMenu] menu to show/hide columns - * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns - * @property {EditableColumn} [EditableColumn] draggable headers columns - * @property {TouchSupport} [TouchSupport] touch swipe - * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows - * @property {FixedHeight} [FixedHeight] allows having fixed height tables - * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content - * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly - * @property {RowActions} [RowActions] add action on rows - * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading. - * @property {SaveState} [SaveState] stores grid filter, sort, and paging. - */ - -/** - * Parameters to pass along or receive from the server - * @typedef ServerParams - * @property {String} serverParams.start - * @property {String} serverParams.length - * @property {String} serverParams.search - * @property {String} serverParams.sort - * @property {String} serverParams.sortDir - * @property {String} serverParams.dataKey - * @property {String} serverParams.metaKey - * @property {String} serverParams.metaTotalKey - * @property {String} serverParams.metaFilteredKey - * @property {String} serverParams.optionsKey - * @property {String} serverParams.paramsKey - */ - -/** - * Available data grid options, plugins included - * @typedef Options - * @property {?String} id Custom id for the grid - * @property {?String} url An URL with data to display in JSON format - * @property {Boolean} debug Log actions in DevTools console - * @property {Boolean} filter Allows a filtering functionality - * @property {Boolean} sort Allows a sort by column functionality - * @property {String} defaultSort Default sort field if sorting is enabled - * @property {Boolean} server Is a server side powered grid - * @property {ServerParams} serverParams Describe keys passed to the server backend - * @property {String} dir Dir - * @property {Array} perPageValues Available per page options - * @property {Boolean} hidePerPage Hides the page size select element - * @property {Column[]} columns Available columns - * @property {Number} defaultPage Starting page - * @property {Number} perPage Number of records displayed per page (page size) - * @property {Boolean} expand Allow cell content to spawn over multiple lines - * @property {Action[]} actions Row actions (RowActions module) - * @property {Boolean} collapseActions Group actions (RowActions module) - * @property {Boolean} resizable Make columns resizable (ColumnResizer module) - * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module) - * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module) - * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module) - * @property {Boolean} autosize Compute column sizes based on given data (Autosize module) - * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module) - * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size - * @property {Boolean} menu Right click menu on column headers (ContextMenu module) - * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module) - * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module) - * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module) - * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key - * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner) - * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation. - * @property {Boolean} saveState Enable/disable save state plugin (SaveState module) - * @property {?String} errorMessage A generic text to be displayed in footer when error occurs. - * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component. - */ - -/** - * Available labels that can be translated - * @typedef Labels - * @property {String} itemsPerPage - * @property {String} gotoPage - * @property {String} gotoFirstPage - * @property {String} gotoPrevPage - * @property {String} gotoNextPage - * @property {String} gotoLastPage - * @property {String} of - * @property {String} items - * @property {String} resizeColumn - * @property {String} noData - * @property {String} areYouSure - * @property {String} networkError - */ - -/** - * List of registered plugins - * @type {Plugins} - */ -let plugins = {}; - -/** - * @type {Labels} - */ -let labels = { - itemsPerPage: "Items per page", - gotoPage: "Go to page", - gotoFirstPage: "Go to first page", - gotoPrevPage: "Go to previous page", - gotoNextPage: "Go to next page", - gotoLastPage: "Go to last page", - of: "of", - items: "items", - resizeColumn: "Resize column", - noData: "No data", - areYouSure: "Are you sure?", - networkError: "Network response error", -}; - -/** - * Column definition will update some props on the html element - * @param {HTMLElement} el - * @param {Column} column - */ -function applyColumnDefinition(el, column) { - if (column.width) { - setAttribute(el, "width", column.width); - } - if (column.class) { - addClass(el, column.class); - } - if (column.hidden) { - setAttribute(el, "hidden", ""); - if (column.responsiveHidden) { - addClass(el, "dg-responsive-hidden"); - } - } -} - -/** - */ -class DataGrid extends BaseElement { +/** + * Data Grid Web component + * + * Credits for inspiration + * @link https://github.com/riverside/zino-grid + */ + +import BaseElement from "./core/base-element.js"; +import addSelectOption from "./utils/addSelectOption.js"; +import appendParamsToUrl from "./utils/appendParamsToUrl.js"; +import camelize from "./utils/camelize.js"; +import convertArray from "./utils/convertArray.js"; +import elementOffset from "./utils/elementOffset.js"; +import interpolate from "./utils/interpolate.js"; +import getTextWidth from "./utils/getTextWidth.js"; +import randstr from "./utils/randstr.js"; +import debounce from "./utils/debounce.js"; +import { + $, + $$, + dispatch, + find, + findAll, + hasClass, + removeAttribute, + getAttribute, + setAttribute, + addClass, + toggleClass, + on, + ce, +} from "./utils/shortcuts.js"; + +/** + * Column definition + * @typedef Column + * @property {String} field - the key in the data + * @property {String} title - the title to display in the header (defaults to "field" if not set) + * @property {Number} [width] - the width of the column (auto otherwise) + * @property {String} [class] - class to set on the column (target body or header with th.class or td.class) + * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field + * @property {Boolean} [hidden] - hide the column + * @property {Boolean} [noSort] - allow disabling sort for a given column + * @property {String | Function} [format] - custom data formatting + * @property {String} [defaultFormatValue] - default value to use for formatting + * @property {String} [transform] - custom value transformation + * @property {Boolean} [editable] - replace with input (EditableColumn module) + * @property {String} [editableType] - type of input (EditableColumn module) + * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module) + * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module) + * @property {String} [filterType] - defines a filter field type ("text" or "select" - defaults to "text") + * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: "", text: ""},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records. + * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: "", text: ""} + */ + +/** + * Row action + * @typedef Action + * @property {String} title - the title of the button + * @property {String} name - the name of the action + * @property {String} class - the class for the button + * @property {String} url - link for the action + * @property {String} html - custom button data + * @property {Boolean} [confirm] - needs confirmation + * @property {Boolean} default - is the default row action + */ + +// Import definitions without importing the actual file +/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */ +/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */ +/** @typedef {import('./plugins/context-menu').default} ContextMenu */ +/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */ +/** @typedef {import('./plugins/editable-column').default} EditableColumn */ +/** @typedef {import('./plugins/fixed-height').default} FixedHeight */ +/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */ +/** @typedef {import('./plugins/row-actions').default} RowActions */ +/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */ +/** @typedef {import('./plugins/touch-support').default} TouchSupport */ +/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */ +/** @typedef {import('./plugins/save-state').default} SaveState */ + +/** + * These plugins are all optional + * @typedef {Object} Plugins + * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers + * @property {ContextMenu} [ContextMenu] menu to show/hide columns + * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns + * @property {EditableColumn} [EditableColumn] draggable headers columns + * @property {TouchSupport} [TouchSupport] touch swipe + * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows + * @property {FixedHeight} [FixedHeight] allows having fixed height tables + * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content + * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly + * @property {RowActions} [RowActions] add action on rows + * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading. + * @property {SaveState} [SaveState] stores grid filter, sort, and paging. + */ + +/** + * Parameters to pass along or receive from the server + * @typedef ServerParams + * @property {String} serverParams.start + * @property {String} serverParams.length + * @property {String} serverParams.search + * @property {String} serverParams.sort + * @property {String} serverParams.sortDir + * @property {String} serverParams.dataKey + * @property {String} serverParams.metaKey + * @property {String} serverParams.metaTotalKey + * @property {String} serverParams.metaFilteredKey + * @property {String} serverParams.optionsKey + * @property {String} serverParams.paramsKey + */ + +/** + * Available data grid options, plugins included + * @typedef Options + * @property {?String} id Custom id for the grid + * @property {?String} url An URL with data to display in JSON format + * @property {Boolean} debug Log actions in DevTools console + * @property {Boolean} filter Allows a filtering functionality + * @property {Boolean} sort Allows a sort by column functionality + * @property {String} defaultSort Default sort field if sorting is enabled + * @property {Boolean} server Is a server side powered grid + * @property {ServerParams} serverParams Describe keys passed to the server backend + * @property {String} dir Dir + * @property {Array} perPageValues Available per page options + * @property {Boolean} hidePerPage Hides the page size select element + * @property {Column[]} columns Available columns + * @property {Number} defaultPage Starting page + * @property {Number} perPage Number of records displayed per page (page size) + * @property {Boolean} expand Allow cell content to spawn over multiple lines + * @property {Action[]} actions Row actions (RowActions module) + * @property {Boolean} collapseActions Group actions (RowActions module) + * @property {Boolean} resizable Make columns resizable (ColumnResizer module) + * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module) + * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module) + * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module) + * @property {Boolean} autosize Compute column sizes based on given data (Autosize module) + * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module) + * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size + * @property {Boolean} menu Right click menu on column headers (ContextMenu module) + * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module) + * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module) + * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module) + * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key + * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner) + * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation. + * @property {Boolean} saveState Enable/disable save state plugin (SaveState module) + * @property {?String} errorMessage A generic text to be displayed in footer when error occurs. + * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component. + */ + +/** + * Available labels that can be translated + * @typedef Labels + * @property {String} itemsPerPage + * @property {String} gotoPage + * @property {String} gotoFirstPage + * @property {String} gotoPrevPage + * @property {String} gotoNextPage + * @property {String} gotoLastPage + * @property {String} of + * @property {String} items + * @property {String} resizeColumn + * @property {String} noData + * @property {String} areYouSure + * @property {String} networkError + */ + +/** + * List of registered plugins + * @type {Plugins} + */ +let plugins = {}; + +/** + * @type {Labels} + */ +let labels = { + itemsPerPage: "Items per page", + gotoPage: "Go to page", + gotoFirstPage: "Go to first page", + gotoPrevPage: "Go to previous page", + gotoNextPage: "Go to next page", + gotoLastPage: "Go to last page", + of: "of", + items: "items", + resizeColumn: "Resize column", + noData: "No data", + areYouSure: "Are you sure?", + networkError: "Network response error", +}; + +/** + * Column definition will update some props on the html element + * @param {HTMLElement} el + * @param {Column} column + */ +function applyColumnDefinition(el, column) { + if (column.width) { + setAttribute(el, "width", column.width); + } + if (column.class) { + addClass(el, column.class); + } + if (column.hidden) { + setAttribute(el, "hidden", ""); + if (column.responsiveHidden) { + addClass(el, "dg-responsive-hidden"); + } + } +} + +/** + */ +class DataGrid extends BaseElement { _filterSelector = "[id^=dg-filter]"; - _excludedRowElementSelector = "a,button,input,select,textarea"; - _excludedKeys = [ - 37, - 39, - 38, - 40, - 45, - 36, - 35, - 33, - 34, - 27, - 20, - 16, - 17, - 91, - 92, - 18, - 93, - 144, - 231, - "ArrowLeft", - "ArrowRight", - "ArrowUp", - "ArrowDown", - "Insert", - "Home", - "End", - "PageUp", - "PageDown", - "Escape", - "CapsLock", - "Shift", - "Control", - "Meta", - "Alt", - "ContextMenu", - "NumLock", - "Unidentified", + _excludedRowElementSelector = "a,button,input,select,textarea"; + _excludedKeys = [ + 37, + 39, + 38, + 40, + 45, + 36, + 35, + 33, + 34, + 27, + 20, + 16, + 17, + 91, + 92, + 18, + 93, + 144, + 231, + "ArrowLeft", + "ArrowRight", + "ArrowUp", + "ArrowDown", + "Insert", + "Home", + "End", + "PageUp", + "PageDown", + "Escape", + "CapsLock", + "Shift", + "Control", + "Meta", + "Alt", + "ContextMenu", + "NumLock", + "Unidentified", ]; - - _ready() { - setAttribute(this, "id", this.options.id ?? randstr("el-"), true); - - /** - * The grid displays that data - * @type {Array} - */ - this.data = []; - /** - * We store the original data in this - * @type {Array} - */ - this.originalData; // declared uninitialized to allow data preloading before fetch. - - // Make the IDE happy - /** - * @type {Options} - */ + + _ready() { + setAttribute(this, "id", this.options.id ?? randstr("el-"), true); + + /** + * The grid displays that data + * @type {Array} + */ + this.data = []; + /** + * We store the original data in this + * @type {Array} + */ + this.originalData; // declared uninitialized to allow data preloading before fetch. + + // Make the IDE happy + /** + * @type {Options} + */ this.options = this.options || this.defaultOptions; - if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable - - // Init values - this.fireEvents = false; - this.page = this.options.defaultPage || 1; - this.pages = 0; - this.meta; // declared uninitialized to allow data preloading before fetch. - /** - * @type {Plugins} - */ - this.plugins = {}; - // Init plugins - for (const [pluginName, pluginClass] of Object.entries(plugins)) { - // @ts-ignore until we can set typeof import ... - this.plugins[pluginName] = new pluginClass(this); - } - - // Expose options as observed attributes in the dom - // Do it when fireEvents is disabled to avoid firing change callbacks - for (const attr of DataGrid.observedAttributes) { - if (attr.indexOf("data-") === 0) { - setAttribute(this, attr, this.options[camelize(attr.slice(5))]); - } - } - } - - static template() { - return ` - - - - - - - - - - - - -
-`; - } - - /** - * @returns {Labels} - */ - get labels() { - return labels; - } - - /** - * @returns {Labels} - */ - static getLabels() { - return labels; - } - - /** - * @param {Object} v - */ - static setLabels(v) { - labels = Object.assign(labels, v); - } - + if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable + + // Init values + this.fireEvents = false; + this.page = this.options.defaultPage || 1; + this.pages = 0; + this.meta; // declared uninitialized to allow data preloading before fetch. + /** + * @type {Plugins} + */ + this.plugins = {}; + // Init plugins + for (const [pluginName, pluginClass] of Object.entries(plugins)) { + // @ts-ignore until we can set typeof import ... + this.plugins[pluginName] = new pluginClass(this); + } + + // Expose options as observed attributes in the dom + // Do it when fireEvents is disabled to avoid firing change callbacks + for (const attr of DataGrid.observedAttributes) { + if (attr.indexOf("data-") === 0) { + setAttribute(this, attr, this.options[camelize(attr.slice(5))]); + } + } + } + + static template() { + return ` + + + + + + + + + + + + +
+`; + } + + /** + * @returns {Labels} + */ + get labels() { + return labels; + } + + /** + * @returns {Labels} + */ + static getLabels() { + return labels; + } + + /** + * @param {Object} v + */ + static setLabels(v) { + labels = Object.assign(labels, v); + } + /** Gets the text to be displayed when no data is loaded. */ get noData() { - return this.options.noData || this.labels.noData; + return this.options.noData || this.labels.noData; } - /** - * @param {HTMLTableSectionElement} tbody + /** + * @param {HTMLTableSectionElement} tbody */ #setNoData(tbody) { - if (!this.hasDataError && tbody.getAttribute("data-empty") !== this.noData) { - tbody.setAttribute("data-empty", this.noData); - } - } - - /** - * @returns {Column} - */ - get defaultColumn() { - return { - field: "", - title: "", - width: 0, - class: "", - attr: "", - hidden: false, - editable: false, - noSort: false, - responsive: 1, - responsiveHidden: false, - format: "", - transform: "", - filterType: "text", - firstFilterOption: { value: "", text: "" }, - }; - } - - /** - * @returns {Options} - */ - get defaultOptions() { - return { - id: null, - url: "", - perPage: 10, - debug: false, - filter: false, - menu: false, - sort: false, - server: false, - serverParams: { - start: "start", - length: "length", - search: "search", - sort: "sort", - sortDir: "sortDir", - dataKey: "data", - metaKey: "meta", - metaTotalKey: "total", - metaFilteredKey: "filtered", - optionsKey: "options", - paramsKey: "params", - }, - defaultSort: "", - reorder: false, - dir: "ltr", - perPageValues: [10, 25, 50, 100, 250], - hidePerPage: false, - columns: [], - actions: [], - collapseActions: false, - selectable: false, + if (!this.hasDataError && tbody.getAttribute("data-empty") !== this.noData) { + tbody.setAttribute("data-empty", this.noData); + } + } + + /** + * @returns {Column} + */ + get defaultColumn() { + return { + field: "", + title: "", + width: 0, + class: "", + attr: "", + hidden: false, + editable: false, + noSort: false, + responsive: 1, + responsiveHidden: false, + format: "", + transform: "", + filterType: "text", + firstFilterOption: { value: "", text: "" }, + }; + } + + /** + * @returns {Options} + */ + get defaultOptions() { + return { + id: null, + url: "", + perPage: 10, + debug: false, + filter: false, + menu: false, + sort: false, + server: false, + serverParams: { + start: "start", + length: "length", + search: "search", + sort: "sort", + sortDir: "sortDir", + dataKey: "data", + metaKey: "meta", + metaTotalKey: "total", + metaFilteredKey: "filtered", + optionsKey: "options", + paramsKey: "params", + }, + defaultSort: "", + reorder: false, + dir: "ltr", + perPageValues: [10, 25, 50, 100, 250], + hidePerPage: false, + columns: [], + actions: [], + collapseActions: false, + selectable: false, selectVisibleOnly: true, - singleSelect: false, - defaultPage: 1, - resizable: false, - autosize: true, - expand: false, - autoheight: true, - autohidePager: false, - responsive: false, - responsiveToggle: true, - filterOnEnter: true, - filterKeypressDelay: 500, - spinnerClass: "", - saveState: false, + singleSelect: false, + defaultPage: 1, + resizable: false, + autosize: true, + expand: false, + autoheight: true, + autohidePager: false, + responsive: false, + responsiveToggle: true, + filterOnEnter: true, + filterKeypressDelay: 500, + spinnerClass: "", + saveState: false, errorMessage: "", - noData: "" - }; - } - - /** - * Determines if the grid is initialized. - * @returns {Boolean} - */ - get isInit() { - return this.classList.contains("dg-initialized"); - } - - /** - * Determines if data load has failed. - * @returns {Boolean} - */ - get hasDataError() { - return this.classList.contains("dg-network-error"); - } - - /** - * @param {Plugins} list - */ - static registerPlugins(list) { - plugins = list; - } - - /** - * @param {String} plugin - */ - static unregisterPlugins(plugin = null) { - if (plugin === null) { - plugins = {}; - } else { - delete plugins[plugin]; - } - } - - /** - * @returns {Plugins} - */ - static registeredPlugins() { - return plugins; - } - - /** - * @param {Object|Array} columns - * @returns {Column[]} - */ - convertColumns(columns) { - const cols = []; - // Convert key:value objects to actual columns - if (typeof columns === "object" && !Array.isArray(columns)) { - for (const key of Object.keys(columns)) { - const col = Object.assign({}, this.defaultColumn); - col.title = columns[key]; - col.field = key; - cols.push(col); - } - } else { - for (const item of columns) { - let col = Object.assign({}, this.defaultColumn); - if (typeof item === "string") { - col.title = item; - col.field = item; - } else if (typeof item === "object") { - col = Object.assign(col, item); - if (!col.field) { - console.error("Invalid column definition", item); - } - if (!col.title) { - col.title = col.field; - } - } else { - console.error("Column definition must be a string or an object"); - } - cols.push(col); - } - } - return cols; - } - - /** - * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes - * @returns {Array} - */ - static get observedAttributes() { - return [ - "page", - "data-filter", - "data-sort", - "data-debug", - "data-reorder", - "data-menu", + noData: "" + }; + } + + /** + * Determines if the grid is initialized. + * @returns {Boolean} + */ + get isInit() { + return this.classList.contains("dg-initialized"); + } + + /** + * Determines if data load has failed. + * @returns {Boolean} + */ + get hasDataError() { + return this.classList.contains("dg-network-error"); + } + + /** + * @param {Plugins} list + */ + static registerPlugins(list) { + plugins = list; + } + + /** + * @param {String} plugin + */ + static unregisterPlugins(plugin = null) { + if (plugin === null) { + plugins = {}; + } else { + delete plugins[plugin]; + } + } + + /** + * @returns {Plugins} + */ + static registeredPlugins() { + return plugins; + } + + /** + * @param {Object|Array} columns + * @returns {Column[]} + */ + convertColumns(columns) { + const cols = []; + // Convert key:value objects to actual columns + if (typeof columns === "object" && !Array.isArray(columns)) { + for (const key of Object.keys(columns)) { + const col = Object.assign({}, this.defaultColumn); + col.title = columns[key]; + col.field = key; + cols.push(col); + } + } else { + for (const item of columns) { + let col = Object.assign({}, this.defaultColumn); + if (typeof item === "string") { + col.title = item; + col.field = item; + } else if (typeof item === "object") { + col = Object.assign(col, item); + if (!col.field) { + console.error("Invalid column definition", item); + } + if (!col.title) { + col.title = col.field; + } + } else { + console.error("Column definition must be a string or an object"); + } + cols.push(col); + } + } + return cols; + } + + /** + * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes + * @returns {Array} + */ + static get observedAttributes() { + return [ + "page", + "data-filter", + "data-sort", + "data-debug", + "data-reorder", + "data-menu", "data-selectable", - "data-single-select", - "data-url", - "data-per-page", - "data-responsive", - ]; - } - - get transformAttributes() { - return { - columns: (v) => this.convertColumns(convertArray(v)), - actions: (v) => convertArray(v), - defaultPage: (v) => Number.parseInt(v), - perPage: (v) => Number.parseInt(v), - }; - } - - /** @returns {HTMLTableSectionElement} */ - get thead() { - //@ts-ignore - return $("thead", this); - } - - /** @returns {HTMLTableSectionElement} */ - get tbody() { - //@ts-ignore - return $("tbody", this); - } - - /** @returns {HTMLTableSectionElement} */ - get tfoot() { - //@ts-ignore - return $("tfoot", this); - } - - get page() { - return Number.parseInt(this.getAttribute("page")); - } - - set page(val) { - setAttribute(this, "page", this.constrainPageValue(val)); - } - - /** - * Loads data and configures the grid. - * @param {Boolean} initOnly - */ - urlChanged(initOnly = false) { - if (initOnly && !this.isInit) return this; - this.reconfig(); - return this.loadData().then(() => this.configureUi()); - } - - /** - * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering. - */ - reconfig() { - const cols = this.options.columns; - this.options.columns = []; - this.configureUi(); - return this.options.columns = cols, this; - } - - constrainPageValue(v) { - let pv = v; - if (this.pages < pv) { - pv = this.pages; - } - if (pv < 1 || !pv) { - pv = 1; - } - return pv; - } - + "data-single-select", + "data-url", + "data-per-page", + "data-responsive", + ]; + } + + get transformAttributes() { + return { + columns: (v) => this.convertColumns(convertArray(v)), + actions: (v) => convertArray(v), + defaultPage: (v) => Number.parseInt(v), + perPage: (v) => Number.parseInt(v), + }; + } + + /** @returns {HTMLTableSectionElement} */ + get thead() { + //@ts-ignore + return $("thead", this); + } + + /** @returns {HTMLTableSectionElement} */ + get tbody() { + //@ts-ignore + return $("tbody", this); + } + + /** @returns {HTMLTableSectionElement} */ + get tfoot() { + //@ts-ignore + return $("tfoot", this); + } + + get page() { + return Number.parseInt(this.getAttribute("page")); + } + + set page(val) { + setAttribute(this, "page", this.constrainPageValue(val)); + } + + /** + * Loads data and configures the grid. + * @param {Boolean} initOnly + */ + urlChanged(initOnly = false) { + if (initOnly && !this.isInit) return this; + this.reconfig(); + return this.loadData().then(() => this.configureUi()); + } + + /** + * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering. + */ + reconfig() { + const cols = this.options.columns; + this.options.columns = []; + this.configureUi(); + return this.options.columns = cols, this; + } + + constrainPageValue(v) { + let pv = v; + if (this.pages < pv) { + pv = this.pages; + } + if (pv < 1 || !pv) { + pv = 1; + } + return pv; + } + fixPage() { - if (!this.inputPage) return this; - this.pages = this.totalPages(); - this.page = this.constrainPageValue(this.page); - - // Show current page in input - setAttribute(this.inputPage, "max", this.pages); - this.inputPage.value = `${this.page}`; - return this.inputPage.disabled = this.pages < 2, this; - } - - pageChanged() { - this.reload(); - } - - responsiveChanged() { - if (!this.plugins.ResponsiveGrid) { - return; - } - if (this.options.responsive) { - this.plugins.ResponsiveGrid.observe(); - } else { - this.plugins.ResponsiveGrid.unobserve(); - } - } - - menuChanged() { - this.renderHeader(); - } - - /** - * This is the callback for the select control - */ - changePerPage() { - this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value); - this.perPageChanged(); - } - - /** - * This is the actual event triggered on attribute change - */ - perPageChanged() { - // Refresh UI - if ( - this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value) - ) { - this.perPageValuesChanged(); - } - // Make sure current page is still valid - let updatePage = this.page; - while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) { - updatePage--; - } - if (updatePage !== this.page) { - // Triggers pageChanged, which will trigger reload - this.page = updatePage; - } else { - // Simply reload current page - this.reload(() => { - // Preserve distance between top of page and select control if no fixed height - if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) { - this.selectPerPage.scrollIntoView(); - } - }); - } - } - - dirChanged() { - setAttribute(this, "dir", this.options.dir); - } - - defaultSortChanged() { - this.sortChanged(); - } - - /** - * Populate the select dropdown according to options - */ - perPageValuesChanged() { - if (!this.selectPerPage) { - return; - } - while (this.selectPerPage.lastChild) { - this.selectPerPage.removeChild(this.selectPerPage.lastChild); - } - for (const v of this.options.perPageValues) { - addSelectOption(this.selectPerPage, v, v, v === this.options.perPage); - } - } - - async _connected() { - /** - * @type {HTMLTableElement} - */ - this.table = this.querySelector("table"); - /** - * @type {HTMLInputElement} - */ - this.btnFirst = this.querySelector(".dg-btn-first"); - /** - * @type {HTMLInputElement} - */ - this.btnPrev = this.querySelector(".dg-btn-prev"); - /** - * @type {HTMLInputElement} - */ - this.btnNext = this.querySelector(".dg-btn-next"); - /** - * @type {HTMLInputElement} - */ - this.btnLast = this.querySelector(".dg-btn-last"); - /** - * @type {HTMLSelectElement} - */ - this.selectPerPage = this.querySelector(".dg-select-per-page"); - /** - * @type {HTMLInputElement} - */ - this.inputPage = this.querySelector(".dg-input-page"); - - this.getFirst = this.getFirst.bind(this); - this.getPrev = this.getPrev.bind(this); - this.getNext = this.getNext.bind(this); - this.getLast = this.getLast.bind(this); - this.changePerPage = this.changePerPage.bind(this); - this.gotoPage = this.gotoPage.bind(this); - - this.btnFirst.addEventListener("click", this.getFirst); - this.btnPrev.addEventListener("click", this.getPrev); - this.btnNext.addEventListener("click", this.getNext); - this.btnLast.addEventListener("click", this.getLast); - this.selectPerPage.addEventListener("change", this.changePerPage); - this.selectPerPage.toggleAttribute("hidden", this.options.hidePerPage); - this.inputPage.addEventListener("input", this.gotoPage); - - for (const plugin of Object.values(this.plugins)) { - await plugin.connected(); - } - - // Display even if we don't have data - this.dirChanged(); - this.perPageValuesChanged(); - - await this.init(); - } - - _disconnected() { - this.btnFirst?.removeEventListener("click", this.getFirst); - this.btnPrev?.removeEventListener("click", this.getPrev); - this.btnNext?.removeEventListener("click", this.getNext); - this.btnLast?.removeEventListener("click", this.getLast); - this.selectPerPage?.removeEventListener("change", this.changePerPage); - this.inputPage?.removeEventListener("input", this.gotoPage); - - for (const plugin of Object.values(this.plugins)) { - plugin.disconnected(); - } + if (!this.inputPage) return this; + this.pages = this.totalPages(); + this.page = this.constrainPageValue(this.page); + + // Show current page in input + setAttribute(this.inputPage, "max", this.pages); + this.inputPage.value = `${this.page}`; + return this.inputPage.disabled = this.pages < 2, this; + } + + pageChanged() { + this.reload(); + } + + responsiveChanged() { + if (!this.plugins.ResponsiveGrid) { + return; + } + if (this.options.responsive) { + this.plugins.ResponsiveGrid.observe(); + } else { + this.plugins.ResponsiveGrid.unobserve(); + } + } + + menuChanged() { + this.renderHeader(); + } + + /** + * This is the callback for the select control + */ + changePerPage() { + this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value); + this.perPageChanged(); + } + + /** + * This is the actual event triggered on attribute change + */ + perPageChanged() { + // Refresh UI + if ( + this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value) + ) { + this.perPageValuesChanged(); + } + // Make sure current page is still valid + let updatePage = this.page; + while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) { + updatePage--; + } + if (updatePage !== this.page) { + // Triggers pageChanged, which will trigger reload + this.page = updatePage; + } else { + // Simply reload current page + this.reload(() => { + // Preserve distance between top of page and select control if no fixed height + if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) { + this.selectPerPage.scrollIntoView(); + } + }); + } + } + + dirChanged() { + setAttribute(this, "dir", this.options.dir); + } + + defaultSortChanged() { + this.sortChanged(); + } + + /** + * Populate the select dropdown according to options + */ + perPageValuesChanged() { + if (!this.selectPerPage) { + return; + } + while (this.selectPerPage.lastChild) { + this.selectPerPage.removeChild(this.selectPerPage.lastChild); + } + for (const v of this.options.perPageValues) { + addSelectOption(this.selectPerPage, v, v, v === this.options.perPage); + } + } + + async _connected() { + /** + * @type {HTMLTableElement} + */ + this.table = this.querySelector("table"); + /** + * @type {HTMLInputElement} + */ + this.btnFirst = this.querySelector(".dg-btn-first"); + /** + * @type {HTMLInputElement} + */ + this.btnPrev = this.querySelector(".dg-btn-prev"); + /** + * @type {HTMLInputElement} + */ + this.btnNext = this.querySelector(".dg-btn-next"); + /** + * @type {HTMLInputElement} + */ + this.btnLast = this.querySelector(".dg-btn-last"); + /** + * @type {HTMLSelectElement} + */ + this.selectPerPage = this.querySelector(".dg-select-per-page"); + /** + * @type {HTMLInputElement} + */ + this.inputPage = this.querySelector(".dg-input-page"); + + this.getFirst = this.getFirst.bind(this); + this.getPrev = this.getPrev.bind(this); + this.getNext = this.getNext.bind(this); + this.getLast = this.getLast.bind(this); + this.changePerPage = this.changePerPage.bind(this); + this.gotoPage = this.gotoPage.bind(this); + + this.btnFirst.addEventListener("click", this.getFirst); + this.btnPrev.addEventListener("click", this.getPrev); + this.btnNext.addEventListener("click", this.getNext); + this.btnLast.addEventListener("click", this.getLast); + this.selectPerPage.addEventListener("change", this.changePerPage); + this.selectPerPage.toggleAttribute("hidden", this.options.hidePerPage); + this.inputPage.addEventListener("input", this.gotoPage); + + for (const plugin of Object.values(this.plugins)) { + await plugin.connected(); + } + + // Display even if we don't have data + this.dirChanged(); + this.perPageValuesChanged(); + + await this.init(); + } + + _disconnected() { + this.btnFirst?.removeEventListener("click", this.getFirst); + this.btnPrev?.removeEventListener("click", this.getPrev); + this.btnNext?.removeEventListener("click", this.getNext); + this.btnLast?.removeEventListener("click", this.getLast); + this.selectPerPage?.removeEventListener("change", this.changePerPage); + this.inputPage?.removeEventListener("input", this.gotoPage); + + for (const plugin of Object.values(this.plugins)) { + plugin.disconnected(); + } } init() { - return this.loadData().finally(() => { - this.configureUi(); - - this.sortChanged(); - this.classList.add("dg-initialized"); //acts as a flag to prevent unnecessary server calls down the chain. - - this.filterChanged(); - this.reorderChanged(); - - this.dirChanged(); - this.perPageValuesChanged(); - this.pageChanged(); - - this.fireEvents = true; // We can now fire attributeChangedCallback events - - this.log("initialized"); - }); - } - - /** - * @param {string} field - * @returns {Column} - */ - getCol(field) { - let found = null; - - for (const col of this.options.columns) { - if (col.field === field) { - found = col; - } - } - return found; - } - - getColProp(field, prop) { - const c = this.getCol(field); - return c ? c[prop] : null; - } - - setColProp(field, prop, val) { - const c = this.getCol(field); - if (c) { - c[prop] = val; - } - } - - visibleColumns() { - return this.options.columns.filter((col) => { - return !col.hidden; + return this.loadData().finally(() => { + this.configureUi(); + + this.sortChanged(); + this.classList.add("dg-initialized"); //acts as a flag to prevent unnecessary server calls down the chain. + + this.filterChanged(); + this.reorderChanged(); + + this.dirChanged(); + this.perPageValuesChanged(); + this.pageChanged(); + + this.fireEvents = true; // We can now fire attributeChangedCallback events + + this.log("initialized"); }); - } - - hiddenColumns() { - return this.options.columns.filter((col) => { - return col.hidden === true; - }); - } - - showColumn(field, render = true) { - this.setColProp(field, "hidden", false); - - // We need to render the whole table otherwise layout fixed won't do its job - if (render) this.renderTable(); - - dispatch(this, "columnVisibility", { - col: field, - visibility: "visible", - }); - } - - hideColumn(field, render = true) { - this.setColProp(field, "hidden", true); - - // We need to render the whole table otherwise layout fixed won't do its job - if (render) this.renderTable(); - - dispatch(this, "columnVisibility", { - col: field, - visibility: "hidden", - }); - } - - /** - * Returns the starting index of actual data - * @returns {Number} - */ - startColIndex() { - let start = 1; - if (this.options.selectable && this.plugins.SelectableRows) { - start++; - } - if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) { - start++; - } - return start; - } - - /** - * @returns {Boolean} - */ - isSticky() { - return this.hasAttribute("sticky"); - } - - /** - * @param {Boolean} visibleOnly - * @returns {Number} - */ - columnsLength(visibleOnly = false) { - let len = 0; - // One column per (visible) column - for (const col of this.options.columns) { - if (visibleOnly && col.hidden) { - continue; - } - if (!col.attr) { - len++; - } - } - // Add one col for selectable checkbox at the beginning - if (this.options.selectable && this.plugins.SelectableRows) { - len++; - } - // Add one col for actions at the end - if (this.options.actions.length && this.plugins.RowActions) { - len++; - } - // Add one col for the responsive toggle - if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) { - len++; - } - return len; - } - - /** - * Global configuration and renderTable - * This should be called after your data has been loaded - */ - configureUi() { + } + + /** + * @param {string} field + * @returns {Column} + */ + getCol(field) { + let found = null; + + for (const col of this.options.columns) { + if (col.field === field) { + found = col; + } + } + return found; + } + + getColProp(field, prop) { + const c = this.getCol(field); + return c ? c[prop] : null; + } + + setColProp(field, prop, val) { + const c = this.getCol(field); + if (c) { + c[prop] = val; + } + } + + visibleColumns() { + return this.options.columns.filter((col) => { + return !col.hidden; + }); + } + + hiddenColumns() { + return this.options.columns.filter((col) => { + return col.hidden === true; + }); + } + + showColumn(field, render = true) { + this.setColProp(field, "hidden", false); + + // We need to render the whole table otherwise layout fixed won't do its job + if (render) this.renderTable(); + + dispatch(this, "columnVisibility", { + col: field, + visibility: "visible", + }); + } + + hideColumn(field, render = true) { + this.setColProp(field, "hidden", true); + + // We need to render the whole table otherwise layout fixed won't do its job + if (render) this.renderTable(); + + dispatch(this, "columnVisibility", { + col: field, + visibility: "hidden", + }); + } + + /** + * Returns the starting index of actual data + * @returns {Number} + */ + startColIndex() { + let start = 1; + if (this.options.selectable && this.plugins.SelectableRows) { + start++; + } + if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) { + start++; + } + return start; + } + + /** + * @returns {Boolean} + */ + isSticky() { + return this.hasAttribute("sticky"); + } + + /** + * @param {Boolean} visibleOnly + * @returns {Number} + */ + columnsLength(visibleOnly = false) { + let len = 0; + // One column per (visible) column + for (const col of this.options.columns) { + if (visibleOnly && col.hidden) { + continue; + } + if (!col.attr) { + len++; + } + } + // Add one col for selectable checkbox at the beginning + if (this.options.selectable && this.plugins.SelectableRows) { + len++; + } + // Add one col for actions at the end + if (this.options.actions.length && this.plugins.RowActions) { + len++; + } + // Add one col for the responsive toggle + if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) { + len++; + } + return len; + } + + /** + * Global configuration and renderTable + * This should be called after your data has been loaded + */ + configureUi() { if (!this.table) return this; - this.table.style.visibility = "hidden"; - this.renderTable(); - if (this.options.responsive && this.plugins.ResponsiveGrid) { - // Let the observer make the table visible - } else { - this.table.style.visibility = "visible"; - } - - // Store row height for later usage - if (!this.rowHeight) { - const tr = find(this, "tbody tr") || find(this, "table tr"); - if (tr) { - this.rowHeight = tr.offsetHeight; - } - } - this.#setNoData(this.tbody); - return this.fixPage(); - } - - filterChanged() { - const row = this.querySelector("thead tr.dg-head-filters"); - if (this.options.filter) { - removeAttribute(row, "hidden"); - } else { - this.clearFilters(); - setAttribute(row, "hidden", ""); - } - } - - reorderChanged() { - const headers = findAll(this, "thead tr.dg-head-columns th"); - for (const th of headers) { - if (th.classList.contains("dg-selectable") || th.classList.contains("dg-actions")) { - continue; - } - if (this.options.reorder && this.plugins.DraggableHeaders) { - th.draggable = true; - } else { - th.removeAttribute("draggable"); - } - } - } - - sortChanged() { - this.log("toggle sort"); - - const headers = findAll(this, "thead tr.dg-head-columns th"); - for (const th of headers) { - const fieldName = th.getAttribute("field"); - if ( - th.classList.contains("dg-not-sortable") || - (!this.fireEvents && fieldName === this.options.defaultSort) - ) { - return; - } - if (this.options.sort && !this.getColProp(fieldName, "noSort")) { - setAttribute(th, "aria-sort", "none"); - } else { - removeAttribute(th, "aria-sort"); - } - } - } - - selectableChanged() { - this.renderTable(); - } - - addRow(row) { - if (!Array.isArray(this.originalData)) { - return; - } - this.log("add row"); - this.originalData.push(row); - this.data = this.originalData.slice(); - this.sortData(); - } - - /** - * @param {any} value Value to remove. Defaults to last row. - * @param {String} key The key of the item to remove. Defaults to first column - */ - removeRow(value = null, key = null) { - if (!Array.isArray(this.originalData)) { - return; - } - - let v = value; - let k = key; - if (k === null) { - k = this.options.columns[0].field; - } - if (v === null) { - v = this.originalData[this.originalData.length - 1][k]; - } - this.log(`remove row ${k}:${v}`); - for (let i = 0; i < this.originalData.length; i++) { - if (this.originalData[i][k] === v) { - this.originalData.splice(i, 1); - break; - } - } - this.data = this.originalData.slice(); - this.sortData(); - } - + this.table.style.visibility = "hidden"; + this.renderTable(); + if (this.options.responsive && this.plugins.ResponsiveGrid) { + // Let the observer make the table visible + } else { + this.table.style.visibility = "visible"; + } + + // Store row height for later usage + if (!this.rowHeight) { + const tr = find(this, "tbody tr") || find(this, "table tr"); + if (tr) { + this.rowHeight = tr.offsetHeight; + } + } + this.#setNoData(this.tbody); + return this.fixPage(); + } + + filterChanged() { + const row = this.querySelector("thead tr.dg-head-filters"); + if (this.options.filter) { + removeAttribute(row, "hidden"); + } else { + this.clearFilters(); + setAttribute(row, "hidden", ""); + } + } + + reorderChanged() { + const headers = findAll(this, "thead tr.dg-head-columns th"); + for (const th of headers) { + if (th.classList.contains("dg-selectable") || th.classList.contains("dg-actions")) { + continue; + } + if (this.options.reorder && this.plugins.DraggableHeaders) { + th.draggable = true; + } else { + th.removeAttribute("draggable"); + } + } + } + + sortChanged() { + this.log("toggle sort"); + + const headers = findAll(this, "thead tr.dg-head-columns th"); + for (const th of headers) { + const fieldName = th.getAttribute("field"); + if ( + th.classList.contains("dg-not-sortable") || + (!this.fireEvents && fieldName === this.options.defaultSort) + ) { + return; + } + if (this.options.sort && !this.getColProp(fieldName, "noSort")) { + setAttribute(th, "aria-sort", "none"); + } else { + removeAttribute(th, "aria-sort"); + } + } + } + + selectableChanged() { + this.renderTable(); + } + + addRow(row) { + if (!Array.isArray(this.originalData)) { + return; + } + this.log("add row"); + this.originalData.push(row); + this.data = this.originalData.slice(); + this.sortData(); + } + + /** + * @param {any} value Value to remove. Defaults to last row. + * @param {String} key The key of the item to remove. Defaults to first column + */ + removeRow(value = null, key = null) { + if (!Array.isArray(this.originalData)) { + return; + } + + let v = value; + let k = key; + if (k === null) { + k = this.options.columns[0].field; + } + if (v === null) { + v = this.originalData[this.originalData.length - 1][k]; + } + this.log(`remove row ${k}:${v}`); + for (let i = 0; i < this.originalData.length; i++) { + if (this.originalData[i][k] === v) { + this.originalData.splice(i, 1); + break; + } + } + this.data = this.originalData.slice(); + this.sortData(); + } + /** * Get selected rows or specific fields from selected rows. * If no keys are provided, returns the full row objects. @@ -1038,973 +1038,977 @@ class DataGrid extends BaseElement { return []; } return this.plugins.SelectableRows.getSelection(...keys); - } - - getData() { - return this.originalData; - } - - clearData(force = false) { - // Already empty - if (!force && this.data.length === 0) { - return; + } + + getData() { + return this.originalData; + } + + clearData(force = false) { + // Already empty + if (!force && this.data.length === 0) { + return; } this.classList.remove("dg-empty", "dg-network-error"); - this.tbody?.setAttribute("data-empty", this.noData); - this.data = this.originalData = []; - this.renderBody(); - } - - /** - * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time. - * Subsequent grid actions after initialization will operate as normal. - * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties. - */ - preload(data) { - const metaKey = this.options.serverParams.metaKey; - const dataKey = this.options.serverParams.dataKey; - if (data?.[metaKey]) { - this.meta = data[metaKey]; - } - if (data?.[dataKey]) { - this.data = this.originalData = data[dataKey]; - } - } + this.tbody?.setAttribute("data-empty", this.noData); + this.data = this.originalData = []; + this.renderBody(); + } + + /** + * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time. + * Subsequent grid actions after initialization will operate as normal. + * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties. + */ + preload(data) { + const metaKey = this.options.serverParams.metaKey; + const dataKey = this.options.serverParams.dataKey; + if (data?.[metaKey]) { + this.meta = data[metaKey]; + } + if (data?.[dataKey]) { + this.data = this.originalData = data[dataKey]; + } + } /** * Clears and reloads data from url. * @param {Function|String} callbackOrUrl * @returns {DataGrid} - */ - refresh(callbackOrUrl = null) { - this.data = this.originalData = []; - return this.reload(callbackOrUrl); - } + */ + refresh(callbackOrUrl = null) { + this.data = this.originalData = []; + return this.reload(callbackOrUrl); + } /** * Reloads data from url. * @param {Function|String} callbackOrUrl * @returns {DataGrid} - */ - reload(callbackOrUrl = null) { - this.log("reload"); + */ + reload(callbackOrUrl = null) { + this.log("reload"); if (typeof callbackOrUrl === "string") { this.options.url = callbackOrUrl; - } - // If the data was cleared, we need to render again - const needRender = !this.originalData?.length; - this.fixPage(); - // @ts-ignore - return this.loadData().finally(() => { - if (this.hasDataError) return; - // If we load data from the server, we redraw the table body - // Otherwise, we just need to paginate - this.options.server || needRender ? this.renderBody() : this.paginate(); - if (typeof callbackOrUrl === "function") { - callbackOrUrl(); - } - }).then(() => this); - } - - /** - * @returns {Promise} - */ - loadData() { - const flagEmpty = () => !this.data.length && this.classList.add("dg-empty"); - const tbody = this.tbody; - - // We already have some data - if (this.meta || this.originalData || this.isInit) { - // We don't use server side data - if (!this.options.server || (this.options.server && !this.fireEvents)) { - this.log("skip loadData"); - flagEmpty(); - return new Promise((resolve) => { - resolve(); - }); - } - } - this.log("loadData"); - this.loading = true; - this.classList.add("dg-loading"); - this.classList.remove("dg-empty", "dg-network-error"); - return ( - this.fetchData() - .then((response) => { - // We can get a straight array or an object - if (Array.isArray(response)) { - this.data = response; - } else { - // Object must contain data key - if (!response[this.options.serverParams.dataKey]) { - console.error( - "Invalid response, it should contain a data key with an array or be a plain array", - response, - ); - this.options.url = null; - return; - } - - // We may have a config object - this.options = Object.assign( - this.options, - response[this.options.serverParams.optionsKey] ?? {}, - ); - // It should return meta data (see metaFilteredKey) - this.meta = response[this.options.serverParams.metaKey] ?? {}; - this.data = response[this.options.serverParams.dataKey]; - } - this.originalData = this.data.slice(); - this.fixPage(); - - // Make sure we have a proper set of columns - if (this.options.columns.length === 0 && this.originalData.length) { - this.options.columns = this.convertColumns(Object.keys(this.originalData[0])); - } else { - this.options.columns = this.convertColumns(this.options.columns); - } - }) - .catch((err) => { - this.log(err); - tbody.setAttribute( - "data-empty", - this.options.errorMessage || - err.message?.replace(/^\s+|\r\n|\n|\r$/g, "") || - labels.networkError, - ); - this.classList.add("dg-empty", "dg-network-error"); - dispatch(this, "loadDataFailed", err); - }) - // @ts-ignore - .finally(() => { - flagEmpty(); - this.#setNoData(tbody); - this.classList.remove("dg-loading"); - setAttribute(this.table, "aria-rowcount", this.data.length); - this.loading = false; - }) - ); - } - - getFirst() { - if (this.loading) { - return; - } - this.page = 1; - } - - getLast() { - if (this.loading) { - return; - } - this.page = this.pages; - } - - getPrev() { - if (this.loading) { - return; - } - this.page = this.page - 1; - } - - getNext() { - if (this.loading) { - return; - } - this.page = this.page + 1; - } - - gotoPage(event) { - if (event.type === "keypress") { - const key = event.keyCode || event.key; - if (key === 13 || key === "Enter") { - event.preventDefault(); - } else { - return; - } - } - this.page = Number.parseInt(this.inputPage.value); - } - - getSort() { - const col = this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']"); - if (col) { - return col.getAttribute("field"); - } - return this.options.defaultSort; - } - - getSortDir() { - const col = this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']"); - if (col) { - return col.getAttribute("aria-sort") || ""; - } - return ""; - } - - getFilters() { - const filters = []; - const inputs = findAll(this, this._filterSelector); - for (const input of inputs) { - filters[input.dataset.name] = input.value; - } - return filters; - } - - clearFilters() { - const inputs = findAll(this, this._filterSelector); - for (const input of inputs) { - input.value = ""; - } - this.filterData(); - } - - filterData() { - this.log("filter data"); - - this.page = 1; - - if (this.options.server) { - this.reload(); - } else { - this.data = this.originalData?.slice() ?? []; - - // Look for rows matching the filters - const inputs = findAll(this, this._filterSelector); - for (const input of inputs) { - const value = input.value; - if (value) { - const name = input.dataset.name; - this.data = this.data.filter((item) => { - const str = `${item[name]}`; - return str.toLowerCase().indexOf(value.toLowerCase()) !== -1; - }); - } - } - this.pageChanged(); - - const col = this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']"); - if (this.options.sort && col) { - this.sortData(); - } else { - this.renderBody(); - } - } - } - - /** - * Data will be sorted then rendered using renderBody - * @param {Element} baseCol The column that was clicked or null to use current sort - */ - sortData(baseCol = null) { - this.log("sort data"); - - let col = baseCol; - - // Early exit - if (col && this.getColProp(col.getAttribute("field"), "noSort")) { - this.log("sorting prevented because column is not sortable"); - return; - } - if (this.plugins.ColumnResizer?.isResizing) { - this.log("sorting prevented because resizing"); - return; - } - if (this.loading) { - this.log("sorting prevented because loading"); - return; - } - - // We clicked on a column, update sort state - if (col !== null) { - // Remove active sort if any - const haveClasses = (c) => ["dg-selectable", "dg-actions", "dg-responsive-toggle"].includes(c); - - const headers = findAll(this, "thead tr:first-child th"); - for (const th of headers) { - // @ts-ignore - if ([...th.classList].some(haveClasses) || !th.hasAttribute("aria-sort")) { - continue; - } - if (th !== col) { - th.setAttribute("aria-sort", "none"); - } - } - - // Set tristate col - if (!col.hasAttribute("aria-sort") || col.getAttribute("aria-sort") === "none") { - col.setAttribute("aria-sort", "ascending"); - } else if (col.getAttribute("aria-sort") === "ascending") { - col.setAttribute("aria-sort", "descending"); - } else if (col.getAttribute("aria-sort") === "descending") { - col.setAttribute("aria-sort", "none"); - } - } else { - // Or fetch current sort - col = this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']"); - } - - if (this.options.server) { - // Reload data with updated sort - this.loadData().finally(() => { - this.renderBody(); - }); - } else { - const sort = col ? col.getAttribute("aria-sort") : "none"; - if (sort === "none") { - const stack = []; - - // Restore order while keeping filters - this.originalData?.some((itemA) => { - this.data.some((itemB) => { - if (JSON.stringify(itemA) === JSON.stringify(itemB)) { - stack.push(itemB); - return true; - } - return false; - }); - return stack.length === this.data.length; - }); - - this.data = stack; - } else { - const field = col.getAttribute("field"); - this.data.sort((a, b) => { - if (!isNaN(a[field]) && !isNaN(b[field])) { - return sort === "ascending" ? a[field] - b[field] : b[field] - a[field]; - } - const valA = sort === "ascending" ? a[field].toUpperCase() : b[field].toUpperCase(); - const valB = sort === "ascending" ? b[field].toUpperCase() : a[field].toUpperCase(); - - switch (true) { - case valA > valB: - return 1; - case valA < valB: - return -1; - case valA === valB: - return 0; - } - }); - } - this.renderBody(); - } - } - - _sort(columnName, sortDir) { - const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`); - const dir = sortDir === "ascending" ? "none" : sortDir === "descending" ? "ascending" : "descending"; - col?.setAttribute("aria-sort", dir); - this.sortData(col); - } - - sortAsc = (columnName) => this._sort(columnName, "ascending"); - sortDesc = (columnName) => this._sort(columnName, "descending"); - sortNone = (columnName) => this._sort(columnName, "none"); - - fetchData() { - if (!this.options.url) { - return new Promise((resolve, reject) => reject("No url set")); - } - - let base = window.location.href; - // Fix trailing slash if no extension is present - if (!base.split("/").pop().includes(".")) { - base += base.endsWith("/") ? "" : "/"; - } - const url = new URL(this.options.url, base); - let params = { - r: Date.now(), - }; - if (this.options.server) { - // 0 based - params[this.options.serverParams.start] = this.page - 1; - params[this.options.serverParams.length] = this.options.perPage; - if (this.options.filter) params[this.options.serverParams.search] = this.getFilters(); - params[this.options.serverParams.sort] = this.getSort() || ""; - params[this.options.serverParams.sortDir] = this.getSortDir(); - - // extra params ? - if (this.meta?.[this.options.serverParams.paramsKey]) { - params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]); - } - } - - appendParamsToUrl(url, params); - - return fetch(url).then((response) => { - const newError = new Error(response.statusText || labels.networkError); - if (!response.ok) { - // @ts-ignore - newError.response = response; - throw newError; - } - return response - .clone() - .json() - .catch((err) => { - let error = err; - if (!this.options.debug) { - error = newError; - } - error.response = response; - throw error; - }); - }); - } - - renderTable() { - this.log("render table"); - - if (this.options.menu && this.plugins.ContextMenu) { - this.plugins.ContextMenu.createMenu(); - } - - let sortedColumn; - - this.renderHeader(); - if (this.options.defaultSort) { - // We can have a default sort even with sort disabled - sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`); - } - - if (sortedColumn) { - this.sortData(sortedColumn); - } else { - this.renderBody(); - } - - this.renderFooter(); - } - - /** - * Create table header - * - One row for the column headers - * - One row for the filters - */ - renderHeader() { - this.log("render header"); - - const thead = this.thead; - this.createColumnHeaders(thead); - this.createColumnFilters(thead); - - if (this.options.resizable && this.plugins.ColumnResizer) { - this.plugins.ColumnResizer.renderResizer(labels.resizeColumn); - } - - dispatch(this, "headerRendered"); - } - - renderFooter() { - this.log("render footer"); - - const tfoot = this.tfoot; + } + // If the data was cleared, we need to render again + const needRender = !this.originalData?.length; + this.fixPage(); + // @ts-ignore + return this.loadData().finally(() => { + if (this.hasDataError) return; + // If we load data from the server, we redraw the table body + // Otherwise, we just need to paginate + this.options.server || needRender ? this.renderBody() : this.paginate(); + if (typeof callbackOrUrl === "function") { + callbackOrUrl(); + } + }).then(() => this); + } + + /** + * @returns {Promise} + */ + loadData() { + const flagEmpty = () => !this.data.length && this.classList.add("dg-empty"); + const tbody = this.tbody; + + // We already have some data + if (this.meta || this.originalData || this.isInit) { + // We don't use server side data + if (!this.options.server || (this.options.server && !this.fireEvents)) { + this.log("skip loadData"); + flagEmpty(); + return new Promise((resolve) => { + resolve(); + }); + } + } + this.log("loadData"); + this.loading = true; + this.classList.add("dg-loading"); + this.classList.remove("dg-empty", "dg-network-error"); + return ( + this.fetchData() + .then((response) => { + // We can get a straight array or an object + if (Array.isArray(response)) { + this.data = response; + } else { + // Object must contain data key + if (!response[this.options.serverParams.dataKey]) { + console.error( + "Invalid response, it should contain a data key with an array or be a plain array", + response, + ); + this.options.url = null; + return; + } + + // We may have a config object + this.options = Object.assign( + this.options, + response[this.options.serverParams.optionsKey] ?? {}, + ); + // It should return meta data (see metaFilteredKey) + this.meta = response[this.options.serverParams.metaKey] ?? {}; + this.data = response[this.options.serverParams.dataKey]; + } + this.originalData = this.data.slice(); + this.fixPage(); + + // Make sure we have a proper set of columns + if (this.options.columns.length === 0 && this.originalData.length) { + this.options.columns = this.convertColumns(Object.keys(this.originalData[0])); + } else { + this.options.columns = this.convertColumns(this.options.columns); + } + }) + .catch((err) => { + this.log(err); + tbody.setAttribute( + "data-empty", + this.options.errorMessage || + err.message?.replace(/^\s+|\r\n|\n|\r$/g, "") || + labels.networkError, + ); + this.classList.add("dg-empty", "dg-network-error"); + dispatch(this, "loadDataFailed", err); + }) + // @ts-ignore + .finally(() => { + flagEmpty(); + this.#setNoData(tbody); + this.classList.remove("dg-loading"); + setAttribute(this.table, "aria-rowcount", this.data.length); + this.loading = false; + }) + ); + } + + getFirst() { + if (this.loading) { + return; + } + this.page = 1; + } + + getLast() { + if (this.loading) { + return; + } + this.page = this.pages; + } + + getPrev() { + if (this.loading) { + return; + } + this.page = this.page - 1; + } + + getNext() { + if (this.loading) { + return; + } + this.page = this.page + 1; + } + + gotoPage(event) { + if (event.type === "keypress") { + const key = event.keyCode || event.key; + if (key === 13 || key === "Enter") { + event.preventDefault(); + } else { + return; + } + } + this.page = Number.parseInt(this.inputPage.value); + } + + getSort() { + const col = this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']"); + if (col) { + return col.getAttribute("field"); + } + return this.options.defaultSort; + } + + getSortDir() { + const col = this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']"); + if (col) { + return col.getAttribute("aria-sort") || ""; + } + return ""; + } + + getFilters() { + const filters = []; + const inputs = findAll(this, this._filterSelector); + for (const input of inputs) { + filters[input.dataset.name] = input.value; + } + return filters; + } + + clearFilters() { + const inputs = findAll(this, this._filterSelector); + for (const input of inputs) { + input.value = ""; + } + this.filterData(); + } + + filterData() { + this.log("filter data"); + + this.page = 1; + + if (this.options.server) { + this.reload(); + } else { + this.data = this.originalData?.slice() ?? []; + + // Look for rows matching the filters + const inputs = findAll(this, this._filterSelector); + for (const input of inputs) { + const value = input.value; + if (value) { + const name = input.dataset.name; + this.data = this.data.filter((item) => { + const str = `${item[name]}`; + return str.toLowerCase().indexOf(value.toLowerCase()) !== -1; + }); + } + } + this.pageChanged(); + + const col = this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']"); + if (this.options.sort && col) { + this.sortData(); + } else { + this.renderBody(); + } + } + } + + /** + * Data will be sorted then rendered using renderBody + * @param {Element} baseCol The column that was clicked or null to use current sort + */ + sortData(baseCol = null) { + this.log("sort data"); + + let col = baseCol; + + // Early exit + if (col && this.getColProp(col.getAttribute("field"), "noSort")) { + this.log("sorting prevented because column is not sortable"); + return; + } + if (this.plugins.ColumnResizer?.isResizing) { + this.log("sorting prevented because resizing"); + return; + } + if (this.loading) { + this.log("sorting prevented because loading"); + return; + } + + // We clicked on a column, update sort state + if (col !== null) { + // Remove active sort if any + const haveClasses = (c) => ["dg-selectable", "dg-actions", "dg-responsive-toggle"].includes(c); + + const headers = findAll(this, "thead tr:first-child th"); + for (const th of headers) { + // @ts-ignore + if ([...th.classList].some(haveClasses) || !th.hasAttribute("aria-sort")) { + continue; + } + if (th !== col) { + th.setAttribute("aria-sort", "none"); + } + } + + // Set tristate col + if (!col.hasAttribute("aria-sort") || col.getAttribute("aria-sort") === "none") { + col.setAttribute("aria-sort", "ascending"); + } else if (col.getAttribute("aria-sort") === "ascending") { + col.setAttribute("aria-sort", "descending"); + } else if (col.getAttribute("aria-sort") === "descending") { + col.setAttribute("aria-sort", "none"); + } + } else { + // Or fetch current sort + col = this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']"); + } + + if (this.options.server) { + // Reload data with updated sort + this.loadData().finally(() => { + this.renderBody(); + }); + } else { + const sort = col ? col.getAttribute("aria-sort") : "none"; + if (sort === "none") { + const stack = []; + + // Restore order while keeping filters + this.originalData?.some((itemA) => { + this.data.some((itemB) => { + if (JSON.stringify(itemA) === JSON.stringify(itemB)) { + stack.push(itemB); + return true; + } + return false; + }); + return stack.length === this.data.length; + }); + + this.data = stack; + } else { + const field = col.getAttribute("field"); + this.data.sort((a, b) => { + if (!isNaN(a[field]) && !isNaN(b[field])) { + return sort === "ascending" ? a[field] - b[field] : b[field] - a[field]; + } + const valA = sort === "ascending" ? a[field].toUpperCase() : b[field].toUpperCase(); + const valB = sort === "ascending" ? b[field].toUpperCase() : a[field].toUpperCase(); + + switch (true) { + case valA > valB: + return 1; + case valA < valB: + return -1; + case valA === valB: + return 0; + } + }); + } + this.renderBody(); + } + } + + _sort(columnName, sortDir) { + const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`); + const dir = sortDir === "ascending" ? "none" : sortDir === "descending" ? "ascending" : "descending"; + col?.setAttribute("aria-sort", dir); + this.sortData(col); + } + + sortAsc = (columnName) => this._sort(columnName, "ascending"); + sortDesc = (columnName) => this._sort(columnName, "descending"); + sortNone = (columnName) => this._sort(columnName, "none"); + + fetchData() { + if (!this.options.url) { + return new Promise((resolve, reject) => reject("No url set")); + } + + let base = window.location.href; + // Fix trailing slash if no extension is present + if (!base.split("/").pop().includes(".")) { + base += base.endsWith("/") ? "" : "/"; + } + const url = new URL(this.options.url, base); + let params = { + r: Date.now(), + }; + if (this.options.server) { + // 0 based + params[this.options.serverParams.start] = this.page - 1; + params[this.options.serverParams.length] = this.options.perPage; + if (this.options.filter) params[this.options.serverParams.search] = this.getFilters(); + params[this.options.serverParams.sort] = this.getSort() || ""; + params[this.options.serverParams.sortDir] = this.getSortDir(); + + // extra params ? + if (this.meta?.[this.options.serverParams.paramsKey]) { + params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]); + } + } + + appendParamsToUrl(url, params); + + return fetch(url).then((response) => { + const newError = new Error(response.statusText || labels.networkError); + if (!response.ok) { + // @ts-ignore + newError.response = response; + throw newError; + } + return response + .clone() + .json() + .catch((err) => { + let error = err; + if (!this.options.debug) { + error = newError; + } + error.response = response; + throw error; + }); + }); + } + + renderTable() { + this.log("render table"); + + if (this.options.menu && this.plugins.ContextMenu) { + this.plugins.ContextMenu.createMenu(); + } + + let sortedColumn; + + this.renderHeader(); + if (this.options.defaultSort) { + // We can have a default sort even with sort disabled + sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`); + } + + if (sortedColumn) { + this.sortData(sortedColumn); + } else { + this.renderBody(); + } + + this.renderFooter(); + } + + /** + * Create table header + * - One row for the column headers + * - One row for the filters + */ + renderHeader() { + this.log("render header"); + + const thead = this.thead; + this.createColumnHeaders(thead); + this.createColumnFilters(thead); + + if (this.options.resizable && this.plugins.ColumnResizer) { + this.plugins.ColumnResizer.renderResizer(labels.resizeColumn); + } + + dispatch(this, "headerRendered"); + } + + renderFooter() { + this.log("render footer"); + + const tfoot = this.tfoot; if (!tfoot) return; - const td = tfoot.querySelector("td"); - tfoot.removeAttribute("hidden"); - setAttribute(td, "colspan", this.columnsLength(true)); - tfoot.style.display = ""; - } - - /** - * Create the column headers based on column definitions and set options - * @param {HTMLTableSectionElement} thead - */ - createColumnHeaders(thead) { - // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively - const availableWidth = this.clientWidth; - const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2); - - let idx = 0; - let tr; - - // Create row - tr = ce("tr"); - this.headerRow = tr; - tr.setAttribute("role", "row"); - tr.setAttribute("aria-rowindex", "1"); - tr.setAttribute("class", "dg-head-columns"); - - // We need a real th from the dom to compute the size + const td = tfoot.querySelector("td"); + tfoot.removeAttribute("hidden"); + setAttribute(td, "colspan", this.columnsLength(true)); + tfoot.style.display = ""; + } + + /** + * Create the column headers based on column definitions and set options + * @param {HTMLTableSectionElement} thead + */ + createColumnHeaders(thead) { + // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively + const availableWidth = this.clientWidth; + const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2); + + let idx = 0; + let tr; + + // Create row + tr = ce("tr"); + this.headerRow = tr; + tr.setAttribute("role", "row"); + tr.setAttribute("aria-rowindex", "1"); + tr.setAttribute("class", "dg-head-columns"); + + // We need a real th from the dom to compute the size let sampleTh = thead?.querySelector("tr.dg-head-columns th"); - this.log("createColumnHeaders - sampleTh", sampleTh); - if (!sampleTh) { - sampleTh = ce("th"); - thead?.querySelector("tr").appendChild(sampleTh); - } - - if (this.options.selectable && this.plugins.SelectableRows) { - this.plugins.SelectableRows.createHeaderCol(tr); - } - if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) { - this.plugins.ResponsiveGrid.createHeaderCol(tr); - } - - // Create columns - idx = 0; - let totalWidth = 0; - this.log("createColumnHeaders - columns", this.options.columns); - - for (const column of this.options.columns) { - if (column.attr) { - continue; - } - const colIdx = idx + this.startColIndex(); - const th = ce("th"); - th.setAttribute("scope", "col"); - th.setAttribute("role", "columnheader button"); - th.setAttribute("aria-colindex", `${colIdx}`); - th.setAttribute("id", randstr("dg-col-")); - if (this.options.sort) { - th.setAttribute("aria-sort", "none"); - } - th.setAttribute("field", column.field); - if (this.plugins.ResponsiveGrid && this.options.responsive) { - setAttribute(th, "data-responsive", column.responsive || ""); - } - // Make sure the header fits (+ add some room for sort icon if necessary) - const computedWidth = getTextWidth(column.title, sampleTh, true) + 20; - th.dataset.minWidth = `${computedWidth}`; - applyColumnDefinition(th, column); - th.tabIndex = 0; - th.textContent = column.title; - - let w = 0; - // Autosize small based on first/last row ? - // Take into account minWidth of the header and max available size based on col numbers - if (this.options.autosize && this.plugins.AutosizeColumn) { - const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth); - w = this.plugins.AutosizeColumn.computeSize( - th, - column, - Number.parseInt(th.dataset.minWidth), - colAvailableWidth, - ); - } else { - w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute("width"))); - } - - setAttribute(th, "width", w); - if (column.hidden) { - th.setAttribute("hidden", ""); - } else { - totalWidth += w; - } - - // Reorder columns with drag/drop - if (this.options.reorder && this.plugins.DraggableHeaders) { - this.plugins.DraggableHeaders.makeHeaderDraggable(th); - } - - tr.appendChild(th); - idx++; - } - - // There is too much available width, and we want to avoid fixed layout to split remaining amount - if (totalWidth < availableWidth) { - const visibleCols = findAll(tr, "th:not([hidden],.dg-not-resizable)"); - if (visibleCols.length) { - const lastCol = visibleCols[visibleCols.length - 1]; - removeAttribute(lastCol, "width"); - } - } - - // Actions - if (this.options.actions.length && this.plugins.RowActions) { - this.plugins.RowActions.makeActionHeader(tr); - } - - thead?.replaceChild(tr, thead.querySelector("tr.dg-head-columns")); - - // Once columns are inserted, we have an actual dom to query - if (thead && thead.offsetWidth > availableWidth) { - this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`); - const scrollbarWidth = this.offsetWidth - this.clientWidth; - let diff = thead.offsetWidth - availableWidth - scrollbarWidth; - if (this.options.responsive && this.plugins.ResponsiveGrid) { - diff += scrollbarWidth; - } - // Remove diff for columns that can afford it - const thWithWidth = findAll(tr, "th[width]"); - - for (const th of thWithWidth) { - if (hasClass(th, "dg-not-resizable")) { - continue; - } - if (diff <= 0) { - continue; - } - const actualWidth = Number.parseInt(th.getAttribute("width")); - const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0; - if (actualWidth > minWidth) { - let newWidth = actualWidth - diff; - if (newWidth < minWidth) { - newWidth = minWidth; - } - diff -= actualWidth - newWidth; - setAttribute(th, "width", newWidth); - } - } - } - - // Context menu - if (this.options.menu && this.plugins.ContextMenu) { - this.plugins.ContextMenu.attachContextMenu(); - } - - // Sort col on click - const rowsWithSort = findAll(tr, "[aria-sort]"); - for (const sortableRow of rowsWithSort) { - sortableRow.addEventListener("click", () => this.sortData(sortableRow)); - } - - this.table && setAttribute(this.table, "aria-colcount", this.columnsLength(true)); - } - - createColumnFilters(thead) { - let idx = 0; - let tr; - - // Create row for filters - tr = ce("tr"); - this.filterRow = tr; - tr.setAttribute("role", "row"); - tr.setAttribute("aria-rowindex", "2"); - tr.setAttribute("class", "dg-head-filters"); - if (!this.options.filter) { - tr.setAttribute("hidden", ""); - } - - if (this.options.selectable && this.plugins.SelectableRows) { - this.plugins.SelectableRows.createFilterCol(tr); - } - if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) { - this.plugins.ResponsiveGrid.createFilterCol(tr); - } - - this.log("createColumnFilters - columns", this.options.columns); - for (const column of this.options.columns) { - if (column.attr) { - continue; - } - const colIdx = idx + this.startColIndex(); - const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex="${colIdx}"]`); - if (!relatedTh) { - console.warn("Related th not found", colIdx); - continue; - } - const th = ce("th"); - th.setAttribute("aria-colindex", `${colIdx}`); - - const filter = this.createFilterElement(column, relatedTh); - if (!this.options.filter) { - th.tabIndex = 0; - } else { - filter.tabIndex = 0; - } - - if (column.hidden) { - th.setAttribute("hidden", ""); - } - - th.appendChild(filter); - tr.appendChild(th); - idx++; - } - - // Actions - if (this.options.actions.length && this.plugins.RowActions) { - this.plugins.RowActions.makeActionFilter(tr); - } - - thead?.replaceChild(tr, thead.querySelector("tr.dg-head-filters")); - - if (typeof this.options.filterKeypressDelay !== "number" || this.options.filterOnEnter) - this.options.filterKeypressDelay = 0; - - // Filter content by field events - const filteredRows = findAll(tr, this._filterSelector); - for (const el of filteredRows) { - const eventName = /select/i.test(el.tagName) ? "change" : "keyup"; - const eventHandler = debounce((e) => { - const key = e.keyCode || e.key; - const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key); - if (key === 13 || key === "Enter" || isKeyPressFilter || e.type === "change") { - this.filterData.call(this); - } - }, this.options.filterKeypressDelay); - el.addEventListener(eventName, eventHandler); - } - } - - createFilterElement(column, relatedTh) { - const isSelect = column.filterType === "select"; - const filter = isSelect ? ce("select") : ce("input"); - if (isSelect) { - if (!Array.isArray(column.filterList)) { - // Gets unique values from column records - const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))] - .filter((v) => v) - .sort(); - column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat( - uniqueValues.map((e) => ({ value: e, text: e })), - ); - } - - for (const e of column.filterList) { - const opt = ce("option"); - opt.value = e.value; - opt.text = e.text; - - if (filter instanceof HTMLSelectElement) { - filter.add(opt); - } - } - } else { - //@ts-ignore - filter.type = "text"; - filter.inputMode = "search"; - filter.autocomplete = "off"; - filter.spellcheck = false; - } - // Allows binding filter to this column - filter.dataset.name = column.field; - filter.id = randstr("dg-filter-"); - // Don't use aria-label as it triggers autocomplete - filter.setAttribute("aria-labelledby", relatedTh.getAttribute("id")); - return filter; - } - - /** - * Render the data as rows in tbody - * It will call paginate() at the end - */ - renderBody() { - this.log("render body"); - let tr; - let td; - let idx; - const tbody = ce("tbody"); - - this.data.forEach((item, i) => { - tr = ce("tr"); - setAttribute(tr, "role", "row"); - setAttribute(tr, "hidden", ""); - setAttribute(tr, "aria-rowindex", i + 1); - tr.tabIndex = 0; - - if (this.options.selectable && this.plugins.SelectableRows) { - this.plugins.SelectableRows.createDataCol(tr); - } - if ( - this.options.responsive && - this.plugins.ResponsiveGrid && - this.plugins.ResponsiveGrid.hasHiddenColumns() - ) { - this.plugins.ResponsiveGrid.createDataCol(tr); - } - - // Expandable - if (this.options.expand) { - tr.classList.add("dg-expandable"); - + this.log("createColumnHeaders - sampleTh", sampleTh); + if (!sampleTh) { + sampleTh = ce("th"); + thead?.querySelector("tr").appendChild(sampleTh); + } + + if (this.options.selectable && this.plugins.SelectableRows) { + this.plugins.SelectableRows.createHeaderCol(tr); + } + if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) { + this.plugins.ResponsiveGrid.createHeaderCol(tr); + } + + // Create columns + idx = 0; + let totalWidth = 0; + this.log("createColumnHeaders - columns", this.options.columns); + + for (const column of this.options.columns) { + if (column.attr) { + continue; + } + const colIdx = idx + this.startColIndex(); + const th = ce("th"); + th.setAttribute("scope", "col"); + th.setAttribute("role", "columnheader button"); + th.setAttribute("aria-colindex", `${colIdx}`); + th.setAttribute("id", randstr("dg-col-")); + if (this.options.sort) { + th.setAttribute("aria-sort", "none"); + } + th.setAttribute("field", column.field); + if (this.plugins.ResponsiveGrid && this.options.responsive) { + setAttribute(th, "data-responsive", column.responsive || ""); + } + // Make sure the header fits (+ add some room for sort icon if necessary) + const computedWidth = getTextWidth(column.title, sampleTh, true) + 20; + th.dataset.minWidth = `${computedWidth}`; + applyColumnDefinition(th, column); + th.tabIndex = 0; + th.textContent = column.title; + + let w = 0; + // Autosize small based on first/last row ? + // Take into account minWidth of the header and max available size based on col numbers + if (this.options.autosize && this.plugins.AutosizeColumn) { + const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth); + w = this.plugins.AutosizeColumn.computeSize( + th, + column, + Number.parseInt(th.dataset.minWidth), + colAvailableWidth, + ); + } else { + w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute("width"))); + } + + setAttribute(th, "width", w); + if (column.hidden) { + th.setAttribute("hidden", ""); + } else { + totalWidth += w; + } + + // Reorder columns with drag/drop + if (this.options.reorder && this.plugins.DraggableHeaders) { + this.plugins.DraggableHeaders.makeHeaderDraggable(th); + } + + tr.appendChild(th); + idx++; + } + + // There is too much available width, and we want to avoid fixed layout to split remaining amount + if (totalWidth < availableWidth) { + const visibleCols = findAll(tr, "th:not([hidden],.dg-not-resizable)"); + if (visibleCols.length) { + const lastCol = visibleCols[visibleCols.length - 1]; + removeAttribute(lastCol, "width"); + } + } + + // Actions + if (this.options.actions.length && this.plugins.RowActions) { + this.plugins.RowActions.makeActionHeader(tr); + } + + thead?.replaceChild(tr, thead.querySelector("tr.dg-head-columns")); + + // Once columns are inserted, we have an actual dom to query + if (thead && thead.offsetWidth > availableWidth) { + this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`); + const scrollbarWidth = this.offsetWidth - this.clientWidth; + let diff = thead.offsetWidth - availableWidth - scrollbarWidth; + if (this.options.responsive && this.plugins.ResponsiveGrid) { + diff += scrollbarWidth; + } + // Remove diff for columns that can afford it + const thWithWidth = findAll(tr, "th[width]"); + + for (const th of thWithWidth) { + if (hasClass(th, "dg-not-resizable")) { + continue; + } + if (diff <= 0) { + continue; + } + const actualWidth = Number.parseInt(th.getAttribute("width")); + const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0; + if (actualWidth > minWidth) { + let newWidth = actualWidth - diff; + if (newWidth < minWidth) { + newWidth = minWidth; + } + diff -= actualWidth - newWidth; + setAttribute(th, "width", newWidth); + } + } + } + + // Context menu + if (this.options.menu && this.plugins.ContextMenu) { + this.plugins.ContextMenu.attachContextMenu(); + } + + // Sort col on click + const rowsWithSort = findAll(tr, "[aria-sort]"); + for (const sortableRow of rowsWithSort) { + sortableRow.addEventListener("click", () => this.sortData(sortableRow)); + } + + this.table && setAttribute(this.table, "aria-colcount", this.columnsLength(true)); + } + + createColumnFilters(thead) { + let idx = 0; + let tr; + + // Create row for filters + tr = ce("tr"); + this.filterRow = tr; + tr.setAttribute("role", "row"); + tr.setAttribute("aria-rowindex", "2"); + tr.setAttribute("class", "dg-head-filters"); + if (!this.options.filter) { + tr.setAttribute("hidden", ""); + } + + if (this.options.selectable && this.plugins.SelectableRows) { + this.plugins.SelectableRows.createFilterCol(tr); + } + if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) { + this.plugins.ResponsiveGrid.createFilterCol(tr); + } + + this.log("createColumnFilters - columns", this.options.columns); + for (const column of this.options.columns) { + if (column.attr) { + continue; + } + const colIdx = idx + this.startColIndex(); + const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex="${colIdx}"]`); + if (!relatedTh) { + console.warn("Related th not found", colIdx); + continue; + } + const th = ce("th"); + th.setAttribute("aria-colindex", `${colIdx}`); + + const filter = this.createFilterElement(column, relatedTh); + if (!this.options.filter) { + th.tabIndex = 0; + } else { + filter.tabIndex = 0; + } + + if (column.hidden) { + th.setAttribute("hidden", ""); + } + + th.appendChild(filter); + tr.appendChild(th); + idx++; + } + + // Actions + if (this.options.actions.length && this.plugins.RowActions) { + this.plugins.RowActions.makeActionFilter(tr); + } + + thead?.replaceChild(tr, thead.querySelector("tr.dg-head-filters")); + + if (typeof this.options.filterKeypressDelay !== "number" || this.options.filterOnEnter) + this.options.filterKeypressDelay = 0; + + // Filter content by field events + const filteredRows = findAll(tr, this._filterSelector); + for (const el of filteredRows) { + const isSelect = /select/i.test(el.tagName); + const eventName = isSelect ? "change" : "keyup"; + const eventHandler = debounce((e) => { + const key = e.keyCode || e.key; + const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key); + if (key === 13 || key === "Enter" || isKeyPressFilter || e.type === "change" || e.type === "paste") { + this.filterData.call(this); + } + }, this.options.filterKeypressDelay); + el.addEventListener(eventName, eventHandler); + if (!isSelect) { // Add paste event support for text input filters + el.addEventListener("paste", eventHandler); + } + } + } + + createFilterElement(column, relatedTh) { + const isSelect = column.filterType === "select"; + const filter = isSelect ? ce("select") : ce("input"); + if (isSelect) { + if (!Array.isArray(column.filterList)) { + // Gets unique values from column records + const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))] + .filter((v) => v) + .sort(); + column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat( + uniqueValues.map((e) => ({ value: e, text: e })), + ); + } + + for (const e of column.filterList) { + const opt = ce("option"); + opt.value = e.value; + opt.text = e.text; + + if (filter instanceof HTMLSelectElement) { + filter.add(opt); + } + } + } else { + //@ts-ignore + filter.type = "text"; + filter.inputMode = "search"; + filter.autocomplete = "off"; + filter.spellcheck = false; + } + // Allows binding filter to this column + filter.dataset.name = column.field; + filter.id = randstr("dg-filter-"); + // Don't use aria-label as it triggers autocomplete + filter.setAttribute("aria-labelledby", relatedTh.getAttribute("id")); + return filter; + } + + /** + * Render the data as rows in tbody + * It will call paginate() at the end + */ + renderBody() { + this.log("render body"); + let tr; + let td; + let idx; + const tbody = ce("tbody"); + + this.data.forEach((item, i) => { + tr = ce("tr"); + setAttribute(tr, "role", "row"); + setAttribute(tr, "hidden", ""); + setAttribute(tr, "aria-rowindex", i + 1); + tr.tabIndex = 0; + + if (this.options.selectable && this.plugins.SelectableRows) { + this.plugins.SelectableRows.createDataCol(tr); + } + if ( + this.options.responsive && + this.plugins.ResponsiveGrid && + this.plugins.ResponsiveGrid.hasHiddenColumns() + ) { + this.plugins.ResponsiveGrid.createDataCol(tr); + } + + // Expandable + if (this.options.expand) { + tr.classList.add("dg-expandable"); + on(tr, "click", (ev) => { - if (ev.target.matches(this._excludedRowElementSelector)) return; - if (this.plugins.ResponsiveGrid) { - this.plugins.ResponsiveGrid.blockObserver(); - } - toggleClass(ev.currentTarget, "dg-expanded"); - if (this.plugins.ResponsiveGrid) { - this.plugins.ResponsiveGrid.unblockObserver(); - } - }); - } - - idx = 0; - - for (const column of this.options.columns) { - if (!column) { - console.error("Empty column found!", this.options.columns); - } - // It should be applied as an attr of the row - if (column.attr) { - if (item[column.field]) { - // Special case if we try to write over the class attr - if (column.attr === "class") { - addClass(tr, item[column.field]); - } else { - tr.setAttribute(column.attr, item[column.field]); - } - } - return; - } - td = ce("td"); - td.setAttribute("role", "gridcell"); - td.setAttribute("aria-colindex", `${idx}${this.startColIndex()}`); - applyColumnDefinition(td, column); - // This is required for pure css responsive layout - td.setAttribute("data-name", column.title); - td.tabIndex = -1; - - // Inline editing ... - if (column.editable && this.plugins.EditableColumn) { - addClass(td, "dg-editable-col"); - this.plugins.EditableColumn.makeEditableInput(td, column, item, i); - } else { - // ... or formatting - const v = item[column.field] ?? ""; - let tv; - // TODO: make this modular - switch (column.transform) { - case "uppercase": - tv = v.toUpperCase(); - break; - case "lowercase": - tv = v.toLowerCase(); - break; - default: - tv = v; - break; - } - if (column.format) { - // Only use formatting with values or if defaultFormatValue is set - if (column.defaultFormatValue !== undefined && (tv === "" || tv === null)) { - tv = `${column.defaultFormatValue}`; - } - if (typeof column.format === "string" && tv) { - td.innerHTML = interpolate( - // @ts-ignore - column.format, - Object.assign( - { - _v: v, - _tv: tv, - }, - item, - ), - ); - } else if (column.format instanceof Function) { - const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr }); - td.innerHTML = val || tv || v; - } - } else { - td.textContent = tv; - } - } - tr.appendChild(td); - idx++; - } - - // Actions - if (this.options.actions.length && this.plugins.RowActions) { - this.plugins.RowActions.makeActionRow(tr, item); - } - - tbody.appendChild(tr); - - dispatch(this, "rowRendered", { rowData: item, tr }); - }); - - tbody.setAttribute("role", "rowgroup"); - - // Keep data empty message - const prev = this.tbody; - prev && tbody.setAttribute("data-empty", prev.getAttribute("data-empty")); - this.table?.replaceChild(tbody, prev); - - if (this.plugins.FixedHeight) { - this.plugins.FixedHeight.createFakeRow(); - } - - this.paginate(); - - if (this.plugins.SelectableRows) { - this.plugins.SelectableRows.shouldSelectAll(tbody); - } - - this.classList.toggle("dg-empty", !this.data.length); - - dispatch(this, "bodyRendered"); - } - - paginate() { - this.log("paginate"); - - const total = this.totalRecords(); - const p = this.page || 1; - const tbody = this.tbody; - const tfoot = this.tfoot; + if (ev.target.matches(this._excludedRowElementSelector)) return; + if (this.plugins.ResponsiveGrid) { + this.plugins.ResponsiveGrid.blockObserver(); + } + toggleClass(ev.currentTarget, "dg-expanded"); + if (this.plugins.ResponsiveGrid) { + this.plugins.ResponsiveGrid.unblockObserver(); + } + }); + } + + idx = 0; + + for (const column of this.options.columns) { + if (!column) { + console.error("Empty column found!", this.options.columns); + } + // It should be applied as an attr of the row + if (column.attr) { + if (item[column.field]) { + // Special case if we try to write over the class attr + if (column.attr === "class") { + addClass(tr, item[column.field]); + } else { + tr.setAttribute(column.attr, item[column.field]); + } + } + return; + } + td = ce("td"); + td.setAttribute("role", "gridcell"); + td.setAttribute("aria-colindex", `${idx}${this.startColIndex()}`); + applyColumnDefinition(td, column); + // This is required for pure css responsive layout + td.setAttribute("data-name", column.title); + td.tabIndex = -1; + + // Inline editing ... + if (column.editable && this.plugins.EditableColumn) { + addClass(td, "dg-editable-col"); + this.plugins.EditableColumn.makeEditableInput(td, column, item, i); + } else { + // ... or formatting + const v = item[column.field] ?? ""; + let tv; + // TODO: make this modular + switch (column.transform) { + case "uppercase": + tv = v.toUpperCase(); + break; + case "lowercase": + tv = v.toLowerCase(); + break; + default: + tv = v; + break; + } + if (column.format) { + // Only use formatting with values or if defaultFormatValue is set + if (column.defaultFormatValue !== undefined && (tv === "" || tv === null)) { + tv = `${column.defaultFormatValue}`; + } + if (typeof column.format === "string" && tv) { + td.innerHTML = interpolate( + // @ts-ignore + column.format, + Object.assign( + { + _v: v, + _tv: tv, + }, + item, + ), + ); + } else if (column.format instanceof Function) { + const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr }); + td.innerHTML = val || tv || v; + } + } else { + td.textContent = tv; + } + } + tr.appendChild(td); + idx++; + } + + // Actions + if (this.options.actions.length && this.plugins.RowActions) { + this.plugins.RowActions.makeActionRow(tr, item); + } + + tbody.appendChild(tr); + + dispatch(this, "rowRendered", { rowData: item, tr }); + }); + + tbody.setAttribute("role", "rowgroup"); + + // Keep data empty message + const prev = this.tbody; + prev && tbody.setAttribute("data-empty", prev.getAttribute("data-empty")); + this.table?.replaceChild(tbody, prev); + + if (this.plugins.FixedHeight) { + this.plugins.FixedHeight.createFakeRow(); + } + + this.paginate(); + + if (this.plugins.SelectableRows) { + this.plugins.SelectableRows.shouldSelectAll(tbody); + } + + this.classList.toggle("dg-empty", !this.data.length); + + dispatch(this, "bodyRendered"); + } + + paginate() { + this.log("paginate"); + + const total = this.totalRecords(); + const p = this.page || 1; + const tbody = this.tbody; + const tfoot = this.tfoot; if (!tbody || !tfoot) return; - const bodyRows = findAll(tbody, "tr"); - - // Refresh page count in case we added/removed a page - this.pages = this.totalPages(); - - let index; - let high = p * this.options.perPage; - let low = high - this.options.perPage + 1; - - if (high > total) { - high = total; - } - if (!total) { - low = 0; - } - - // Display all rows within the set indexes - // For server side paginated grids, we display everything - // since the server is taking care of actual pagination - for (const tr of bodyRows) { - if (this.options.server) { - removeAttribute(tr, "hidden"); - continue; - } - index = Number(getAttribute(tr, "aria-rowindex")); - if (index > high || index < low) { - setAttribute(tr, "hidden", ""); - } else { - removeAttribute(tr, "hidden"); - } - } - - if (this.options.selectable && this.plugins.SelectableRows) { - this.plugins.SelectableRows.clearCheckboxes(tbody); - } - - // Store default height and update styles if needed - if (this.plugins.FixedHeight) { - this.plugins.FixedHeight.updateFakeRow(); - } - - // Enable/disable buttons if shown - if (this.btnFirst) { - this.btnFirst.disabled = this.page <= 1; - this.btnPrev.disabled = this.page <= 1; - this.btnNext.disabled = this.page >= this.pages; - this.btnLast.disabled = this.page >= this.pages; - } - tfoot.querySelector(".dg-low").textContent = low.toString(); - tfoot.querySelector(".dg-high").textContent = high.toString(); - tfoot.querySelector(".dg-total").textContent = `${this.totalRecords()}`; - tfoot.toggleAttribute("hidden", this.options.autohidePager && this.options.perPage > this.totalRecords()); - } - - /** - * @returns {number} - */ - totalPages() { - return Math.ceil(this.totalRecords() / this.options.perPage); - } - - /** - * @returns {number} - */ - totalRecords() { - if (this.options.server) { - return this.meta?.[this.options.serverParams.metaFilteredKey] || 0; - } - return this.data.length; - } -} - -export default DataGrid; + const bodyRows = findAll(tbody, "tr"); + + // Refresh page count in case we added/removed a page + this.pages = this.totalPages(); + + let index; + let high = p * this.options.perPage; + let low = high - this.options.perPage + 1; + + if (high > total) { + high = total; + } + if (!total) { + low = 0; + } + + // Display all rows within the set indexes + // For server side paginated grids, we display everything + // since the server is taking care of actual pagination + for (const tr of bodyRows) { + if (this.options.server) { + removeAttribute(tr, "hidden"); + continue; + } + index = Number(getAttribute(tr, "aria-rowindex")); + if (index > high || index < low) { + setAttribute(tr, "hidden", ""); + } else { + removeAttribute(tr, "hidden"); + } + } + + if (this.options.selectable && this.plugins.SelectableRows) { + this.plugins.SelectableRows.clearCheckboxes(tbody); + } + + // Store default height and update styles if needed + if (this.plugins.FixedHeight) { + this.plugins.FixedHeight.updateFakeRow(); + } + + // Enable/disable buttons if shown + if (this.btnFirst) { + this.btnFirst.disabled = this.page <= 1; + this.btnPrev.disabled = this.page <= 1; + this.btnNext.disabled = this.page >= this.pages; + this.btnLast.disabled = this.page >= this.pages; + } + tfoot.querySelector(".dg-low").textContent = low.toString(); + tfoot.querySelector(".dg-high").textContent = high.toString(); + tfoot.querySelector(".dg-total").textContent = `${this.totalRecords()}`; + tfoot.toggleAttribute("hidden", this.options.autohidePager && this.options.perPage > this.totalRecords()); + } + + /** + * @returns {number} + */ + totalPages() { + return Math.ceil(this.totalRecords() / this.options.perPage); + } + + /** + * @returns {number} + */ + totalRecords() { + if (this.options.server) { + return this.meta?.[this.options.serverParams.metaFilteredKey] || 0; + } + return this.data.length; + } +} + +export default DataGrid; From d086d3de3d757070832b2d80614e124bd9cb0585 Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Mon, 10 Aug 2026 09:25:23 -0400 Subject: [PATCH 4/4] =?UTF-8?q?Fixed=20sort=20icons=20incorrectly=20render?= =?UTF-8?q?ing=20for=20noSort=20columns.=20=E2=80=A2=20Added=20dg-not-sort?= =?UTF-8?q?able=20class=20to=20=20elements=20in=20applyColumnDefinitio?= =?UTF-8?q?n=20when=20column.noSort=20is=20true.=20=E2=80=A2=20Restricted?= =?UTF-8?q?=20class=20assignment=20to=20=20elements=20only,=20excludin?= =?UTF-8?q?g=20=20body=20cells.=20=E2=80=A2=20Fixed=20a=20return/conti?= =?UTF-8?q?nue=20regression=20in=20sortChanged=20left=20over=20from=20a=20?= =?UTF-8?q?past=20forEach-to-for...of=20refactor,=20which=20caused=20the?= =?UTF-8?q?=20loop=20to=20exit=20early=20instead=20of=20skipping=20only=20?= =?UTF-8?q?the=20current=20non-sortable=20column.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/data-grid.js | 7 +++- dist/data-grid.js.map | 4 +- dist/data-grid.min.js | 10 ++--- dist/data-grid.min.js.map | 4 +- src/data-grid.js | 83 ++++++++++++++++++++------------------- 5 files changed, 57 insertions(+), 51 deletions(-) diff --git a/dist/data-grid.js b/dist/data-grid.js index 6b8ebe4..322133f 100644 --- a/dist/data-grid.js +++ b/dist/data-grid.js @@ -406,6 +406,9 @@ function applyColumnDefinition(el, column) { addClass(el, "dg-responsive-hidden"); } } + if (column.noSort && el.tagName === "TH") { + addClass(el, "dg-not-sortable"); + } } var DataGrid = class _DataGrid extends base_element_default { _filterSelector = "[id^=dg-filter]"; @@ -1026,7 +1029,7 @@ var DataGrid = class _DataGrid extends base_element_default { for (const th of headers) { const fieldName = th.getAttribute("field"); if (th.classList.contains("dg-not-sortable") || !this.fireEvents && fieldName === this.options.defaultSort) { - return; + continue; } if (this.options.sort && !this.getColProp(fieldName, "noSort")) { setAttribute(th, "aria-sort", "none"); @@ -1504,7 +1507,7 @@ var DataGrid = class _DataGrid extends base_element_default { th.setAttribute("role", "columnheader button"); th.setAttribute("aria-colindex", `${colIdx}`); th.setAttribute("id", randstr("dg-col-")); - if (this.options.sort) { + if (this.options.sort && !column.noSort) { th.setAttribute("aria-sort", "none"); } th.setAttribute("field", column.field); diff --git a/dist/data-grid.js.map b/dist/data-grid.js.map index 8706248..dcaf37a 100644 --- a/dist/data-grid.js.map +++ b/dist/data-grid.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/utils/camelize.js", "../src/utils/normalizeData.js", "../src/utils/shortcuts.js", "../src/core/base-element.js", "../src/utils/addSelectOption.js", "../src/utils/appendParamsToUrl.js", "../src/utils/convertArray.js", "../src/utils/elementOffset.js", "../src/utils/interpolate.js", "../src/utils/getTextWidth.js", "../src/utils/randstr.js", "../src/utils/debounce.js", "../src/data-grid.js", "../src/core/base-plugin.js", "../src/plugins/column-resizer.js", "../src/utils/getParentElement.js", "../src/plugins/context-menu.js", "../src/plugins/draggable-headers.js", "../src/plugins/touch-support.js", "../src/plugins/selectable-rows.js", "../src/plugins/fixed-height.js", "../src/plugins/autosize-column.js", "../src/plugins/responsive-grid.js", "../src/plugins/row-actions.js", "../src/plugins/editable-column.js", "../src/plugins/spinner-support.js", "../src/plugins/save-state.js", "../data-grid.js"], - "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const isSelect = /select/i.test(el.tagName);\r\n const eventName = isSelect ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\" || e.type === \"paste\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n if (!isSelect) { // Add paste event support for text input filters\r\n el.addEventListener(\"paste\", eventHandler);\r\n }\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], - "mappings": "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", + "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\n if (column.width) {\n setAttribute(el, \"width\", column.width);\n }\n if (column.class) {\n addClass(el, column.class);\n }\n if (column.hidden) {\n setAttribute(el, \"hidden\", \"\");\n if (column.responsiveHidden) {\n addClass(el, \"dg-responsive-hidden\");\n }\n }\n if (column.noSort && el.tagName === \"TH\") {\n addClass(el, \"dg-not-sortable\");\n }\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\n this.log(\"toggle sort\");\n\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\n for (const th of headers) {\n const fieldName = th.getAttribute(\"field\");\n if (\n th.classList.contains(\"dg-not-sortable\") ||\n (!this.fireEvents && fieldName === this.options.defaultSort)\n ) {\n continue;\n }\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\n setAttribute(th, \"aria-sort\", \"none\");\n } else {\n removeAttribute(th, \"aria-sort\");\n }\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\n if (this.options.sort && !column.noSort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\n }\n // Make sure the header fits (+ add some room for sort icon if necessary)\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\n th.dataset.minWidth = `${computedWidth}`;\n applyColumnDefinition(th, column);\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const isSelect = /select/i.test(el.tagName);\r\n const eventName = isSelect ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\" || e.type === \"paste\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n if (!isSelect) { // Add paste event support for text input filters\r\n el.addEventListener(\"paste\", eventHandler);\r\n }\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], + "mappings": "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", "names": ["col", "e", "th", "labels", "filters", "data_grid_default"] } diff --git a/dist/data-grid.min.js b/dist/data-grid.min.js index 1670135..a176ba5 100644 --- a/dist/data-grid.min.js +++ b/dist/data-grid.min.js @@ -1,4 +1,4 @@ -function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUpperCase())}function V(r){if(r==="true")return!0;if(r==="false")return!1;if(r===""||r==="null")return null;if(r===Number(r).toString())return Number(r);if(r&&typeof r.substring=="function"&&["[","{"].includes(r.substring(0,1)))try{let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(decodeURIComponent(t))}catch{return console.error(`Failed to parse ${r}`),{}}return r}var zt=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];function vt(r){return zt.includes(r)?{passive:!0}:{}}function D(r,t){return r.getAttribute(t)}function U(r,t){return r.hasAttribute(t)}function c(r,t,e="",i=!1){i&&U(r,t)||r.setAttribute(t,`${e}`)}function k(r,t){U(r,t)&&r.removeAttribute(t)}function S(r,t,e){r.addEventListener(t,e,vt(t))}function O(r,t,e){r.removeEventListener(t,e,vt(t))}function y(r,t,e={},i=!1){let o={};i&&(o.bubbles=!0),e&&(o.detail=e),r.dispatchEvent(new CustomEvent(t,o))}function T(r,t){return r.classList.contains(t)}function E(r,t){r.classList.add(...t.split(" "))}function W(r,t){r.classList.remove(...t.split(" "))}function yt(r,t){r.classList.toggle(t)}function I(r,t=document){return r instanceof HTMLElement?r:t.querySelector(r)}function Y(r,t=document){return Array.from(t.querySelectorAll(r))}function N(r,t){return I(t,r)}function g(r,t){return Y(t,r)}function x(r,t=null){let e=document.createElement(r);return t&&t.appendChild(e),e}function xt(r,t){t.parentNode.insertBefore(r,t.nextSibling)}var J=class extends HTMLElement{constructor(t={}){super(),this.options=Object.assign({},this.defaultOptions,this.normalizedDataset,t),this.log("constructor"),this.setup=!1,this.fireEvents=!0,this._ready(),this.log("ready")}get defaultOptions(){return{}}getOption(t){return this.options[t]}setOption(t,e){c(this,`data-${t}`,e)}toggleOption(t){c(this,`data-${t}`,!this.getOption(t))}get normalizedDataset(){let t=this.dataset.config?JSON.parse(this.dataset.config):{},e={...this.dataset};for(let i in e)i==="config"||!e.hasOwnProperty(i)||typeof e[i]=="function"||(e[i]=V(e[i]));return Object.assign(e,t),e}static template(){return""}_ready(){}log(...t){this.options.debug&&console.log(`[${D(this,"id")}] `,...t)}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}_connected(){}connectedCallback(){this.setup||(this.setup=!0,setTimeout(async()=>{this.log("connectedCallback");let t=document.createElement("template");t.innerHTML=this.constructor.template(),this.appendChild(t.content.cloneNode(!0)),await this._connected(),y(this,"connected")},0))}_disconnected(){}disconnectedCallback(){setTimeout(()=>{!this.isConnected&&this.setup&&(this.log("disconnectedCallback"),this._disconnected(),y(this,"disconnected"),this.setup=!1)},0)}get transformAttributes(){return{}}attributeChangedCallback(t,e,i){if(e===i)return;this.log(`attributeChangedCallback: ${t}`);let o=!1,n=this.transformAttributes[t]??V,s=t;s.indexOf("data-")===0&&(s=s.slice(5),o=!0),s=F(s),o?this.options[s]=n(i):this[s]=n(i),this.fireEvents&&this[`${s}Changed`]&&this[`${s}Changed`]()}},Ct=J;function Z(r,t,e,i=!1){let o=document.createElement("option");o.value=`${t}`,i&&(o.selected=!0),o.label=e,r.appendChild(o)}function Q(r,t={}){for(let e of Object.keys(t))if(Array.isArray(t[e]))for(let i of Object.keys(t[e]))r.searchParams.append(isNaN(i)?`${e}[${i}]`:e,t[e][i]);else r.searchParams.append(e,t[e])}function X(r){if(typeof r=="string"){if(r[0]==="["){let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(t)}return r.split(",")}return Array.isArray(r)?r:(console.error("Invalid array",r),[])}function tt(r){let t=r.getBoundingClientRect(),e=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+i,left:t.left+e}}function M(r,t){return r.replace(/\{([^}]+)?\}/g,(e,i)=>t[i])}var et;function _(r,t=document.body,e=!1){let i=window.getComputedStyle(t||document.createElement("div")),o=i.getPropertyValue("font-weight")||"normal",n=i.getPropertyValue("font-size")||"1rem",s=i.getPropertyValue("font-family")||"Arial",a=0;if(e){let h=i.getPropertyValue("padding-left")||"0",u=i.getPropertyValue("padding-right")||"0";a=Number.parseInt(h)+Number.parseInt(u)}et||(et=document.createElement("canvas"));let l=et.getContext("2d");l.font=`${o} ${n} ${s}`;let d=l.measureText(r);return Number.parseInt(d.width)+a}function q(r){return Math.random().toString(36).replace("0.",r||"")}function G(r,t=300){let e=null;return(...i)=>{clearTimeout(e),e=setTimeout(()=>{e=null,r(...i)},t)}}var B={},C={itemsPerPage:"Items per page",gotoPage:"Go to page",gotoFirstPage:"Go to first page",gotoPrevPage:"Go to previous page",gotoNextPage:"Go to next page",gotoLastPage:"Go to last page",of:"of",items:"items",resizeColumn:"Resize column",noData:"No data",areYouSure:"Are you sure?",networkError:"Network response error"};function wt(r,t){t.width&&c(r,"width",t.width),t.class&&E(r,t.class),t.hidden&&(c(r,"hidden",""),t.responsiveHidden&&E(r,"dg-responsive-hidden"))}var it=class r extends Ct{_filterSelector="[id^=dg-filter]";_excludedRowElementSelector="a,button,input,select,textarea";_excludedKeys=[37,39,38,40,45,36,35,33,34,27,20,16,17,91,92,18,93,144,231,"ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Insert","Home","End","PageUp","PageDown","Escape","CapsLock","Shift","Control","Meta","Alt","ContextMenu","NumLock","Unidentified"];_ready(){c(this,"id",this.options.id??q("el-"),!0),this.data=[],this.originalData,this.options=this.options||this.defaultOptions,this.options.singleSelect&&(this.options.selectable=!0),this.fireEvents=!1,this.page=this.options.defaultPage||1,this.pages=0,this.meta,this.plugins={};for(let[t,e]of Object.entries(B))this.plugins[t]=new e(this);for(let t of r.observedAttributes)t.indexOf("data-")===0&&c(this,t,this.options[F(t.slice(5))])}static template(){return` +function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUpperCase())}function V(r){if(r==="true")return!0;if(r==="false")return!1;if(r===""||r==="null")return null;if(r===Number(r).toString())return Number(r);if(r&&typeof r.substring=="function"&&["[","{"].includes(r.substring(0,1)))try{let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(decodeURIComponent(t))}catch{return console.error(`Failed to parse ${r}`),{}}return r}var zt=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];function vt(r){return zt.includes(r)?{passive:!0}:{}}function D(r,t){return r.getAttribute(t)}function U(r,t){return r.hasAttribute(t)}function c(r,t,e="",i=!1){i&&U(r,t)||r.setAttribute(t,`${e}`)}function E(r,t){U(r,t)&&r.removeAttribute(t)}function P(r,t,e){r.addEventListener(t,e,vt(t))}function O(r,t,e){r.removeEventListener(t,e,vt(t))}function y(r,t,e={},i=!1){let o={};i&&(o.bubbles=!0),e&&(o.detail=e),r.dispatchEvent(new CustomEvent(t,o))}function T(r,t){return r.classList.contains(t)}function L(r,t){r.classList.add(...t.split(" "))}function W(r,t){r.classList.remove(...t.split(" "))}function yt(r,t){r.classList.toggle(t)}function I(r,t=document){return r instanceof HTMLElement?r:t.querySelector(r)}function Y(r,t=document){return Array.from(t.querySelectorAll(r))}function N(r,t){return I(t,r)}function g(r,t){return Y(t,r)}function x(r,t=null){let e=document.createElement(r);return t&&t.appendChild(e),e}function xt(r,t){t.parentNode.insertBefore(r,t.nextSibling)}var J=class extends HTMLElement{constructor(t={}){super(),this.options=Object.assign({},this.defaultOptions,this.normalizedDataset,t),this.log("constructor"),this.setup=!1,this.fireEvents=!0,this._ready(),this.log("ready")}get defaultOptions(){return{}}getOption(t){return this.options[t]}setOption(t,e){c(this,`data-${t}`,e)}toggleOption(t){c(this,`data-${t}`,!this.getOption(t))}get normalizedDataset(){let t=this.dataset.config?JSON.parse(this.dataset.config):{},e={...this.dataset};for(let i in e)i==="config"||!e.hasOwnProperty(i)||typeof e[i]=="function"||(e[i]=V(e[i]));return Object.assign(e,t),e}static template(){return""}_ready(){}log(...t){this.options.debug&&console.log(`[${D(this,"id")}] `,...t)}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}_connected(){}connectedCallback(){this.setup||(this.setup=!0,setTimeout(async()=>{this.log("connectedCallback");let t=document.createElement("template");t.innerHTML=this.constructor.template(),this.appendChild(t.content.cloneNode(!0)),await this._connected(),y(this,"connected")},0))}_disconnected(){}disconnectedCallback(){setTimeout(()=>{!this.isConnected&&this.setup&&(this.log("disconnectedCallback"),this._disconnected(),y(this,"disconnected"),this.setup=!1)},0)}get transformAttributes(){return{}}attributeChangedCallback(t,e,i){if(e===i)return;this.log(`attributeChangedCallback: ${t}`);let o=!1,n=this.transformAttributes[t]??V,s=t;s.indexOf("data-")===0&&(s=s.slice(5),o=!0),s=F(s),o?this.options[s]=n(i):this[s]=n(i),this.fireEvents&&this[`${s}Changed`]&&this[`${s}Changed`]()}},Ct=J;function Z(r,t,e,i=!1){let o=document.createElement("option");o.value=`${t}`,i&&(o.selected=!0),o.label=e,r.appendChild(o)}function Q(r,t={}){for(let e of Object.keys(t))if(Array.isArray(t[e]))for(let i of Object.keys(t[e]))r.searchParams.append(isNaN(i)?`${e}[${i}]`:e,t[e][i]);else r.searchParams.append(e,t[e])}function X(r){if(typeof r=="string"){if(r[0]==="["){let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(t)}return r.split(",")}return Array.isArray(r)?r:(console.error("Invalid array",r),[])}function tt(r){let t=r.getBoundingClientRect(),e=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+i,left:t.left+e}}function M(r,t){return r.replace(/\{([^}]+)?\}/g,(e,i)=>t[i])}var et;function _(r,t=document.body,e=!1){let i=window.getComputedStyle(t||document.createElement("div")),o=i.getPropertyValue("font-weight")||"normal",n=i.getPropertyValue("font-size")||"1rem",s=i.getPropertyValue("font-family")||"Arial",a=0;if(e){let h=i.getPropertyValue("padding-left")||"0",u=i.getPropertyValue("padding-right")||"0";a=Number.parseInt(h)+Number.parseInt(u)}et||(et=document.createElement("canvas"));let l=et.getContext("2d");l.font=`${o} ${n} ${s}`;let d=l.measureText(r);return Number.parseInt(d.width)+a}function q(r){return Math.random().toString(36).replace("0.",r||"")}function G(r,t=300){let e=null;return(...i)=>{clearTimeout(e),e=setTimeout(()=>{e=null,r(...i)},t)}}var B={},C={itemsPerPage:"Items per page",gotoPage:"Go to page",gotoFirstPage:"Go to first page",gotoPrevPage:"Go to previous page",gotoNextPage:"Go to next page",gotoLastPage:"Go to last page",of:"of",items:"items",resizeColumn:"Resize column",noData:"No data",areYouSure:"Are you sure?",networkError:"Network response error"};function wt(r,t){t.width&&c(r,"width",t.width),t.class&&L(r,t.class),t.hidden&&(c(r,"hidden",""),t.responsiveHidden&&L(r,"dg-responsive-hidden")),t.noSort&&r.tagName==="TH"&&L(r,"dg-not-sortable")}var it=class r extends Ct{_filterSelector="[id^=dg-filter]";_excludedRowElementSelector="a,button,input,select,textarea";_excludedKeys=[37,39,38,40,45,36,35,33,34,27,20,16,17,91,92,18,93,144,231,"ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Insert","Home","End","PageUp","PageDown","Escape","CapsLock","Shift","Control","Meta","Alt","ContextMenu","NumLock","Unidentified"];_ready(){c(this,"id",this.options.id??q("el-"),!0),this.data=[],this.originalData,this.options=this.options||this.defaultOptions,this.options.singleSelect&&(this.options.selectable=!0),this.fireEvents=!1,this.page=this.options.defaultPage||1,this.pages=0,this.meta,this.plugins={};for(let[t,e]of Object.entries(B))this.plugins[t]=new e(this);for(let t of r.observedAttributes)t.indexOf("data-")===0&&c(this,t,this.options[F(t.slice(5))])}static template(){return` @@ -36,13 +36,13 @@ function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUppe
-`}get labels(){return C}static getLabels(){return C}static setLabels(t){C=Object.assign(C,t)}get noData(){return this.options.noData||this.labels.noData}#t(t){!this.hasDataError&&t.getAttribute("data-empty")!==this.noData&&t.setAttribute("data-empty",this.noData)}get defaultColumn(){return{field:"",title:"",width:0,class:"",attr:"",hidden:!1,editable:!1,noSort:!1,responsive:1,responsiveHidden:!1,format:"",transform:"",filterType:"text",firstFilterOption:{value:"",text:""}}}get defaultOptions(){return{id:null,url:"",perPage:10,debug:!1,filter:!1,menu:!1,sort:!1,server:!1,serverParams:{start:"start",length:"length",search:"search",sort:"sort",sortDir:"sortDir",dataKey:"data",metaKey:"meta",metaTotalKey:"total",metaFilteredKey:"filtered",optionsKey:"options",paramsKey:"params"},defaultSort:"",reorder:!1,dir:"ltr",perPageValues:[10,25,50,100,250],hidePerPage:!1,columns:[],actions:[],collapseActions:!1,selectable:!1,selectVisibleOnly:!0,singleSelect:!1,defaultPage:1,resizable:!1,autosize:!0,expand:!1,autoheight:!0,autohidePager:!1,responsive:!1,responsiveToggle:!0,filterOnEnter:!0,filterKeypressDelay:500,spinnerClass:"",saveState:!1,errorMessage:"",noData:""}}get isInit(){return this.classList.contains("dg-initialized")}get hasDataError(){return this.classList.contains("dg-network-error")}static registerPlugins(t){B=t}static unregisterPlugins(t=null){t===null?B={}:delete B[t]}static registeredPlugins(){return B}convertColumns(t){let e=[];if(typeof t=="object"&&!Array.isArray(t))for(let i of Object.keys(t)){let o=Object.assign({},this.defaultColumn);o.title=t[i],o.field=i,e.push(o)}else for(let i of t){let o=Object.assign({},this.defaultColumn);typeof i=="string"?(o.title=i,o.field=i):typeof i=="object"?(o=Object.assign(o,i),o.field||console.error("Invalid column definition",i),o.title||(o.title=o.field)):console.error("Column definition must be a string or an object"),e.push(o)}return e}static get observedAttributes(){return["page","data-filter","data-sort","data-debug","data-reorder","data-menu","data-selectable","data-single-select","data-url","data-per-page","data-responsive"]}get transformAttributes(){return{columns:t=>this.convertColumns(X(t)),actions:t=>X(t),defaultPage:t=>Number.parseInt(t),perPage:t=>Number.parseInt(t)}}get thead(){return I("thead",this)}get tbody(){return I("tbody",this)}get tfoot(){return I("tfoot",this)}get page(){return Number.parseInt(this.getAttribute("page"))}set page(t){c(this,"page",this.constrainPageValue(t))}urlChanged(t=!1){return t&&!this.isInit?this:(this.reconfig(),this.loadData().then(()=>this.configureUi()))}reconfig(){let t=this.options.columns;return this.options.columns=[],this.configureUi(),this.options.columns=t,this}constrainPageValue(t){let e=t;return this.pages1&&this.page*this.options.perPage>this.totalRecords();)t--;t!==this.page?this.page=t:this.reload(()=>{(!this.plugins.FixedHeight||!this.plugins.FixedHeight.hasFixedHeight)&&this.selectPerPage.scrollIntoView()})}dirChanged(){c(this,"dir",this.options.dir)}defaultSortChanged(){this.sortChanged()}perPageValuesChanged(){if(this.selectPerPage){for(;this.selectPerPage.lastChild;)this.selectPerPage.removeChild(this.selectPerPage.lastChild);for(let t of this.options.perPageValues)Z(this.selectPerPage,t,t,t===this.options.perPage)}}async _connected(){this.table=this.querySelector("table"),this.btnFirst=this.querySelector(".dg-btn-first"),this.btnPrev=this.querySelector(".dg-btn-prev"),this.btnNext=this.querySelector(".dg-btn-next"),this.btnLast=this.querySelector(".dg-btn-last"),this.selectPerPage=this.querySelector(".dg-select-per-page"),this.inputPage=this.querySelector(".dg-input-page"),this.getFirst=this.getFirst.bind(this),this.getPrev=this.getPrev.bind(this),this.getNext=this.getNext.bind(this),this.getLast=this.getLast.bind(this),this.changePerPage=this.changePerPage.bind(this),this.gotoPage=this.gotoPage.bind(this),this.btnFirst.addEventListener("click",this.getFirst),this.btnPrev.addEventListener("click",this.getPrev),this.btnNext.addEventListener("click",this.getNext),this.btnLast.addEventListener("click",this.getLast),this.selectPerPage.addEventListener("change",this.changePerPage),this.selectPerPage.toggleAttribute("hidden",this.options.hidePerPage),this.inputPage.addEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))await t.connected();this.dirChanged(),this.perPageValuesChanged(),await this.init()}_disconnected(){this.btnFirst?.removeEventListener("click",this.getFirst),this.btnPrev?.removeEventListener("click",this.getPrev),this.btnNext?.removeEventListener("click",this.getNext),this.btnLast?.removeEventListener("click",this.getLast),this.selectPerPage?.removeEventListener("change",this.changePerPage),this.inputPage?.removeEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))t.disconnected()}init(){return this.loadData().finally(()=>{this.configureUi(),this.sortChanged(),this.classList.add("dg-initialized"),this.filterChanged(),this.reorderChanged(),this.dirChanged(),this.perPageValuesChanged(),this.pageChanged(),this.fireEvents=!0,this.log("initialized")})}getCol(t){let e=null;for(let i of this.options.columns)i.field===t&&(e=i);return e}getColProp(t,e){let i=this.getCol(t);return i?i[e]:null}setColProp(t,e,i){let o=this.getCol(t);o&&(o[e]=i)}visibleColumns(){return this.options.columns.filter(t=>!t.hidden)}hiddenColumns(){return this.options.columns.filter(t=>t.hidden===!0)}showColumn(t,e=!0){this.setColProp(t,"hidden",!1),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"visible"})}hideColumn(t,e=!0){this.setColProp(t,"hidden",!0),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"hidden"})}startColIndex(){let t=1;return this.options.selectable&&this.plugins.SelectableRows&&t++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&t++,t}isSticky(){return this.hasAttribute("sticky")}columnsLength(t=!1){let e=0;for(let i of this.options.columns)t&&i.hidden||i.attr||e++;return this.options.selectable&&this.plugins.SelectableRows&&e++,this.options.actions.length&&this.plugins.RowActions&&e++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&e++,e}configureUi(){if(!this.table)return this;if(this.table.style.visibility="hidden",this.renderTable(),this.options.responsive&&this.plugins.ResponsiveGrid||(this.table.style.visibility="visible"),!this.rowHeight){let t=N(this,"tbody tr")||N(this,"table tr");t&&(this.rowHeight=t.offsetHeight)}return this.#t(this.tbody),this.fixPage()}filterChanged(){let t=this.querySelector("thead tr.dg-head-filters");this.options.filter?k(t,"hidden"):(this.clearFilters(),c(t,"hidden",""))}reorderChanged(){let t=g(this,"thead tr.dg-head-columns th");for(let e of t)e.classList.contains("dg-selectable")||e.classList.contains("dg-actions")||(this.options.reorder&&this.plugins.DraggableHeaders?e.draggable=!0:e.removeAttribute("draggable"))}sortChanged(){this.log("toggle sort");let t=g(this,"thead tr.dg-head-columns th");for(let e of t){let i=e.getAttribute("field");if(e.classList.contains("dg-not-sortable")||!this.fireEvents&&i===this.options.defaultSort)return;this.options.sort&&!this.getColProp(i,"noSort")?c(e,"aria-sort","none"):k(e,"aria-sort")}}selectableChanged(){this.renderTable()}addRow(t){Array.isArray(this.originalData)&&(this.log("add row"),this.originalData.push(t),this.data=this.originalData.slice(),this.sortData())}removeRow(t=null,e=null){if(!Array.isArray(this.originalData))return;let i=t,o=e;o===null&&(o=this.options.columns[0].field),i===null&&(i=this.originalData[this.originalData.length-1][o]),this.log(`remove row ${o}:${i}`);for(let n=0;n{this.hasDataError||(this.options.server||e?this.renderBody():this.paginate(),typeof t=="function"&&t())}).then(()=>this)}loadData(){let t=()=>!this.data.length&&this.classList.add("dg-empty"),e=this.tbody;return(this.meta||this.originalData||this.isInit)&&(!this.options.server||this.options.server&&!this.fireEvents)?(this.log("skip loadData"),t(),new Promise(i=>{i()})):(this.log("loadData"),this.loading=!0,this.classList.add("dg-loading"),this.classList.remove("dg-empty","dg-network-error"),this.fetchData().then(i=>{if(Array.isArray(i))this.data=i;else{if(!i[this.options.serverParams.dataKey]){console.error("Invalid response, it should contain a data key with an array or be a plain array",i),this.options.url=null;return}this.options=Object.assign(this.options,i[this.options.serverParams.optionsKey]??{}),this.meta=i[this.options.serverParams.metaKey]??{},this.data=i[this.options.serverParams.dataKey]}this.originalData=this.data.slice(),this.fixPage(),this.options.columns.length===0&&this.originalData.length?this.options.columns=this.convertColumns(Object.keys(this.originalData[0])):this.options.columns=this.convertColumns(this.options.columns)}).catch(i=>{this.log(i),e.setAttribute("data-empty",this.options.errorMessage||i.message?.replace(/^\s+|\r\n|\n|\r$/g,"")||C.networkError),this.classList.add("dg-empty","dg-network-error"),y(this,"loadDataFailed",i)}).finally(()=>{t(),this.#t(e),this.classList.remove("dg-loading"),c(this.table,"aria-rowcount",this.data.length),this.loading=!1}))}getFirst(){this.loading||(this.page=1)}getLast(){this.loading||(this.page=this.pages)}getPrev(){this.loading||(this.page=this.page-1)}getNext(){this.loading||(this.page=this.page+1)}gotoPage(t){if(t.type==="keypress"){let e=t.keyCode||t.key;if(e===13||e==="Enter")t.preventDefault();else return}this.page=Number.parseInt(this.inputPage.value)}getSort(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t?t.getAttribute("field"):this.options.defaultSort}getSortDir(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t&&t.getAttribute("aria-sort")||""}getFilters(){let t=[],e=g(this,this._filterSelector);for(let i of e)t[i.dataset.name]=i.value;return t}clearFilters(){let t=g(this,this._filterSelector);for(let e of t)e.value="";this.filterData()}filterData(){if(this.log("filter data"),this.page=1,this.options.server)this.reload();else{this.data=this.originalData?.slice()??[];let t=g(this,this._filterSelector);for(let i of t){let o=i.value;if(o){let n=i.dataset.name;this.data=this.data.filter(s=>`${s[n]}`.toLowerCase().indexOf(o.toLowerCase())!==-1)}}this.pageChanged();let e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");this.options.sort&&e?this.sortData():this.renderBody()}}sortData(t=null){this.log("sort data");let e=t;if(e&&this.getColProp(e.getAttribute("field"),"noSort")){this.log("sorting prevented because column is not sortable");return}if(this.plugins.ColumnResizer?.isResizing){this.log("sorting prevented because resizing");return}if(this.loading){this.log("sorting prevented because loading");return}if(e!==null){let i=n=>["dg-selectable","dg-actions","dg-responsive-toggle"].includes(n),o=g(this,"thead tr:first-child th");for(let n of o)[...n.classList].some(i)||!n.hasAttribute("aria-sort")||n!==e&&n.setAttribute("aria-sort","none");!e.hasAttribute("aria-sort")||e.getAttribute("aria-sort")==="none"?e.setAttribute("aria-sort","ascending"):e.getAttribute("aria-sort")==="ascending"?e.setAttribute("aria-sort","descending"):e.getAttribute("aria-sort")==="descending"&&e.setAttribute("aria-sort","none")}else e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");if(this.options.server)this.loadData().finally(()=>{this.renderBody()});else{let i=e?e.getAttribute("aria-sort"):"none";if(i==="none"){let o=[];this.originalData?.some(n=>(this.data.some(s=>JSON.stringify(n)===JSON.stringify(s)?(o.push(s),!0):!1),o.length===this.data.length)),this.data=o}else{let o=e.getAttribute("field");this.data.sort((n,s)=>{if(!isNaN(n[o])&&!isNaN(s[o]))return i==="ascending"?n[o]-s[o]:s[o]-n[o];let a=i==="ascending"?n[o].toUpperCase():s[o].toUpperCase(),l=i==="ascending"?s[o].toUpperCase():n[o].toUpperCase();switch(!0){case a>l:return 1;case athis._sort(t,"ascending");sortDesc=t=>this._sort(t,"descending");sortNone=t=>this._sort(t,"none");fetchData(){if(!this.options.url)return new Promise((o,n)=>n("No url set"));let t=window.location.href;t.split("/").pop().includes(".")||(t+=t.endsWith("/")?"":"/");let e=new URL(this.options.url,t),i={r:Date.now()};return this.options.server&&(i[this.options.serverParams.start]=this.page-1,i[this.options.serverParams.length]=this.options.perPage,this.options.filter&&(i[this.options.serverParams.search]=this.getFilters()),i[this.options.serverParams.sort]=this.getSort()||"",i[this.options.serverParams.sortDir]=this.getSortDir(),this.meta?.[this.options.serverParams.paramsKey]&&(i=Object.assign(i,this.meta[this.options.serverParams.paramsKey]))),Q(e,i),fetch(e).then(o=>{let n=new Error(o.statusText||C.networkError);if(!o.ok)throw n.response=o,n;return o.clone().json().catch(s=>{let a=s;throw this.options.debug||(a=n),a.response=o,a})})}renderTable(){this.log("render table"),this.options.menu&&this.plugins.ContextMenu&&this.plugins.ContextMenu.createMenu();let t;this.renderHeader(),this.options.defaultSort&&(t=this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`)),t?this.sortData(t):this.renderBody(),this.renderFooter()}renderHeader(){this.log("render header");let t=this.thead;this.createColumnHeaders(t),this.createColumnFilters(t),this.options.resizable&&this.plugins.ColumnResizer&&this.plugins.ColumnResizer.renderResizer(C.resizeColumn),y(this,"headerRendered")}renderFooter(){this.log("render footer");let t=this.tfoot;if(!t)return;let e=t.querySelector("td");t.removeAttribute("hidden"),c(e,"colspan",this.columnsLength(!0)),t.style.display=""}createColumnHeaders(t){let e=this.clientWidth,i=Math.round(e/this.columnsLength(!0)*2),o=0,n;n=x("tr"),this.headerRow=n,n.setAttribute("role","row"),n.setAttribute("aria-rowindex","1"),n.setAttribute("class","dg-head-columns");let s=t?.querySelector("tr.dg-head-columns th");this.log("createColumnHeaders - sampleTh",s),s||(s=x("th"),t?.querySelector("tr").appendChild(s)),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createHeaderCol(n),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createHeaderCol(n),o=0;let a=0;this.log("createColumnHeaders - columns",this.options.columns);for(let d of this.options.columns){if(d.attr)continue;let h=o+this.startColIndex(),u=x("th");u.setAttribute("scope","col"),u.setAttribute("role","columnheader button"),u.setAttribute("aria-colindex",`${h}`),u.setAttribute("id",q("dg-col-")),this.options.sort&&u.setAttribute("aria-sort","none"),u.setAttribute("field",d.field),this.plugins.ResponsiveGrid&&this.options.responsive&&c(u,"data-responsive",d.responsive||"");let p=_(d.title,s,!0)+20;u.dataset.minWidth=`${p}`,wt(u,d),u.tabIndex=0,u.textContent=d.title;let f=0;if(this.options.autosize&&this.plugins.AutosizeColumn){let b=Math.min(e-a,i);f=this.plugins.AutosizeColumn.computeSize(u,d,Number.parseInt(u.dataset.minWidth),b)}else f=Math.max(Number.parseInt(u.dataset.minWidth),Number.parseInt(u.getAttribute("width")));c(u,"width",f),d.hidden?u.setAttribute("hidden",""):a+=f,this.options.reorder&&this.plugins.DraggableHeaders&&this.plugins.DraggableHeaders.makeHeaderDraggable(u),n.appendChild(u),o++}if(ae){this.log(`adjust width to fix size, ${t.offsetWidth} > ${e}`);let d=this.offsetWidth-this.clientWidth,h=t.offsetWidth-e-d;this.options.responsive&&this.plugins.ResponsiveGrid&&(h+=d);let u=g(n,"th[width]");for(let p of u){if(T(p,"dg-not-resizable")||h<=0)continue;let f=Number.parseInt(p.getAttribute("width")),b=p.dataset.minWidth?Number.parseInt(p.dataset.minWidth):0;if(f>b){let A=f-h;Athis.sortData(d));this.table&&c(this.table,"aria-colcount",this.columnsLength(!0))}createColumnFilters(t){let e=0,i;i=x("tr"),this.filterRow=i,i.setAttribute("role","row"),i.setAttribute("aria-rowindex","2"),i.setAttribute("class","dg-head-filters"),this.options.filter||i.setAttribute("hidden",""),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createFilterCol(i),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createFilterCol(i),this.log("createColumnFilters - columns",this.options.columns);for(let n of this.options.columns){if(n.attr)continue;let s=e+this.startColIndex(),a=t?.querySelector(`tr.dg-head-columns th[aria-colindex="${s}"]`);if(!a){console.warn("Related th not found",s);continue}let l=x("th");l.setAttribute("aria-colindex",`${s}`);let d=this.createFilterElement(n,a);this.options.filter?d.tabIndex=0:l.tabIndex=0,n.hidden&&l.setAttribute("hidden",""),l.appendChild(d),i.appendChild(l),e++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionFilter(i),t?.replaceChild(i,t.querySelector("tr.dg-head-filters")),(typeof this.options.filterKeypressDelay!="number"||this.options.filterOnEnter)&&(this.options.filterKeypressDelay=0);let o=g(i,this._filterSelector);for(let n of o){let s=/select/i.test(n.tagName),a=s?"change":"keyup",l=G(d=>{let h=d.keyCode||d.key,u=!this.options.filterOnEnter&&!this._excludedKeys.some(p=>p===h);(h===13||h==="Enter"||u||d.type==="change"||d.type==="paste")&&this.filterData.call(this)},this.options.filterKeypressDelay);n.addEventListener(a,l),s||n.addEventListener("paste",l)}}createFilterElement(t,e){let i=t.filterType==="select",o=i?x("select"):x("input");if(i){if(!Array.isArray(t.filterList)){let n=[...new Set((this.data??[]).map(s=>s[t.field]))].filter(s=>s).sort();t.filterList=[t.firstFilterOption||this.defaultColumn.firstFilterOption].concat(n.map(s=>({value:s,text:s})))}for(let n of t.filterList){let s=x("option");s.value=n.value,s.text=n.text,o instanceof HTMLSelectElement&&o.add(s)}}else o.type="text",o.inputMode="search",o.autocomplete="off",o.spellcheck=!1;return o.dataset.name=t.field,o.id=q("dg-filter-"),o.setAttribute("aria-labelledby",e.getAttribute("id")),o}renderBody(){this.log("render body");let t,e,i,o=x("tbody");this.data.forEach((s,a)=>{t=x("tr"),c(t,"role","row"),c(t,"hidden",""),c(t,"aria-rowindex",a+1),t.tabIndex=0,this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createDataCol(t),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createDataCol(t),this.options.expand&&(t.classList.add("dg-expandable"),S(t,"click",l=>{l.target.matches(this._excludedRowElementSelector)||(this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.blockObserver(),yt(l.currentTarget,"dg-expanded"),this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.unblockObserver())})),i=0;for(let l of this.options.columns){if(l||console.error("Empty column found!",this.options.columns),l.attr){s[l.field]&&(l.attr==="class"?E(t,s[l.field]):t.setAttribute(l.attr,s[l.field]));return}if(e=x("td"),e.setAttribute("role","gridcell"),e.setAttribute("aria-colindex",`${i}${this.startColIndex()}`),wt(e,l),e.setAttribute("data-name",l.title),e.tabIndex=-1,l.editable&&this.plugins.EditableColumn)E(e,"dg-editable-col"),this.plugins.EditableColumn.makeEditableInput(e,l,s,a);else{let d=s[l.field]??"",h;switch(l.transform){case"uppercase":h=d.toUpperCase();break;case"lowercase":h=d.toLowerCase();break;default:h=d;break}if(l.format){if(l.defaultFormatValue!==void 0&&(h===""||h===null)&&(h=`${l.defaultFormatValue}`),typeof l.format=="string"&&h)e.innerHTML=M(l.format,Object.assign({_v:d,_tv:h},s));else if(l.format instanceof Function){let u=l.format.call(this,{column:l,rowData:s,cellData:h,td:e,tr:t});e.innerHTML=u||h||d}}else e.textContent=h}t.appendChild(e),i++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionRow(t,s),o.appendChild(t),y(this,"rowRendered",{rowData:s,tr:t})}),o.setAttribute("role","rowgroup");let n=this.tbody;n&&o.setAttribute("data-empty",n.getAttribute("data-empty")),this.table?.replaceChild(o,n),this.plugins.FixedHeight&&this.plugins.FixedHeight.createFakeRow(),this.paginate(),this.plugins.SelectableRows&&this.plugins.SelectableRows.shouldSelectAll(o),this.classList.toggle("dg-empty",!this.data.length),y(this,"bodyRendered")}paginate(){this.log("paginate");let t=this.totalRecords(),e=this.page||1,i=this.tbody,o=this.tfoot;if(!i||!o)return;let n=g(i,"tr");this.pages=this.totalPages();let s,a=e*this.options.perPage,l=a-this.options.perPage+1;a>t&&(a=t),t||(l=0);for(let d of n){if(this.options.server){k(d,"hidden");continue}s=Number(D(d,"aria-rowindex")),s>a||s=this.pages,this.btnLast.disabled=this.page>=this.pages),o.querySelector(".dg-low").textContent=l.toString(),o.querySelector(".dg-high").textContent=a.toString(),o.querySelector(".dg-total").textContent=`${this.totalRecords()}`,o.toggleAttribute("hidden",this.options.autohidePager&&this.options.perPage>this.totalRecords())}totalPages(){return Math.ceil(this.totalRecords()/this.options.perPage)}totalRecords(){return this.options.server?this.meta?.[this.options.serverParams.metaFilteredKey]||0:this.data.length}},j=it;var st=class{constructor(t){this.grid=t}connected(){}disconnected(){}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}},m=st;var ot=class extends m{constructor(t){super(t),this.isResizing=!1}renderResizer(t){let e=this.grid,i=e.table,o=g(e,"thead tr.dg-head-columns th");for(let n of o){if(T(n,"dg-not-resizable"))continue;let s=document.createElement("div");E(s,"dg-resizer"),s.ariaLabel=t,n.appendChild(s);let a=0,l=0,d=0,h=0,u=f=>{if(f.clientX>h)return;let b=l+(f.clientX-a);n.dataset.minWidth&&b>Number.parseInt(n.dataset.minWidth)&&c(n,"width",b)},p=()=>{e.log("resized column"),setTimeout(()=>{this.isResizing=!1},0),W(s,"dg-resizer-active"),e.options.reorder&&(n.draggable=!0),n.style.overflow="hidden",O(document,"mousemove",u),O(document,"mouseup",p),y(e,"columnResized",{col:D(n,"field"),width:D(n,"width")})};S(s,"click",f=>{f.stopPropagation()}),S(s,"mousedown",f=>{f.stopPropagation(),this.isResizing=!0;let b=f.target,P=g(e,"dg-head-columns th").filter(v=>!v.hasAttribute("hidden")),w=P.findIndex(v=>v===b.parentNode);e.log("resize column"),E(s,"dg-resizer-active"),k(n,"draggable"),n.style.overflow="visible",s.style.height=`${i.offsetHeight-1}px`,a=f.clientX,l=n.offsetWidth,d=(P.length-w)*30,h=tt(b).left+e.offsetWidth-d,c(n,"width",l);for(let v=0;vw&&k(o[v],"width");S(document,"mousemove",u),S(document,"mouseup",p)})}}},Pt=ot;function K(r,t,e="nodeName"){let i=r;for(;i[e]!==t;)i=i.parentElement;return i}var nt=class extends m{connected(){this.menu=this.grid.querySelector(".dg-menu")}disconnected(){this.grid.headerRow&&O(this.grid.headerRow,"contextmenu",this)}attachContextMenu(){let t=this.grid;S(t.headerRow,"contextmenu",this)}onchange(t){let e=this.grid,i=t.target,o=i.dataset.name;if(i.checked)e.showColumn(o);else{if(e.visibleColumns().length<=1){i.checked=!0;return}e.hideColumn(o)}e.fixPage()}oncontextmenu(t){t.preventDefault();let e=K(t.target,"THEAD"),i=this.menu,o=e.getBoundingClientRect(),n=t.clientX-o.left,s=t.clientY-o.top;i.style.top=`${s}px`,i.style.left=`${n}px`,k(i,"hidden"),n+150>o.width&&(n-=i.offsetWidth,i.style.left=`${n}px`);let a=l=>{i.contains(l.target)||(c(i,"hidden",""),O(document,"click",a))};S(document,"click",a)}createMenu(){let t=this.grid,e=this.menu;for(;e.lastChild;)e.removeChild(e.lastChild);e.addEventListener("change",this);for(let i of t.options.columns){if(i.attr)continue;let o=document.createElement("li"),n=document.createElement("label"),s=document.createElement("input");c(s,"type","checkbox"),c(s,"data-name",i.field),i.hidden||(s.checked=!0);let a=document.createTextNode(i.title);n.appendChild(s),n.appendChild(a),o.appendChild(n),e.appendChild(o)}}},St=nt;var rt=class extends m{makeHeaderDraggable(t){let e=this.grid;t.draggable=!0,S(t,"dragstart",i=>{if(e.plugins.ColumnResizer?.isResizing&&i.preventDefault){i.preventDefault();return}e.log("reorder col"),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",i.target.getAttribute("aria-colindex"))}),S(t,"dragover",i=>(i.preventDefault&&i.preventDefault(),i.dataTransfer.dropEffect="move",!1)),S(t,"drop",i=>{i.stopPropagation&&i.stopPropagation();let o=i.target,n=K(o,"TH"),s=Number.parseInt(i.dataTransfer.getData("text/plain")),a=Number.parseInt(n.getAttribute("aria-colindex"));if(s===a){e.log("reordered col stayed the same");return}e.log(`reordered col from ${s} to ${a}`);let l=e.startColIndex(),d=e.options.columns[s-l];e.options.columns[s-l]=e.options.columns[a-l],e.options.columns[a-l]=d;let h=(u,p)=>{let f=p.parentNode.getAttribute("aria-rowindex"),b=e.querySelector(`${u} tr[aria-rowindex="${f}"] [aria-colindex="${a}"]`);c(p,"aria-colindex",a),c(b,"aria-colindex",s);let A=document.createElement("th");p.parentNode.insertBefore(A,p),b.parentNode.replaceChild(p,b),A.parentNode.replaceChild(b,A)};for(let u of g(e,`thead th[aria-colindex="${s}"]`))h("thead",u);for(let u of g(e,`tbody td[aria-colindex="${s}"]`))h("tbody",u);return e.options.columns=g(e,"thead tr.dg-head-columns th[field]").map(u=>e.options.columns.find(p=>p.field===D(u,"field"))),y(e,"columnReordered",{col:d.field,from:s,to:a}),!1})}},At=rt;var at=class extends m{constructor(t){super(t),this.touch=null}connected(){let t=this.grid;t.addEventListener("touchstart",this,{passive:!0}),t.addEventListener("touchmove",this,{passive:!0})}disconnected(){let t=this.grid;t.removeEventListener("touchstart",this),t.removeEventListener("touchmove",this)}ontouchstart(t){this.touch=t.touches[0]}ontouchmove(t){if(!this.touch)return;let e=this.grid,i=this.touch.clientX-t.touches[0].clientX,o=this.touch.clientY-t.touches[0].clientY;Math.abs(i)>Math.abs(o)&&(i>0?e.getNext():e.getPrev()),this.touch=null}},Lt=at;var H="dg-selectable",lt="dg-select-all",kt="form-check-input",dt=class extends m{#t=`tbody tr${this.visibleOnly?":not([hidden])":""} .${H} input[type=checkbox]`;#e=`tbody .${H} input`;disconnected(){this.selectAll&&this.selectAll.removeEventListener("change",this)}get isSingleSelect(){return this.grid.options.singleSelect}get visibleOnly(){return this.grid.options.selectVisibleOnly}getSelection(...t){let e=this.grid,i=[],o=g(e,`${this.#e}:checked`);for(let n of o){let s=Number.parseInt(n.dataset.id),a=e.data[s-1];if(!a){console.warn(`Item ${s} not found`);continue}t.length===0?i.push(a):t.length===1?i.push(a[t[0]]):i.push(Object.fromEntries(t.map(l=>[l,a[l]])))}return this.isSingleSelect?i[0]??{}:i}clearCheckboxes(t){if(!this.grid.options.selectVisibleOnly)return;let i=g(t,`tr[hidden] .${H} input`);for(let o of i)o.checked=!1,this.isSingleSelect&&(o.dataset.toggled="false");this.selectAll.checked=!1}colIndex(){return this.grid.startColIndex()-2}createHeaderCol(t){let e=document.createElement("th");c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0,this.selectAll=document.createElement("input"),this.selectAll.type="checkbox",this.selectAll.classList.add(lt),this.selectAll.classList.add(kt),this.selectAll.addEventListener("change",this);let i=document.createElement("label");i.hidden=this.isSingleSelect,i.appendChild(this.selectAll),e.appendChild(i),e.setAttribute("width","40"),t.appendChild(e)}createFilterCol(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H),e.tabIndex=0,t.appendChild(e)}shouldSelectAll(t){this.selectAll&&(t.addEventListener("change",this),t.dispatchEvent(new Event("change")))}createDataCol(t){let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H);let i=document.createElement("input");i.dataset.id=t.getAttribute("aria-rowindex"),i.type=this.isSingleSelect?"radio":"checkbox",i.classList.add(kt),this.isSingleSelect&&(i.name="dg-row-select",i.dataset.toggled="false");let o=document.createElement("label");o.classList.add("dg-clickable-cell"),o.appendChild(i),e.appendChild(o),o.addEventListener("click",this),t.appendChild(e)}onclick(t){if(!this.isSingleSelect)return t.stopPropagation();let e=t.target,i=e.dataset.toggled!=="true";i&&Y(`${this.#t.replace("checkbox","radio")}`,this.grid)?.forEach(o=>{o.name===e.name&&o!==e&&(o.checked=o.dataset.toggled=!1)}),e.checked=e.dataset.toggled=i,!i&&this.onchange(t)}onchange(t){let e=t.target,i=this.grid;if(T(t.target,lt))g(i,this.#e).forEach(o=>{(!this.visibleOnly||o.offsetWidth)&&(o.checked=this.selectAll.checked)});else if(e.matches(this.#t)){if(!e.closest(`.${H}`))return;let o=g(i,this.#t);this.selectAll.checked=o.every(n=>n.checked)}e.matches(`.${lt},${this.#e}`)&&y(e,"rowsSelected",{selection:i.getSelection()},!0)}},Et=dt;var ct=class extends m{constructor(t){super(t),this.hasFixedHeight=!1,t.style.height&&(t.style.overflowY="auto",this.hasFixedHeight=!0)}createFakeRow(){let e=this.grid.querySelector("tbody"),i=document.createElement("tr");c(i,"role","row"),c(i,"hidden",""),i.classList.add("dg-fake-row"),i.tabIndex=0,e?.appendChild(i)}get fakeRow(){return this.grid.querySelector(".dg-fake-row")}updateFakeRow(){let t=this.grid,e=this.fakeRow;if(!e||t.options.perPage>t.totalRecords()||t.page!==t.totalPages()||!t.options.autoheight)return;let i=t.options.perPage*t.rowHeight,o=t.querySelectorAll("tbody tr:not([hidden])").length,n=o>1?i-o*t.rowHeight:i;n>0?(c(e,"height",n),e.removeAttribute("hidden")):e.removeAttribute("height")}},Dt=ct;var ht=class extends m{computeSize(t,e,i,o){let n=this.grid;if(U(t,"width"))return D(t,"width");if(!n.data.length)return;let s=n.data[0],a=n.data[n.data.length-1],l=s[e.field]?s[e.field].toString():"",d=a[e.field]?a[e.field].toString():"";d.length>l.length&&(l=d);let h=0;return l.length<=6?h=i:l.length>50?h=o:h=_(`${l}0000`,t),h>o&&(h=o),h{let i=Number.parseInt(t.dataset.responsive)||1;return(Number.parseInt(e.dataset.responsive)||1)-i})}var Wt=G(r=>{for(let t of r){let e=t.target,i=e.table;if(e.plugins.ResponsiveGrid.observerBlocked)return;let o=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize,n=Number.parseInt(o.inlineSize),s=i.offsetWidth,a=g(e.headerRow,"th").reduce((P,w)=>P+w.offsetWidth,0),l=(a||s)-n-1,d=50,h=e.plugins.ResponsiveGrid.prevAction,u=Ft(g(e.headerRow,"th[field]").reverse().filter(P=>P.dataset.responsive!=="0")),p=!1;if(e.log(`table is ${s}/${a} and available size is ${n}. Diff: ${l}`),l>0){if(h==="show")return;e.plugins.ResponsiveGrid.prevAction="hide";let P=l,w=u.filter(v=>!v.hasAttribute("hidden")&&v.hasAttribute("data-responsive"));if(w.length===0&&(w=u.filter(v=>!v.hasAttribute("hidden")),w.length===1))return;for(let v of w){if(P<0)continue;let $=v.offsetWidth,R=v.getAttribute("field");R&&(v.dataset.baseWidth=`${v.offsetWidth}`,e.hideColumn(R,!1),e.setColProp(R,"responsiveHidden",!0),p=!0,P-=$,P=Math.round(P))}}else{if(h==="hide")return;e.plugins.ResponsiveGrid.prevAction="show";let P=u.filter($=>!$.hasAttribute("hidden")).reduce(($,R)=>{let z=R.dataset.minWidth?Number.parseInt(R.dataset.minWidth):R.offsetWidth;return $+z},0)+d,w=n-P,v=u.slice().reverse().filter($=>$.hasAttribute("hidden"));for(let $ of v){if(ww){w=-1;continue}let z=$.getAttribute("field");z&&(e.showColumn(z,!1),e.setColProp(z,"responsiveHidden",!1),p=!0,w-=R,w=Math.round(w))}}let f=N(e.table,"tfoot"),b=g(e.table,".dg-footer > div").reduce((P,w)=>P+w.offsetWidth,0),A=f.offsetWidth-b;b>n?E(f,"dg-footer-compact"):A>250&&W(f,"dg-footer-compact"),p&&e.renderTable(),setTimeout(()=>{e.plugins.ResponsiveGrid.prevAction=null},1e3),e.table.style.visibility="visible"}},100),Rt=new ResizeObserver(Wt),gt=class extends m{constructor(t){super(t),this.observerBlocked=!1,this.prevAction=null}connected(){this.grid.options.responsive&&this.observe()}disconnected(){this.unobserve()}observe(){this.grid.options.responsive&&(Rt.observe(this.grid),this.grid.style.display="block",this.grid.style.overflowX="hidden")}unobserve(){Rt.unobserve(this.grid),this.grid.style.display="unset",this.grid.style.overflowX="unset"}blockObserver(){this.observerBlocked=!0,ut&&clearTimeout(ut)}unblockObserver(){ut=setTimeout(()=>{this.observerBlocked=!1},200)}hasHiddenColumns(){let t=!1;for(let e of this.grid.options.columns)e.responsiveHidden&&(t=!0);return t}colIndex(){return this.grid.startColIndex()-1}createHeaderCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),c(e,"width","40"),e.classList.add(`${L}-toggle`,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0}createFilterCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.tabIndex=0}createDataCol(t){if(!this.grid.options.responsiveToggle)return;let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${L}-toggle`),e.innerHTML=`
+`}get labels(){return C}static getLabels(){return C}static setLabels(t){C=Object.assign(C,t)}get noData(){return this.options.noData||this.labels.noData}#t(t){!this.hasDataError&&t.getAttribute("data-empty")!==this.noData&&t.setAttribute("data-empty",this.noData)}get defaultColumn(){return{field:"",title:"",width:0,class:"",attr:"",hidden:!1,editable:!1,noSort:!1,responsive:1,responsiveHidden:!1,format:"",transform:"",filterType:"text",firstFilterOption:{value:"",text:""}}}get defaultOptions(){return{id:null,url:"",perPage:10,debug:!1,filter:!1,menu:!1,sort:!1,server:!1,serverParams:{start:"start",length:"length",search:"search",sort:"sort",sortDir:"sortDir",dataKey:"data",metaKey:"meta",metaTotalKey:"total",metaFilteredKey:"filtered",optionsKey:"options",paramsKey:"params"},defaultSort:"",reorder:!1,dir:"ltr",perPageValues:[10,25,50,100,250],hidePerPage:!1,columns:[],actions:[],collapseActions:!1,selectable:!1,selectVisibleOnly:!0,singleSelect:!1,defaultPage:1,resizable:!1,autosize:!0,expand:!1,autoheight:!0,autohidePager:!1,responsive:!1,responsiveToggle:!0,filterOnEnter:!0,filterKeypressDelay:500,spinnerClass:"",saveState:!1,errorMessage:"",noData:""}}get isInit(){return this.classList.contains("dg-initialized")}get hasDataError(){return this.classList.contains("dg-network-error")}static registerPlugins(t){B=t}static unregisterPlugins(t=null){t===null?B={}:delete B[t]}static registeredPlugins(){return B}convertColumns(t){let e=[];if(typeof t=="object"&&!Array.isArray(t))for(let i of Object.keys(t)){let o=Object.assign({},this.defaultColumn);o.title=t[i],o.field=i,e.push(o)}else for(let i of t){let o=Object.assign({},this.defaultColumn);typeof i=="string"?(o.title=i,o.field=i):typeof i=="object"?(o=Object.assign(o,i),o.field||console.error("Invalid column definition",i),o.title||(o.title=o.field)):console.error("Column definition must be a string or an object"),e.push(o)}return e}static get observedAttributes(){return["page","data-filter","data-sort","data-debug","data-reorder","data-menu","data-selectable","data-single-select","data-url","data-per-page","data-responsive"]}get transformAttributes(){return{columns:t=>this.convertColumns(X(t)),actions:t=>X(t),defaultPage:t=>Number.parseInt(t),perPage:t=>Number.parseInt(t)}}get thead(){return I("thead",this)}get tbody(){return I("tbody",this)}get tfoot(){return I("tfoot",this)}get page(){return Number.parseInt(this.getAttribute("page"))}set page(t){c(this,"page",this.constrainPageValue(t))}urlChanged(t=!1){return t&&!this.isInit?this:(this.reconfig(),this.loadData().then(()=>this.configureUi()))}reconfig(){let t=this.options.columns;return this.options.columns=[],this.configureUi(),this.options.columns=t,this}constrainPageValue(t){let e=t;return this.pages1&&this.page*this.options.perPage>this.totalRecords();)t--;t!==this.page?this.page=t:this.reload(()=>{(!this.plugins.FixedHeight||!this.plugins.FixedHeight.hasFixedHeight)&&this.selectPerPage.scrollIntoView()})}dirChanged(){c(this,"dir",this.options.dir)}defaultSortChanged(){this.sortChanged()}perPageValuesChanged(){if(this.selectPerPage){for(;this.selectPerPage.lastChild;)this.selectPerPage.removeChild(this.selectPerPage.lastChild);for(let t of this.options.perPageValues)Z(this.selectPerPage,t,t,t===this.options.perPage)}}async _connected(){this.table=this.querySelector("table"),this.btnFirst=this.querySelector(".dg-btn-first"),this.btnPrev=this.querySelector(".dg-btn-prev"),this.btnNext=this.querySelector(".dg-btn-next"),this.btnLast=this.querySelector(".dg-btn-last"),this.selectPerPage=this.querySelector(".dg-select-per-page"),this.inputPage=this.querySelector(".dg-input-page"),this.getFirst=this.getFirst.bind(this),this.getPrev=this.getPrev.bind(this),this.getNext=this.getNext.bind(this),this.getLast=this.getLast.bind(this),this.changePerPage=this.changePerPage.bind(this),this.gotoPage=this.gotoPage.bind(this),this.btnFirst.addEventListener("click",this.getFirst),this.btnPrev.addEventListener("click",this.getPrev),this.btnNext.addEventListener("click",this.getNext),this.btnLast.addEventListener("click",this.getLast),this.selectPerPage.addEventListener("change",this.changePerPage),this.selectPerPage.toggleAttribute("hidden",this.options.hidePerPage),this.inputPage.addEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))await t.connected();this.dirChanged(),this.perPageValuesChanged(),await this.init()}_disconnected(){this.btnFirst?.removeEventListener("click",this.getFirst),this.btnPrev?.removeEventListener("click",this.getPrev),this.btnNext?.removeEventListener("click",this.getNext),this.btnLast?.removeEventListener("click",this.getLast),this.selectPerPage?.removeEventListener("change",this.changePerPage),this.inputPage?.removeEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))t.disconnected()}init(){return this.loadData().finally(()=>{this.configureUi(),this.sortChanged(),this.classList.add("dg-initialized"),this.filterChanged(),this.reorderChanged(),this.dirChanged(),this.perPageValuesChanged(),this.pageChanged(),this.fireEvents=!0,this.log("initialized")})}getCol(t){let e=null;for(let i of this.options.columns)i.field===t&&(e=i);return e}getColProp(t,e){let i=this.getCol(t);return i?i[e]:null}setColProp(t,e,i){let o=this.getCol(t);o&&(o[e]=i)}visibleColumns(){return this.options.columns.filter(t=>!t.hidden)}hiddenColumns(){return this.options.columns.filter(t=>t.hidden===!0)}showColumn(t,e=!0){this.setColProp(t,"hidden",!1),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"visible"})}hideColumn(t,e=!0){this.setColProp(t,"hidden",!0),e&&this.renderTable(),y(this,"columnVisibility",{col:t,visibility:"hidden"})}startColIndex(){let t=1;return this.options.selectable&&this.plugins.SelectableRows&&t++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&t++,t}isSticky(){return this.hasAttribute("sticky")}columnsLength(t=!1){let e=0;for(let i of this.options.columns)t&&i.hidden||i.attr||e++;return this.options.selectable&&this.plugins.SelectableRows&&e++,this.options.actions.length&&this.plugins.RowActions&&e++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&e++,e}configureUi(){if(!this.table)return this;if(this.table.style.visibility="hidden",this.renderTable(),this.options.responsive&&this.plugins.ResponsiveGrid||(this.table.style.visibility="visible"),!this.rowHeight){let t=N(this,"tbody tr")||N(this,"table tr");t&&(this.rowHeight=t.offsetHeight)}return this.#t(this.tbody),this.fixPage()}filterChanged(){let t=this.querySelector("thead tr.dg-head-filters");this.options.filter?E(t,"hidden"):(this.clearFilters(),c(t,"hidden",""))}reorderChanged(){let t=g(this,"thead tr.dg-head-columns th");for(let e of t)e.classList.contains("dg-selectable")||e.classList.contains("dg-actions")||(this.options.reorder&&this.plugins.DraggableHeaders?e.draggable=!0:e.removeAttribute("draggable"))}sortChanged(){this.log("toggle sort");let t=g(this,"thead tr.dg-head-columns th");for(let e of t){let i=e.getAttribute("field");e.classList.contains("dg-not-sortable")||!this.fireEvents&&i===this.options.defaultSort||(this.options.sort&&!this.getColProp(i,"noSort")?c(e,"aria-sort","none"):E(e,"aria-sort"))}}selectableChanged(){this.renderTable()}addRow(t){Array.isArray(this.originalData)&&(this.log("add row"),this.originalData.push(t),this.data=this.originalData.slice(),this.sortData())}removeRow(t=null,e=null){if(!Array.isArray(this.originalData))return;let i=t,o=e;o===null&&(o=this.options.columns[0].field),i===null&&(i=this.originalData[this.originalData.length-1][o]),this.log(`remove row ${o}:${i}`);for(let n=0;n{this.hasDataError||(this.options.server||e?this.renderBody():this.paginate(),typeof t=="function"&&t())}).then(()=>this)}loadData(){let t=()=>!this.data.length&&this.classList.add("dg-empty"),e=this.tbody;return(this.meta||this.originalData||this.isInit)&&(!this.options.server||this.options.server&&!this.fireEvents)?(this.log("skip loadData"),t(),new Promise(i=>{i()})):(this.log("loadData"),this.loading=!0,this.classList.add("dg-loading"),this.classList.remove("dg-empty","dg-network-error"),this.fetchData().then(i=>{if(Array.isArray(i))this.data=i;else{if(!i[this.options.serverParams.dataKey]){console.error("Invalid response, it should contain a data key with an array or be a plain array",i),this.options.url=null;return}this.options=Object.assign(this.options,i[this.options.serverParams.optionsKey]??{}),this.meta=i[this.options.serverParams.metaKey]??{},this.data=i[this.options.serverParams.dataKey]}this.originalData=this.data.slice(),this.fixPage(),this.options.columns.length===0&&this.originalData.length?this.options.columns=this.convertColumns(Object.keys(this.originalData[0])):this.options.columns=this.convertColumns(this.options.columns)}).catch(i=>{this.log(i),e.setAttribute("data-empty",this.options.errorMessage||i.message?.replace(/^\s+|\r\n|\n|\r$/g,"")||C.networkError),this.classList.add("dg-empty","dg-network-error"),y(this,"loadDataFailed",i)}).finally(()=>{t(),this.#t(e),this.classList.remove("dg-loading"),c(this.table,"aria-rowcount",this.data.length),this.loading=!1}))}getFirst(){this.loading||(this.page=1)}getLast(){this.loading||(this.page=this.pages)}getPrev(){this.loading||(this.page=this.page-1)}getNext(){this.loading||(this.page=this.page+1)}gotoPage(t){if(t.type==="keypress"){let e=t.keyCode||t.key;if(e===13||e==="Enter")t.preventDefault();else return}this.page=Number.parseInt(this.inputPage.value)}getSort(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t?t.getAttribute("field"):this.options.defaultSort}getSortDir(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t&&t.getAttribute("aria-sort")||""}getFilters(){let t=[],e=g(this,this._filterSelector);for(let i of e)t[i.dataset.name]=i.value;return t}clearFilters(){let t=g(this,this._filterSelector);for(let e of t)e.value="";this.filterData()}filterData(){if(this.log("filter data"),this.page=1,this.options.server)this.reload();else{this.data=this.originalData?.slice()??[];let t=g(this,this._filterSelector);for(let i of t){let o=i.value;if(o){let n=i.dataset.name;this.data=this.data.filter(s=>`${s[n]}`.toLowerCase().indexOf(o.toLowerCase())!==-1)}}this.pageChanged();let e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");this.options.sort&&e?this.sortData():this.renderBody()}}sortData(t=null){this.log("sort data");let e=t;if(e&&this.getColProp(e.getAttribute("field"),"noSort")){this.log("sorting prevented because column is not sortable");return}if(this.plugins.ColumnResizer?.isResizing){this.log("sorting prevented because resizing");return}if(this.loading){this.log("sorting prevented because loading");return}if(e!==null){let i=n=>["dg-selectable","dg-actions","dg-responsive-toggle"].includes(n),o=g(this,"thead tr:first-child th");for(let n of o)[...n.classList].some(i)||!n.hasAttribute("aria-sort")||n!==e&&n.setAttribute("aria-sort","none");!e.hasAttribute("aria-sort")||e.getAttribute("aria-sort")==="none"?e.setAttribute("aria-sort","ascending"):e.getAttribute("aria-sort")==="ascending"?e.setAttribute("aria-sort","descending"):e.getAttribute("aria-sort")==="descending"&&e.setAttribute("aria-sort","none")}else e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");if(this.options.server)this.loadData().finally(()=>{this.renderBody()});else{let i=e?e.getAttribute("aria-sort"):"none";if(i==="none"){let o=[];this.originalData?.some(n=>(this.data.some(s=>JSON.stringify(n)===JSON.stringify(s)?(o.push(s),!0):!1),o.length===this.data.length)),this.data=o}else{let o=e.getAttribute("field");this.data.sort((n,s)=>{if(!isNaN(n[o])&&!isNaN(s[o]))return i==="ascending"?n[o]-s[o]:s[o]-n[o];let a=i==="ascending"?n[o].toUpperCase():s[o].toUpperCase(),l=i==="ascending"?s[o].toUpperCase():n[o].toUpperCase();switch(!0){case a>l:return 1;case athis._sort(t,"ascending");sortDesc=t=>this._sort(t,"descending");sortNone=t=>this._sort(t,"none");fetchData(){if(!this.options.url)return new Promise((o,n)=>n("No url set"));let t=window.location.href;t.split("/").pop().includes(".")||(t+=t.endsWith("/")?"":"/");let e=new URL(this.options.url,t),i={r:Date.now()};return this.options.server&&(i[this.options.serverParams.start]=this.page-1,i[this.options.serverParams.length]=this.options.perPage,this.options.filter&&(i[this.options.serverParams.search]=this.getFilters()),i[this.options.serverParams.sort]=this.getSort()||"",i[this.options.serverParams.sortDir]=this.getSortDir(),this.meta?.[this.options.serverParams.paramsKey]&&(i=Object.assign(i,this.meta[this.options.serverParams.paramsKey]))),Q(e,i),fetch(e).then(o=>{let n=new Error(o.statusText||C.networkError);if(!o.ok)throw n.response=o,n;return o.clone().json().catch(s=>{let a=s;throw this.options.debug||(a=n),a.response=o,a})})}renderTable(){this.log("render table"),this.options.menu&&this.plugins.ContextMenu&&this.plugins.ContextMenu.createMenu();let t;this.renderHeader(),this.options.defaultSort&&(t=this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`)),t?this.sortData(t):this.renderBody(),this.renderFooter()}renderHeader(){this.log("render header");let t=this.thead;this.createColumnHeaders(t),this.createColumnFilters(t),this.options.resizable&&this.plugins.ColumnResizer&&this.plugins.ColumnResizer.renderResizer(C.resizeColumn),y(this,"headerRendered")}renderFooter(){this.log("render footer");let t=this.tfoot;if(!t)return;let e=t.querySelector("td");t.removeAttribute("hidden"),c(e,"colspan",this.columnsLength(!0)),t.style.display=""}createColumnHeaders(t){let e=this.clientWidth,i=Math.round(e/this.columnsLength(!0)*2),o=0,n;n=x("tr"),this.headerRow=n,n.setAttribute("role","row"),n.setAttribute("aria-rowindex","1"),n.setAttribute("class","dg-head-columns");let s=t?.querySelector("tr.dg-head-columns th");this.log("createColumnHeaders - sampleTh",s),s||(s=x("th"),t?.querySelector("tr").appendChild(s)),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createHeaderCol(n),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createHeaderCol(n),o=0;let a=0;this.log("createColumnHeaders - columns",this.options.columns);for(let d of this.options.columns){if(d.attr)continue;let h=o+this.startColIndex(),u=x("th");u.setAttribute("scope","col"),u.setAttribute("role","columnheader button"),u.setAttribute("aria-colindex",`${h}`),u.setAttribute("id",q("dg-col-")),this.options.sort&&!d.noSort&&u.setAttribute("aria-sort","none"),u.setAttribute("field",d.field),this.plugins.ResponsiveGrid&&this.options.responsive&&c(u,"data-responsive",d.responsive||"");let p=_(d.title,s,!0)+20;u.dataset.minWidth=`${p}`,wt(u,d),u.tabIndex=0,u.textContent=d.title;let f=0;if(this.options.autosize&&this.plugins.AutosizeColumn){let b=Math.min(e-a,i);f=this.plugins.AutosizeColumn.computeSize(u,d,Number.parseInt(u.dataset.minWidth),b)}else f=Math.max(Number.parseInt(u.dataset.minWidth),Number.parseInt(u.getAttribute("width")));c(u,"width",f),d.hidden?u.setAttribute("hidden",""):a+=f,this.options.reorder&&this.plugins.DraggableHeaders&&this.plugins.DraggableHeaders.makeHeaderDraggable(u),n.appendChild(u),o++}if(ae){this.log(`adjust width to fix size, ${t.offsetWidth} > ${e}`);let d=this.offsetWidth-this.clientWidth,h=t.offsetWidth-e-d;this.options.responsive&&this.plugins.ResponsiveGrid&&(h+=d);let u=g(n,"th[width]");for(let p of u){if(T(p,"dg-not-resizable")||h<=0)continue;let f=Number.parseInt(p.getAttribute("width")),b=p.dataset.minWidth?Number.parseInt(p.dataset.minWidth):0;if(f>b){let A=f-h;Athis.sortData(d));this.table&&c(this.table,"aria-colcount",this.columnsLength(!0))}createColumnFilters(t){let e=0,i;i=x("tr"),this.filterRow=i,i.setAttribute("role","row"),i.setAttribute("aria-rowindex","2"),i.setAttribute("class","dg-head-filters"),this.options.filter||i.setAttribute("hidden",""),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createFilterCol(i),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createFilterCol(i),this.log("createColumnFilters - columns",this.options.columns);for(let n of this.options.columns){if(n.attr)continue;let s=e+this.startColIndex(),a=t?.querySelector(`tr.dg-head-columns th[aria-colindex="${s}"]`);if(!a){console.warn("Related th not found",s);continue}let l=x("th");l.setAttribute("aria-colindex",`${s}`);let d=this.createFilterElement(n,a);this.options.filter?d.tabIndex=0:l.tabIndex=0,n.hidden&&l.setAttribute("hidden",""),l.appendChild(d),i.appendChild(l),e++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionFilter(i),t?.replaceChild(i,t.querySelector("tr.dg-head-filters")),(typeof this.options.filterKeypressDelay!="number"||this.options.filterOnEnter)&&(this.options.filterKeypressDelay=0);let o=g(i,this._filterSelector);for(let n of o){let s=/select/i.test(n.tagName),a=s?"change":"keyup",l=G(d=>{let h=d.keyCode||d.key,u=!this.options.filterOnEnter&&!this._excludedKeys.some(p=>p===h);(h===13||h==="Enter"||u||d.type==="change"||d.type==="paste")&&this.filterData.call(this)},this.options.filterKeypressDelay);n.addEventListener(a,l),s||n.addEventListener("paste",l)}}createFilterElement(t,e){let i=t.filterType==="select",o=i?x("select"):x("input");if(i){if(!Array.isArray(t.filterList)){let n=[...new Set((this.data??[]).map(s=>s[t.field]))].filter(s=>s).sort();t.filterList=[t.firstFilterOption||this.defaultColumn.firstFilterOption].concat(n.map(s=>({value:s,text:s})))}for(let n of t.filterList){let s=x("option");s.value=n.value,s.text=n.text,o instanceof HTMLSelectElement&&o.add(s)}}else o.type="text",o.inputMode="search",o.autocomplete="off",o.spellcheck=!1;return o.dataset.name=t.field,o.id=q("dg-filter-"),o.setAttribute("aria-labelledby",e.getAttribute("id")),o}renderBody(){this.log("render body");let t,e,i,o=x("tbody");this.data.forEach((s,a)=>{t=x("tr"),c(t,"role","row"),c(t,"hidden",""),c(t,"aria-rowindex",a+1),t.tabIndex=0,this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createDataCol(t),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createDataCol(t),this.options.expand&&(t.classList.add("dg-expandable"),P(t,"click",l=>{l.target.matches(this._excludedRowElementSelector)||(this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.blockObserver(),yt(l.currentTarget,"dg-expanded"),this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.unblockObserver())})),i=0;for(let l of this.options.columns){if(l||console.error("Empty column found!",this.options.columns),l.attr){s[l.field]&&(l.attr==="class"?L(t,s[l.field]):t.setAttribute(l.attr,s[l.field]));return}if(e=x("td"),e.setAttribute("role","gridcell"),e.setAttribute("aria-colindex",`${i}${this.startColIndex()}`),wt(e,l),e.setAttribute("data-name",l.title),e.tabIndex=-1,l.editable&&this.plugins.EditableColumn)L(e,"dg-editable-col"),this.plugins.EditableColumn.makeEditableInput(e,l,s,a);else{let d=s[l.field]??"",h;switch(l.transform){case"uppercase":h=d.toUpperCase();break;case"lowercase":h=d.toLowerCase();break;default:h=d;break}if(l.format){if(l.defaultFormatValue!==void 0&&(h===""||h===null)&&(h=`${l.defaultFormatValue}`),typeof l.format=="string"&&h)e.innerHTML=M(l.format,Object.assign({_v:d,_tv:h},s));else if(l.format instanceof Function){let u=l.format.call(this,{column:l,rowData:s,cellData:h,td:e,tr:t});e.innerHTML=u||h||d}}else e.textContent=h}t.appendChild(e),i++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionRow(t,s),o.appendChild(t),y(this,"rowRendered",{rowData:s,tr:t})}),o.setAttribute("role","rowgroup");let n=this.tbody;n&&o.setAttribute("data-empty",n.getAttribute("data-empty")),this.table?.replaceChild(o,n),this.plugins.FixedHeight&&this.plugins.FixedHeight.createFakeRow(),this.paginate(),this.plugins.SelectableRows&&this.plugins.SelectableRows.shouldSelectAll(o),this.classList.toggle("dg-empty",!this.data.length),y(this,"bodyRendered")}paginate(){this.log("paginate");let t=this.totalRecords(),e=this.page||1,i=this.tbody,o=this.tfoot;if(!i||!o)return;let n=g(i,"tr");this.pages=this.totalPages();let s,a=e*this.options.perPage,l=a-this.options.perPage+1;a>t&&(a=t),t||(l=0);for(let d of n){if(this.options.server){E(d,"hidden");continue}s=Number(D(d,"aria-rowindex")),s>a||s=this.pages,this.btnLast.disabled=this.page>=this.pages),o.querySelector(".dg-low").textContent=l.toString(),o.querySelector(".dg-high").textContent=a.toString(),o.querySelector(".dg-total").textContent=`${this.totalRecords()}`,o.toggleAttribute("hidden",this.options.autohidePager&&this.options.perPage>this.totalRecords())}totalPages(){return Math.ceil(this.totalRecords()/this.options.perPage)}totalRecords(){return this.options.server?this.meta?.[this.options.serverParams.metaFilteredKey]||0:this.data.length}},j=it;var st=class{constructor(t){this.grid=t}connected(){}disconnected(){}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}},m=st;var ot=class extends m{constructor(t){super(t),this.isResizing=!1}renderResizer(t){let e=this.grid,i=e.table,o=g(e,"thead tr.dg-head-columns th");for(let n of o){if(T(n,"dg-not-resizable"))continue;let s=document.createElement("div");L(s,"dg-resizer"),s.ariaLabel=t,n.appendChild(s);let a=0,l=0,d=0,h=0,u=f=>{if(f.clientX>h)return;let b=l+(f.clientX-a);n.dataset.minWidth&&b>Number.parseInt(n.dataset.minWidth)&&c(n,"width",b)},p=()=>{e.log("resized column"),setTimeout(()=>{this.isResizing=!1},0),W(s,"dg-resizer-active"),e.options.reorder&&(n.draggable=!0),n.style.overflow="hidden",O(document,"mousemove",u),O(document,"mouseup",p),y(e,"columnResized",{col:D(n,"field"),width:D(n,"width")})};P(s,"click",f=>{f.stopPropagation()}),P(s,"mousedown",f=>{f.stopPropagation(),this.isResizing=!0;let b=f.target,S=g(e,"dg-head-columns th").filter(v=>!v.hasAttribute("hidden")),w=S.findIndex(v=>v===b.parentNode);e.log("resize column"),L(s,"dg-resizer-active"),E(n,"draggable"),n.style.overflow="visible",s.style.height=`${i.offsetHeight-1}px`,a=f.clientX,l=n.offsetWidth,d=(S.length-w)*30,h=tt(b).left+e.offsetWidth-d,c(n,"width",l);for(let v=0;vw&&E(o[v],"width");P(document,"mousemove",u),P(document,"mouseup",p)})}}},St=ot;function K(r,t,e="nodeName"){let i=r;for(;i[e]!==t;)i=i.parentElement;return i}var nt=class extends m{connected(){this.menu=this.grid.querySelector(".dg-menu")}disconnected(){this.grid.headerRow&&O(this.grid.headerRow,"contextmenu",this)}attachContextMenu(){let t=this.grid;P(t.headerRow,"contextmenu",this)}onchange(t){let e=this.grid,i=t.target,o=i.dataset.name;if(i.checked)e.showColumn(o);else{if(e.visibleColumns().length<=1){i.checked=!0;return}e.hideColumn(o)}e.fixPage()}oncontextmenu(t){t.preventDefault();let e=K(t.target,"THEAD"),i=this.menu,o=e.getBoundingClientRect(),n=t.clientX-o.left,s=t.clientY-o.top;i.style.top=`${s}px`,i.style.left=`${n}px`,E(i,"hidden"),n+150>o.width&&(n-=i.offsetWidth,i.style.left=`${n}px`);let a=l=>{i.contains(l.target)||(c(i,"hidden",""),O(document,"click",a))};P(document,"click",a)}createMenu(){let t=this.grid,e=this.menu;for(;e.lastChild;)e.removeChild(e.lastChild);e.addEventListener("change",this);for(let i of t.options.columns){if(i.attr)continue;let o=document.createElement("li"),n=document.createElement("label"),s=document.createElement("input");c(s,"type","checkbox"),c(s,"data-name",i.field),i.hidden||(s.checked=!0);let a=document.createTextNode(i.title);n.appendChild(s),n.appendChild(a),o.appendChild(n),e.appendChild(o)}}},Pt=nt;var rt=class extends m{makeHeaderDraggable(t){let e=this.grid;t.draggable=!0,P(t,"dragstart",i=>{if(e.plugins.ColumnResizer?.isResizing&&i.preventDefault){i.preventDefault();return}e.log("reorder col"),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",i.target.getAttribute("aria-colindex"))}),P(t,"dragover",i=>(i.preventDefault&&i.preventDefault(),i.dataTransfer.dropEffect="move",!1)),P(t,"drop",i=>{i.stopPropagation&&i.stopPropagation();let o=i.target,n=K(o,"TH"),s=Number.parseInt(i.dataTransfer.getData("text/plain")),a=Number.parseInt(n.getAttribute("aria-colindex"));if(s===a){e.log("reordered col stayed the same");return}e.log(`reordered col from ${s} to ${a}`);let l=e.startColIndex(),d=e.options.columns[s-l];e.options.columns[s-l]=e.options.columns[a-l],e.options.columns[a-l]=d;let h=(u,p)=>{let f=p.parentNode.getAttribute("aria-rowindex"),b=e.querySelector(`${u} tr[aria-rowindex="${f}"] [aria-colindex="${a}"]`);c(p,"aria-colindex",a),c(b,"aria-colindex",s);let A=document.createElement("th");p.parentNode.insertBefore(A,p),b.parentNode.replaceChild(p,b),A.parentNode.replaceChild(b,A)};for(let u of g(e,`thead th[aria-colindex="${s}"]`))h("thead",u);for(let u of g(e,`tbody td[aria-colindex="${s}"]`))h("tbody",u);return e.options.columns=g(e,"thead tr.dg-head-columns th[field]").map(u=>e.options.columns.find(p=>p.field===D(u,"field"))),y(e,"columnReordered",{col:d.field,from:s,to:a}),!1})}},At=rt;var at=class extends m{constructor(t){super(t),this.touch=null}connected(){let t=this.grid;t.addEventListener("touchstart",this,{passive:!0}),t.addEventListener("touchmove",this,{passive:!0})}disconnected(){let t=this.grid;t.removeEventListener("touchstart",this),t.removeEventListener("touchmove",this)}ontouchstart(t){this.touch=t.touches[0]}ontouchmove(t){if(!this.touch)return;let e=this.grid,i=this.touch.clientX-t.touches[0].clientX,o=this.touch.clientY-t.touches[0].clientY;Math.abs(i)>Math.abs(o)&&(i>0?e.getNext():e.getPrev()),this.touch=null}},Lt=at;var H="dg-selectable",lt="dg-select-all",kt="form-check-input",dt=class extends m{#t=`tbody tr${this.visibleOnly?":not([hidden])":""} .${H} input[type=checkbox]`;#e=`tbody .${H} input`;disconnected(){this.selectAll&&this.selectAll.removeEventListener("change",this)}get isSingleSelect(){return this.grid.options.singleSelect}get visibleOnly(){return this.grid.options.selectVisibleOnly}getSelection(...t){let e=this.grid,i=[],o=g(e,`${this.#e}:checked`);for(let n of o){let s=Number.parseInt(n.dataset.id),a=e.data[s-1];if(!a){console.warn(`Item ${s} not found`);continue}t.length===0?i.push(a):t.length===1?i.push(a[t[0]]):i.push(Object.fromEntries(t.map(l=>[l,a[l]])))}return this.isSingleSelect?i[0]??{}:i}clearCheckboxes(t){if(!this.grid.options.selectVisibleOnly)return;let i=g(t,`tr[hidden] .${H} input`);for(let o of i)o.checked=!1,this.isSingleSelect&&(o.dataset.toggled="false");this.selectAll.checked=!1}colIndex(){return this.grid.startColIndex()-2}createHeaderCol(t){let e=document.createElement("th");c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0,this.selectAll=document.createElement("input"),this.selectAll.type="checkbox",this.selectAll.classList.add(lt),this.selectAll.classList.add(kt),this.selectAll.addEventListener("change",this);let i=document.createElement("label");i.hidden=this.isSingleSelect,i.appendChild(this.selectAll),e.appendChild(i),e.setAttribute("width","40"),t.appendChild(e)}createFilterCol(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H),e.tabIndex=0,t.appendChild(e)}shouldSelectAll(t){this.selectAll&&(t.addEventListener("change",this),t.dispatchEvent(new Event("change")))}createDataCol(t){let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H);let i=document.createElement("input");i.dataset.id=t.getAttribute("aria-rowindex"),i.type=this.isSingleSelect?"radio":"checkbox",i.classList.add(kt),this.isSingleSelect&&(i.name="dg-row-select",i.dataset.toggled="false");let o=document.createElement("label");o.classList.add("dg-clickable-cell"),o.appendChild(i),e.appendChild(o),o.addEventListener("click",this),t.appendChild(e)}onclick(t){if(!this.isSingleSelect)return t.stopPropagation();let e=t.target,i=e.dataset.toggled!=="true";i&&Y(`${this.#t.replace("checkbox","radio")}`,this.grid)?.forEach(o=>{o.name===e.name&&o!==e&&(o.checked=o.dataset.toggled=!1)}),e.checked=e.dataset.toggled=i,!i&&this.onchange(t)}onchange(t){let e=t.target,i=this.grid;if(T(t.target,lt))g(i,this.#e).forEach(o=>{(!this.visibleOnly||o.offsetWidth)&&(o.checked=this.selectAll.checked)});else if(e.matches(this.#t)){if(!e.closest(`.${H}`))return;let o=g(i,this.#t);this.selectAll.checked=o.every(n=>n.checked)}e.matches(`.${lt},${this.#e}`)&&y(e,"rowsSelected",{selection:i.getSelection()},!0)}},Et=dt;var ct=class extends m{constructor(t){super(t),this.hasFixedHeight=!1,t.style.height&&(t.style.overflowY="auto",this.hasFixedHeight=!0)}createFakeRow(){let e=this.grid.querySelector("tbody"),i=document.createElement("tr");c(i,"role","row"),c(i,"hidden",""),i.classList.add("dg-fake-row"),i.tabIndex=0,e?.appendChild(i)}get fakeRow(){return this.grid.querySelector(".dg-fake-row")}updateFakeRow(){let t=this.grid,e=this.fakeRow;if(!e||t.options.perPage>t.totalRecords()||t.page!==t.totalPages()||!t.options.autoheight)return;let i=t.options.perPage*t.rowHeight,o=t.querySelectorAll("tbody tr:not([hidden])").length,n=o>1?i-o*t.rowHeight:i;n>0?(c(e,"height",n),e.removeAttribute("hidden")):e.removeAttribute("height")}},Dt=ct;var ht=class extends m{computeSize(t,e,i,o){let n=this.grid;if(U(t,"width"))return D(t,"width");if(!n.data.length)return;let s=n.data[0],a=n.data[n.data.length-1],l=s[e.field]?s[e.field].toString():"",d=a[e.field]?a[e.field].toString():"";d.length>l.length&&(l=d);let h=0;return l.length<=6?h=i:l.length>50?h=o:h=_(`${l}0000`,t),h>o&&(h=o),h{let i=Number.parseInt(t.dataset.responsive)||1;return(Number.parseInt(e.dataset.responsive)||1)-i})}var Wt=G(r=>{for(let t of r){let e=t.target,i=e.table;if(e.plugins.ResponsiveGrid.observerBlocked)return;let o=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize,n=Number.parseInt(o.inlineSize),s=i.offsetWidth,a=g(e.headerRow,"th").reduce((S,w)=>S+w.offsetWidth,0),l=(a||s)-n-1,d=50,h=e.plugins.ResponsiveGrid.prevAction,u=Ft(g(e.headerRow,"th[field]").reverse().filter(S=>S.dataset.responsive!=="0")),p=!1;if(e.log(`table is ${s}/${a} and available size is ${n}. Diff: ${l}`),l>0){if(h==="show")return;e.plugins.ResponsiveGrid.prevAction="hide";let S=l,w=u.filter(v=>!v.hasAttribute("hidden")&&v.hasAttribute("data-responsive"));if(w.length===0&&(w=u.filter(v=>!v.hasAttribute("hidden")),w.length===1))return;for(let v of w){if(S<0)continue;let $=v.offsetWidth,R=v.getAttribute("field");R&&(v.dataset.baseWidth=`${v.offsetWidth}`,e.hideColumn(R,!1),e.setColProp(R,"responsiveHidden",!0),p=!0,S-=$,S=Math.round(S))}}else{if(h==="hide")return;e.plugins.ResponsiveGrid.prevAction="show";let S=u.filter($=>!$.hasAttribute("hidden")).reduce(($,R)=>{let z=R.dataset.minWidth?Number.parseInt(R.dataset.minWidth):R.offsetWidth;return $+z},0)+d,w=n-S,v=u.slice().reverse().filter($=>$.hasAttribute("hidden"));for(let $ of v){if(ww){w=-1;continue}let z=$.getAttribute("field");z&&(e.showColumn(z,!1),e.setColProp(z,"responsiveHidden",!1),p=!0,w-=R,w=Math.round(w))}}let f=N(e.table,"tfoot"),b=g(e.table,".dg-footer > div").reduce((S,w)=>S+w.offsetWidth,0),A=f.offsetWidth-b;b>n?L(f,"dg-footer-compact"):A>250&&W(f,"dg-footer-compact"),p&&e.renderTable(),setTimeout(()=>{e.plugins.ResponsiveGrid.prevAction=null},1e3),e.table.style.visibility="visible"}},100),Rt=new ResizeObserver(Wt),gt=class extends m{constructor(t){super(t),this.observerBlocked=!1,this.prevAction=null}connected(){this.grid.options.responsive&&this.observe()}disconnected(){this.unobserve()}observe(){this.grid.options.responsive&&(Rt.observe(this.grid),this.grid.style.display="block",this.grid.style.overflowX="hidden")}unobserve(){Rt.unobserve(this.grid),this.grid.style.display="unset",this.grid.style.overflowX="unset"}blockObserver(){this.observerBlocked=!0,ut&&clearTimeout(ut)}unblockObserver(){ut=setTimeout(()=>{this.observerBlocked=!1},200)}hasHiddenColumns(){let t=!1;for(let e of this.grid.options.columns)e.responsiveHidden&&(t=!0);return t}colIndex(){return this.grid.startColIndex()-1}createHeaderCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),c(e,"width","40"),e.classList.add(`${k}-toggle`,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0}createFilterCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${k}-toggle`),e.tabIndex=0}createDataCol(t){if(!this.grid.options.responsiveToggle)return;let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${k}-toggle`),e.innerHTML=`
-
`,t.appendChild(e),e.addEventListener("click",this),e.addEventListener("mousedown",this)}computeLabelWidth(){let t=0,e=0;for(;t<120;){e++;let i=N(this.grid,`.dg-head-columns th[aria-colindex="${e}"]`);if(i)t+=i.offsetWidth;else break}return t}onmousedown(t){t.preventDefault()}onclick(t){t.stopPropagation();let e=t.currentTarget,i=e.parentElement,o=N(e,`.${L}-open`),n=N(e,`.${L}-close`);if(this.blockObserver(),T(i,`${L}-expanded`)){W(i,`${L}-expanded`),o.style.display="unset",n.style.display="none";let a=i.nextElementSibling,l=g(a,`.${L}-hidden`);for(let d of l)i.appendChild(d),c(d,"hidden");a.parentElement.removeChild(a)}else{E(i,`${L}-expanded`),o.style.display="none",n.style.display="unset";let a=x("tr");xt(a,i),E(a,`${L}-child-row`);let l=x("td",a);c(l,"colspan",this.grid.columnsLength(!0));let d=x("table",l);E(d,`${L}-table`);let h=g(i,`.${L}-hidden`),u=this.computeLabelWidth();for(let p of h){let f=x("tr",d),b=p.dataset.name,A=x("th",f);A.style.width=`${u}px`,A.innerHTML=b,f.appendChild(p),k(p,"hidden")}}this.unblockObserver()}},It=gt;var pt=class extends m{hasActions(){return this.grid.options.actions.length>0}makeActionHeader(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions","dg-not-sortable","dg-not-resizable",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionFilter(t){let e=document.createElement("th");e.setAttribute("role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionRow(t,e){let i=this.grid.labels,o=document.createElement("td");c(o,"role","gridcell"),c(o,"aria-colindex",this.grid.columnsLength(!0)),o.classList.add("dg-actions",this.actionClass),o.tabIndex=0;let n=document.createElement("button");n.classList.add("dg-actions-toggle"),n.innerHTML="\u2630",o.appendChild(n),S(n,"click",s=>{s.stopPropagation(),s.target.parentElement.classList.toggle("dg-actions-expand")});for(let s of this.grid.options.actions){let a=document.createElement("button");s.html?a.innerHTML=s.html:a.innerText=s.title??s.name,s.title&&(a.title=s.title),s.url&&(a.type="submit",a.formAction=M(s.url,e)),s.class&&a.classList.add(...s.class.split(" "));let l=d=>{if(d.stopPropagation(),s.confirm&&!confirm(i.areYouSure)){d.preventDefault();return}y(this.grid,"action",{data:e,action:s.name})};a.addEventListener("click",l),o.appendChild(a),s.default&&(t.classList.add("dg-actionable"),t.addEventListener("click",l))}t.appendChild(o)}get actionClass(){return this.grid.options.actions.length<3&&!this.grid.options.collapseActions?`dg-actions-${this.grid.options.actions.length}`:"dg-actions-more"}},Tt=pt;var ft=class extends m{makeEditableInput(t,e,i,o){let n=this.grid.getAttribute("id"),s=document.createElement("input");s.type=e.editableType||"text",s.type==="email"&&(s.inputMode="email"),s.type==="decimal"&&(s.type="text",s.inputMode="decimal"),s.autocomplete="off",s.spellcheck=!1,s.tabIndex=0,s.classList.add("dg-editable"),s.name=`${n.replace("-","_")}[${o+1}][${e.field}]`,s.value=i[e.field],s.dataset.field=e.field,s.addEventListener("click",a=>a.stopPropagation()),s.addEventListener("keypress",a=>{if(a.type==="keypress"){let l=a.keyCode||a.key;(l===13||l==="Enter")&&(s.blur(),a.preventDefault())}}),s.addEventListener("blur",()=>{s.value!==i[s.dataset.field]&&(i[s.dataset.field]=s.value,y(this.grid,"edit",{data:i,value:s.value}))}),t.appendChild(s)}},Nt=ft;var mt=class extends m{connected(){this.grid.options.spinnerClass&&this.grid.plugins.SpinnerSupport&&this.add()}add(){let t=this.grid,e=t.options.spinnerClass;if(!e)return;let i=e.split(" ").map(n=>`.${n}`).join(""),o=` +
`,t.appendChild(e),e.addEventListener("click",this),e.addEventListener("mousedown",this)}computeLabelWidth(){let t=0,e=0;for(;t<120;){e++;let i=N(this.grid,`.dg-head-columns th[aria-colindex="${e}"]`);if(i)t+=i.offsetWidth;else break}return t}onmousedown(t){t.preventDefault()}onclick(t){t.stopPropagation();let e=t.currentTarget,i=e.parentElement,o=N(e,`.${k}-open`),n=N(e,`.${k}-close`);if(this.blockObserver(),T(i,`${k}-expanded`)){W(i,`${k}-expanded`),o.style.display="unset",n.style.display="none";let a=i.nextElementSibling,l=g(a,`.${k}-hidden`);for(let d of l)i.appendChild(d),c(d,"hidden");a.parentElement.removeChild(a)}else{L(i,`${k}-expanded`),o.style.display="none",n.style.display="unset";let a=x("tr");xt(a,i),L(a,`${k}-child-row`);let l=x("td",a);c(l,"colspan",this.grid.columnsLength(!0));let d=x("table",l);L(d,`${k}-table`);let h=g(i,`.${k}-hidden`),u=this.computeLabelWidth();for(let p of h){let f=x("tr",d),b=p.dataset.name,A=x("th",f);A.style.width=`${u}px`,A.innerHTML=b,f.appendChild(p),E(p,"hidden")}}this.unblockObserver()}},It=gt;var pt=class extends m{hasActions(){return this.grid.options.actions.length>0}makeActionHeader(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions","dg-not-sortable","dg-not-resizable",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionFilter(t){let e=document.createElement("th");e.setAttribute("role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionRow(t,e){let i=this.grid.labels,o=document.createElement("td");c(o,"role","gridcell"),c(o,"aria-colindex",this.grid.columnsLength(!0)),o.classList.add("dg-actions",this.actionClass),o.tabIndex=0;let n=document.createElement("button");n.classList.add("dg-actions-toggle"),n.innerHTML="\u2630",o.appendChild(n),P(n,"click",s=>{s.stopPropagation(),s.target.parentElement.classList.toggle("dg-actions-expand")});for(let s of this.grid.options.actions){let a=document.createElement("button");s.html?a.innerHTML=s.html:a.innerText=s.title??s.name,s.title&&(a.title=s.title),s.url&&(a.type="submit",a.formAction=M(s.url,e)),s.class&&a.classList.add(...s.class.split(" "));let l=d=>{if(d.stopPropagation(),s.confirm&&!confirm(i.areYouSure)){d.preventDefault();return}y(this.grid,"action",{data:e,action:s.name})};a.addEventListener("click",l),o.appendChild(a),s.default&&(t.classList.add("dg-actionable"),t.addEventListener("click",l))}t.appendChild(o)}get actionClass(){return this.grid.options.actions.length<3&&!this.grid.options.collapseActions?`dg-actions-${this.grid.options.actions.length}`:"dg-actions-more"}},Tt=pt;var ft=class extends m{makeEditableInput(t,e,i,o){let n=this.grid.getAttribute("id"),s=document.createElement("input");s.type=e.editableType||"text",s.type==="email"&&(s.inputMode="email"),s.type==="decimal"&&(s.type="text",s.inputMode="decimal"),s.autocomplete="off",s.spellcheck=!1,s.tabIndex=0,s.classList.add("dg-editable"),s.name=`${n.replace("-","_")}[${o+1}][${e.field}]`,s.value=i[e.field],s.dataset.field=e.field,s.addEventListener("click",a=>a.stopPropagation()),s.addEventListener("keypress",a=>{if(a.type==="keypress"){let l=a.keyCode||a.key;(l===13||l==="Enter")&&(s.blur(),a.preventDefault())}}),s.addEventListener("blur",()=>{s.value!==i[s.dataset.field]&&(i[s.dataset.field]=s.value,y(this.grid,"edit",{data:i,value:s.value}))}),t.appendChild(s)}},Nt=ft;var mt=class extends m{connected(){this.grid.options.spinnerClass&&this.grid.plugins.SpinnerSupport&&this.add()}add(){let t=this.grid,e=t.options.spinnerClass;if(!e)return;let i=e.split(" ").map(n=>`.${n}`).join(""),o=` -`;if(!I("#dg-styles")){let n=I("head")??I("body"),s=/head/i.test(n.tagName)?"beforeend":"afterbegin";n.insertAdjacentHTML(s,o)}!I(`i${i}`,t)&&t.insertAdjacentHTML("afterbegin",``)}},Ht=mt;var bt=class extends m{constructor(t){super(t),this.cachedState=null,this.isFilterSortSet=!1,this.isDataLoaded=!1,this.isScrolled=!1,this.log("Init")}async connected(){this.log("connected");let t=this.grid;if(this.log(t.options),!t.options.saveState){this.log("disabled");return}this.log("enabled");let e=this._getState();if(e){let n=async()=>{if(!t.options.server)return;let a=500,l=Date.now(),d;for(;(d=!t.options.columns?.length)&&Date.now()-lrequestAnimationFrame(h));d&&this.log("Timeout waiting for columns.")};await(async()=>{await n(),this.log("hide columns");for(let a of e.columns)if(a.hidden){let l=t.options.columns.find(d=>d.field===a.field);l.hidden=!0}this.log("set: meta, pages"),t.options.perPage=e.perPage,t.options.server&&(t.meta=e.meta,t.pages=e.pages,t.page=e.page)})()}this.cachedState=e,this.log("cachedState",this.cachedState);let i=t.loadData;t.loadData=function(...n){return i.apply(this,n).finally(()=>{let s=this.plugins.SaveState;if(s.log("loadData",this.options.columns),!t.classList.contains("dg-initialized")){s.log("not init, loadData skipped");return}if(s.log("loadData finished, set param controls",this.options.columns),s.cachedState&&!s.isFilterSortSet){s.log("set sort and filters");let d=g(t,"thead tr.dg-head-columns th[aria-sort]");for(let u of d)u.setAttribute("aria-sort","none");t.querySelector(`thead tr.dg-head-columns th[field='${s.cachedState.sort}']`)?.setAttribute("aria-sort",s.cachedState.sortDir);let h=g(t.filterRow,"[id^=dg-filter]");s.log("filters",h);for(let u of h)u.value=s?.cachedState?.filters?.[u.dataset.name]??"",s.log({name:u.dataset.name,val:u.value,saveState:s});s.isFilterSortSet=!0}let a={meta:t.meta,pages:t.pages,page:t.page,perPage:t.options.perPage,filters:{},columns:t.options.columns.map(d=>({field:d.field,hidden:d.hidden})),sort:t.getSort(),sortDir:t.getSortDir(),scrollTo:window.scrollY},l=t.getFilters();s.log("filters",l);for(let d of Object.keys(l))a.filters[d]=l[d]??"",s.log({key:d,val:l[d],newState:a,filters:l});s.log("store new state",a),s._setState(a),!t.options.server&&s.cachedState&&!s.isDataLoaded&&(s.isDataLoaded=!0,t.filterData(),t.page=s.cachedState.page,t.pageChanged(),s.log("data loaded"))})};let o=()=>{let n=t.plugins.SaveState,s=n._getState();s&&(s.columns=t.options.columns.map(a=>({field:a.field,hidden:a.hidden})),s.sort=t.getSort(),s.sortDir=t.getSortDir(),s.scrollTo=window.scrollY,n._setState(s))};document.addEventListener("scrollend",o),t.addEventListener("headerRendered",o),t.addEventListener("bodyRendered",n=>{if(!t.classList.contains("dg-initialized")||t.classList.contains("dg-loading"))return;t.options.server||o();let s=t.plugins.SaveState;!s.cachedState||!s.isFilterSortSet||(s.isDataLoaded?s.isScrolled||(s.isScrolled=!0,window.scrollTo({top:s.cachedState.scrollTo,left:0,behavior:"instant"})):(s.isDataLoaded=!0,t.reload(),s.log("***grid reloaded")))})}log(...t){this.grid.log("[Save-State] ",...t)}_getState(){let t;try{t=JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`))}catch{}return t}_setState(t){sessionStorage.setItem(`gridSaveState_${this.grid.id}`,JSON.stringify(t))}},Ot=bt;j.registerPlugins({ColumnResizer:Pt,ContextMenu:St,DraggableHeaders:At,TouchSupport:Lt,SelectableRows:Et,FixedHeight:Dt,AutosizeColumn:$t,ResponsiveGrid:It,RowActions:Tt,EditableColumn:Nt,SpinnerSupport:Ht,SaveState:Ot});customElements.get("data-grid")||customElements.define("data-grid",j);var xi=j,Mt=typeof globalThis<"u"?globalThis:self;Mt.DataGrid=j;export{xi as default}; +`;if(!I("#dg-styles")){let n=I("head")??I("body"),s=/head/i.test(n.tagName)?"beforeend":"afterbegin";n.insertAdjacentHTML(s,o)}!I(`i${i}`,t)&&t.insertAdjacentHTML("afterbegin",``)}},Ht=mt;var bt=class extends m{constructor(t){super(t),this.cachedState=null,this.isFilterSortSet=!1,this.isDataLoaded=!1,this.isScrolled=!1,this.log("Init")}async connected(){this.log("connected");let t=this.grid;if(this.log(t.options),!t.options.saveState){this.log("disabled");return}this.log("enabled");let e=this._getState();if(e){let n=async()=>{if(!t.options.server)return;let a=500,l=Date.now(),d;for(;(d=!t.options.columns?.length)&&Date.now()-lrequestAnimationFrame(h));d&&this.log("Timeout waiting for columns.")};await(async()=>{await n(),this.log("hide columns");for(let a of e.columns)if(a.hidden){let l=t.options.columns.find(d=>d.field===a.field);l.hidden=!0}this.log("set: meta, pages"),t.options.perPage=e.perPage,t.options.server&&(t.meta=e.meta,t.pages=e.pages,t.page=e.page)})()}this.cachedState=e,this.log("cachedState",this.cachedState);let i=t.loadData;t.loadData=function(...n){return i.apply(this,n).finally(()=>{let s=this.plugins.SaveState;if(s.log("loadData",this.options.columns),!t.classList.contains("dg-initialized")){s.log("not init, loadData skipped");return}if(s.log("loadData finished, set param controls",this.options.columns),s.cachedState&&!s.isFilterSortSet){s.log("set sort and filters");let d=g(t,"thead tr.dg-head-columns th[aria-sort]");for(let u of d)u.setAttribute("aria-sort","none");t.querySelector(`thead tr.dg-head-columns th[field='${s.cachedState.sort}']`)?.setAttribute("aria-sort",s.cachedState.sortDir);let h=g(t.filterRow,"[id^=dg-filter]");s.log("filters",h);for(let u of h)u.value=s?.cachedState?.filters?.[u.dataset.name]??"",s.log({name:u.dataset.name,val:u.value,saveState:s});s.isFilterSortSet=!0}let a={meta:t.meta,pages:t.pages,page:t.page,perPage:t.options.perPage,filters:{},columns:t.options.columns.map(d=>({field:d.field,hidden:d.hidden})),sort:t.getSort(),sortDir:t.getSortDir(),scrollTo:window.scrollY},l=t.getFilters();s.log("filters",l);for(let d of Object.keys(l))a.filters[d]=l[d]??"",s.log({key:d,val:l[d],newState:a,filters:l});s.log("store new state",a),s._setState(a),!t.options.server&&s.cachedState&&!s.isDataLoaded&&(s.isDataLoaded=!0,t.filterData(),t.page=s.cachedState.page,t.pageChanged(),s.log("data loaded"))})};let o=()=>{let n=t.plugins.SaveState,s=n._getState();s&&(s.columns=t.options.columns.map(a=>({field:a.field,hidden:a.hidden})),s.sort=t.getSort(),s.sortDir=t.getSortDir(),s.scrollTo=window.scrollY,n._setState(s))};document.addEventListener("scrollend",o),t.addEventListener("headerRendered",o),t.addEventListener("bodyRendered",n=>{if(!t.classList.contains("dg-initialized")||t.classList.contains("dg-loading"))return;t.options.server||o();let s=t.plugins.SaveState;!s.cachedState||!s.isFilterSortSet||(s.isDataLoaded?s.isScrolled||(s.isScrolled=!0,window.scrollTo({top:s.cachedState.scrollTo,left:0,behavior:"instant"})):(s.isDataLoaded=!0,t.reload(),s.log("***grid reloaded")))})}log(...t){this.grid.log("[Save-State] ",...t)}_getState(){let t;try{t=JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`))}catch{}return t}_setState(t){sessionStorage.setItem(`gridSaveState_${this.grid.id}`,JSON.stringify(t))}},Ot=bt;j.registerPlugins({ColumnResizer:St,ContextMenu:Pt,DraggableHeaders:At,TouchSupport:Lt,SelectableRows:Et,FixedHeight:Dt,AutosizeColumn:$t,ResponsiveGrid:It,RowActions:Tt,EditableColumn:Nt,SpinnerSupport:Ht,SaveState:Ot});customElements.get("data-grid")||customElements.define("data-grid",j);var xi=j,Mt=typeof globalThis<"u"?globalThis:self;Mt.DataGrid=j;export{xi as default}; /** * Data Grid custom element * https://github.com/lekoala/data-grid/ diff --git a/dist/data-grid.min.js.map b/dist/data-grid.min.js.map index 1f7e219..01fa9ff 100644 --- a/dist/data-grid.min.js.map +++ b/dist/data-grid.min.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/utils/camelize.js", "../src/utils/normalizeData.js", "../src/utils/shortcuts.js", "../src/core/base-element.js", "../src/utils/addSelectOption.js", "../src/utils/appendParamsToUrl.js", "../src/utils/convertArray.js", "../src/utils/elementOffset.js", "../src/utils/interpolate.js", "../src/utils/getTextWidth.js", "../src/utils/randstr.js", "../src/utils/debounce.js", "../src/data-grid.js", "../src/core/base-plugin.js", "../src/plugins/column-resizer.js", "../src/utils/getParentElement.js", "../src/plugins/context-menu.js", "../src/plugins/draggable-headers.js", "../src/plugins/touch-support.js", "../src/plugins/selectable-rows.js", "../src/plugins/fixed-height.js", "../src/plugins/autosize-column.js", "../src/plugins/responsive-grid.js", "../src/plugins/row-actions.js", "../src/plugins/editable-column.js", "../src/plugins/spinner-support.js", "../src/plugins/save-state.js", "../data-grid.js"], - "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const isSelect = /select/i.test(el.tagName);\r\n const eventName = isSelect ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\" || e.type === \"paste\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n if (!isSelect) { // Add paste event support for text input filters\r\n el.addEventListener(\"paste\", eventHandler);\r\n }\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], - "mappings": "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", + "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\n if (column.width) {\n setAttribute(el, \"width\", column.width);\n }\n if (column.class) {\n addClass(el, column.class);\n }\n if (column.hidden) {\n setAttribute(el, \"hidden\", \"\");\n if (column.responsiveHidden) {\n addClass(el, \"dg-responsive-hidden\");\n }\n }\n if (column.noSort && el.tagName === \"TH\") {\n addClass(el, \"dg-not-sortable\");\n }\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\n this.log(\"toggle sort\");\n\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\n for (const th of headers) {\n const fieldName = th.getAttribute(\"field\");\n if (\n th.classList.contains(\"dg-not-sortable\") ||\n (!this.fireEvents && fieldName === this.options.defaultSort)\n ) {\n continue;\n }\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\n setAttribute(th, \"aria-sort\", \"none\");\n } else {\n removeAttribute(th, \"aria-sort\");\n }\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\n if (this.options.sort && !column.noSort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\n }\n // Make sure the header fits (+ add some room for sort icon if necessary)\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\n th.dataset.minWidth = `${computedWidth}`;\n applyColumnDefinition(th, column);\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const isSelect = /select/i.test(el.tagName);\r\n const eventName = isSelect ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\" || e.type === \"paste\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n if (!isSelect) { // Add paste event support for text input filters\r\n el.addEventListener(\"paste\", eventHandler);\r\n }\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `
\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"], + "mappings": "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", "names": ["camelize", "str", "m", "chr", "normalizeData", "v", "val", "supportedPassiveTypes", "passiveOpts", "type", "getAttribute", "el", "name", "hasAttribute", "setAttribute", "v", "check", "removeAttribute", "on", "listener", "off", "dispatch", "el", "name", "data", "bubbles", "opts", "hasClass", "addClass", "removeClass", "toggleClass", "$", "selector", "base", "$$", "find", "findAll", "ce", "tagName", "parent", "el", "insertAfter", "newNode", "existingNode", "BaseElement", "options", "opt", "v", "setAttribute", "jsonConfig", "data", "key", "normalizeData", "getAttribute", "event", "template", "dispatch", "attributeName", "oldValue", "newValue", "isOption", "transformer", "attr", "camelize", "base_element_default", "addSelectOption", "el", "value", "label", "checked", "opt", "appendParamsToUrl", "url", "params", "key", "k", "convertArray", "v", "bv", "elementOffset", "el", "rect", "scrollLeft", "scrollTop", "interpolate", "str", "data", "$1", "$2", "canvas", "getTextWidth", "text", "el", "withPadding", "styles", "fontWeight", "fontSize", "fontFamily", "padding", "paddingLeft", "paddingRight", "context", "metrics", "randstr", "prefix", "debounce", "handler", "timeout", "timer", "args", "plugins", "labels", "applyColumnDefinition", "el", "column", "setAttribute", "addClass", "DataGrid", "_DataGrid", "base_element_default", "randstr", "pluginName", "pluginClass", "attr", "camelize", "v", "#setNoData", "tbody", "list", "plugin", "columns", "cols", "key", "col", "item", "convertArray", "$", "val", "initOnly", "pv", "updatePage", "addSelectOption", "field", "found", "prop", "c", "render", "dispatch", "start", "visibleOnly", "len", "tr", "find", "row", "removeAttribute", "headers", "findAll", "th", "fieldName", "value", "k", "i", "keys", "force", "data", "metaKey", "dataKey", "callbackOrUrl", "needRender", "flagEmpty", "resolve", "response", "err", "event", "filters", "inputs", "input", "name", "baseCol", "haveClasses", "sort", "stack", "itemA", "itemB", "a", "b", "valA", "valB", "columnName", "sortDir", "dir", "reject", "base", "url", "params", "appendParamsToUrl", "newError", "error", "sortedColumn", "thead", "tfoot", "td", "availableWidth", "colMaxWidth", "idx", "ce", "sampleTh", "totalWidth", "colIdx", "computedWidth", "getTextWidth", "w", "colAvailableWidth", "visibleCols", "lastCol", "scrollbarWidth", "diff", "thWithWidth", "hasClass", "actualWidth", "minWidth", "newWidth", "rowsWithSort", "sortableRow", "relatedTh", "filter", "filteredRows", "isSelect", "eventName", "eventHandler", "debounce", "e", "isKeyPressFilter", "uniqueValues", "opt", "on", "ev", "toggleClass", "tv", "interpolate", "prev", "total", "p", "bodyRows", "index", "high", "low", "getAttribute", "data_grid_default", "BasePlugin", "grid", "event", "base_plugin_default", "ColumnResizer", "base_plugin_default", "grid", "resizeLabel", "table", "cols", "findAll", "col", "hasClass", "resizer", "addClass", "startX", "startW", "remainingSpace", "max", "mouseMoveHandler", "e", "newWidth", "setAttribute", "mouseUpHandler", "removeClass", "off", "dispatch", "getAttribute", "on", "target", "visibleCols", "columnIndex", "column", "removeAttribute", "elementOffset", "j", "column_resizer_default", "getParentElement", "el", "type", "prop", "parent", "ContextMenu", "base_plugin_default", "off", "grid", "on", "e", "t", "field", "target", "getParentElement", "menu", "rect", "x", "y", "removeAttribute", "documentClickHandler", "setAttribute", "col", "li", "label", "checkbox", "text", "context_menu_default", "DraggableHeaders", "base_plugin_default", "th", "grid", "on", "e", "t", "target", "getParentElement", "index", "targetIndex", "offset", "tmp", "swapNodes", "selector", "el1", "rowIndex", "el2", "setAttribute", "newNode", "findAll", "c", "getAttribute", "dispatch", "draggable_headers_default", "TouchSupport", "base_plugin_default", "grid", "e", "xDiff", "yDiff", "touch_support_default", "SELECTABLE_CLASS", "SELECT_ALL_CLASS", "CHECKBOX_CLASS", "SelectableRows", "base_plugin_default", "#cbSelector", "#inputSelector", "keys", "grid", "selectedData", "inputs", "findAll", "checkbox", "idx", "item", "k", "tbody", "input", "tr", "th", "setAttribute", "label", "td", "e", "el", "unchecked", "$$", "r", "hasClass", "cb", "totalCheckboxes", "dispatch", "selectable_rows_default", "FixedHeight", "base_plugin_default", "grid", "tbody", "tr", "setAttribute", "fakeRow", "max", "visibleRows", "fakeHeight", "fixed_height_default", "AutosizeColumn", "base_plugin_default", "th", "column", "min", "max", "grid", "hasAttribute", "getAttribute", "firstVal", "lastVal", "v", "v2", "width", "getTextWidth", "setAttribute", "autosize_column_default", "RESPONSIVE_CLASS", "obsTo", "sortByPriority", "list", "a", "b", "v1", "callback", "debounce", "entries", "entry", "grid", "table", "contentBoxSize", "size", "tableWidth", "realTableWidth", "findAll", "result", "th", "diff", "minWidth", "prevAction", "headerCols", "col", "changed", "remaining", "cols", "colWidth", "field", "requiredWidth", "width", "filteredHeaderCols", "footer", "find", "realFooterWidth", "div", "availableFooterWidth", "addClass", "removeClass", "resizeObserver", "ResponsiveGrid", "base_plugin_default", "flag", "tr", "ce", "setAttribute", "td", "idealWidth", "consideredCol", "hCol", "ev", "open", "close", "hasClass", "childRow", "hiddenCols", "insertAfter", "childRowTd", "childTable", "childTableRow", "label", "labelCol", "removeAttribute", "responsive_grid_default", "RowActions", "base_plugin_default", "tr", "actionsTh", "setAttribute", "item", "labels", "td", "actionsToggle", "on", "ev", "action", "button", "interpolate", "actionHandler", "dispatch", "row_actions_default", "EditableColumn", "base_plugin_default", "td", "column", "item", "i", "gridId", "input", "ev", "key", "dispatch", "editable_column_default", "SpinnerSupport", "base_plugin_default", "grid", "classes", "cls", "e", "template", "$", "styleParent", "position", "spinner_support_default", "SaveState", "base_plugin_default", "grid", "cachedState", "waitForColumns", "timeout", "start", "colAbsent", "resolve", "col", "hideCol", "c", "dgLoadData", "args", "saveState", "sortableHeaders", "findAll", "el", "filters", "newState", "key", "updateState", "state", "ev", "data", "save_state_default", "data_grid_default", "column_resizer_default", "context_menu_default", "draggable_headers_default", "touch_support_default", "selectable_rows_default", "fixed_height_default", "autosize_column_default", "responsive_grid_default", "row_actions_default", "editable_column_default", "spinner_support_default", "save_state_default", "global"] } diff --git a/src/data-grid.js b/src/data-grid.js index 97b0cc1..0355ef2 100644 --- a/src/data-grid.js +++ b/src/data-grid.js @@ -197,19 +197,22 @@ let labels = { * @param {HTMLElement} el * @param {Column} column */ -function applyColumnDefinition(el, column) { - if (column.width) { - setAttribute(el, "width", column.width); - } - if (column.class) { - addClass(el, column.class); - } - if (column.hidden) { - setAttribute(el, "hidden", ""); - if (column.responsiveHidden) { - addClass(el, "dg-responsive-hidden"); - } - } +function applyColumnDefinition(el, column) { + if (column.width) { + setAttribute(el, "width", column.width); + } + if (column.class) { + addClass(el, column.class); + } + if (column.hidden) { + setAttribute(el, "hidden", ""); + if (column.responsiveHidden) { + addClass(el, "dg-responsive-hidden"); + } + } + if (column.noSort && el.tagName === "TH") { + addClass(el, "dg-not-sortable"); + } } /** @@ -962,23 +965,23 @@ class DataGrid extends BaseElement { } } - sortChanged() { - this.log("toggle sort"); - - const headers = findAll(this, "thead tr.dg-head-columns th"); - for (const th of headers) { - const fieldName = th.getAttribute("field"); - if ( - th.classList.contains("dg-not-sortable") || - (!this.fireEvents && fieldName === this.options.defaultSort) - ) { - return; - } - if (this.options.sort && !this.getColProp(fieldName, "noSort")) { - setAttribute(th, "aria-sort", "none"); - } else { - removeAttribute(th, "aria-sort"); - } + sortChanged() { + this.log("toggle sort"); + + const headers = findAll(this, "thead tr.dg-head-columns th"); + for (const th of headers) { + const fieldName = th.getAttribute("field"); + if ( + th.classList.contains("dg-not-sortable") || + (!this.fireEvents && fieldName === this.options.defaultSort) + ) { + continue; + } + if (this.options.sort && !this.getColProp(fieldName, "noSort")) { + setAttribute(th, "aria-sort", "none"); + } else { + removeAttribute(th, "aria-sort"); + } } } @@ -1554,18 +1557,18 @@ class DataGrid extends BaseElement { th.setAttribute("scope", "col"); th.setAttribute("role", "columnheader button"); th.setAttribute("aria-colindex", `${colIdx}`); - th.setAttribute("id", randstr("dg-col-")); - if (this.options.sort) { + th.setAttribute("id", randstr("dg-col-")); + if (this.options.sort && !column.noSort) { th.setAttribute("aria-sort", "none"); } - th.setAttribute("field", column.field); - if (this.plugins.ResponsiveGrid && this.options.responsive) { - setAttribute(th, "data-responsive", column.responsive || ""); - } - // Make sure the header fits (+ add some room for sort icon if necessary) - const computedWidth = getTextWidth(column.title, sampleTh, true) + 20; - th.dataset.minWidth = `${computedWidth}`; - applyColumnDefinition(th, column); + th.setAttribute("field", column.field); + if (this.plugins.ResponsiveGrid && this.options.responsive) { + setAttribute(th, "data-responsive", column.responsive || ""); + } + // Make sure the header fits (+ add some room for sort icon if necessary) + const computedWidth = getTextWidth(column.title, sampleTh, true) + 20; + th.dataset.minWidth = `${computedWidth}`; + applyColumnDefinition(th, column); th.tabIndex = 0; th.textContent = column.title;