Skip to content
Snippets Groups Projects
Verified Commit bd266eca authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: datatable, datasource optimisation #272

parent fec8229e
No related branches found
No related tags found
No related merge requests found
Showing
with 1938 additions and 1314 deletions
...@@ -5,93 +5,13 @@ ...@@ -5,93 +5,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Datatable Pagination um Max Count erweitern #226</title> <title>Datatable Pagination um Max Count erweitern #226</title>
<script src="./226.mjs" type="module"></script> <script src="./226.mjs" type="module"></script>
<style>
:not(:defined) {
display: none;
}
.slide {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
main {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
monster-slider::part(prev) {
}
monster-slider::part(control) {
}
.container {
padding: 10px;
width: 1200px;
height: 600px;
background-color: #cccccc;
box-sizing: border-box;
overflow: hidden;
}
</style>
</head> </head>
<body> <body>
<h1>Datatable Pagination um Max Count erweitern #226</h1> <h1>Datatable Pagination um Max Count erweitern #226</h1>
<p>user aborted</p>
<ul> <ul>
<li><a href="https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/226">Issue #226</a></li> <li><a href="https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/226">Issue #226</a></li>
<li><a href="/">Back to overview</a></li> <li><a href="/">Back to overview</a></li>
</ul> </ul>
<main> <main></main>
<div class="container">
<monster-slider>
<div slot="prev"><svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="currentColor" class="bi bi-arrow-left-square-fill" viewBox="0 0 16 16">
<path d="M16 14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2zm-4.5-6.5H5.707l2.147-2.146a.5.5 0 1 0-.708-.708l-3 3a.5.5 0 0 0 0 .708l3 3a.5.5 0 0 0 .708-.708L5.707 8.5H11.5a.5.5 0 0 0 0-1"/>
</svg></div>
<div class="slide" style="display:none;background-color: #ff6666;width:50px">
<h1>SLIDE 1</h1>
</div>
<div class="slide" style="background-color: #ff6666;width:50px">
<h1>SLIDE 1 a</h1>
</div>
<div class="slide" style="background-color: #66ff66;width:50px;"><svg xmlns="http://www.w3.org/2000/svg"
width="467" height="462">
<rect x="80" y="60" width="250" height="250" rx="20"
style="fill:#ff0000; stroke:#000000;stroke-width:2px;" />
<rect x="140" y="120" width="250" height="250" rx="40"
style="fill:#0000ff; stroke:#000000; stroke-width:2px;
fill-opacity:0.7;" />
</svg></div>
<div class="slide" style="background-color: #6666ff;width:50px;">
<h1>SLIDE 3</h1>
</div>
<div slot="next">
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="currentColor" class="bi bi-arrow-right-square-fill" viewBox="0 0 16 16">
<path d="M0 14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2zm4.5-6.5h5.793L8.146 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L10.293 8.5H4.5a.5.5 0 0 1 0-1"/>
</svg>
</div>
</monster-slider>
</div>
</main>
</body> </body>
</html> </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>check and update data save button #272</title>
<script src="./272.mjs" type="module"></script>
</head>
<body>
<h1>check and update pagination and dataset #272</h1>
<p></p>
<ul>
<li><a href="https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/272">Issue #272</a></li>
<li><a href="/">Back to overview</a></li>
</ul>
<main>
<monster-datasource-rest id="ds272-r"
data-monster-option-features-autoInit="true"
data-monster-option-write-url="/issue-272.json"
data-monster-option-write-acceptedstatus="400::200"
data-monster-option-read-url="/issue-272.json?limit=1&page=${page}"
data-x-monster-option-read-mapping-transformer="path:dataset"
></monster-datasource-rest>
<monster-datasource-dom id="ds272-d">
<script type="application/json">
[
{
"id": 1,
"username": "martin89",
"email": "elena.richards@domain.com",
"full_name": "Elena Richards",
"age": 29,
"country": "Greece",
"registered_date": "2019-11-23",
"status": "active"
},
{
"id": 2,
"username": "sophiabell",
"email": "thomas.cook@gmail.com",
"full_name": "Thomas Cook",
"age": 22,
"country": "Portugal",
"registered_date": "2022-04-15",
"status": "banned"
},
{
"id": 3,
"username": "brianm",
"email": "chloe.adams@webmail.com",
"full_name": "Chloe Adams",
"age": 37,
"country": "New Zealand",
"registered_date": "2021-06-01",
"status": "inactive"
},
{
"id": 4,
"username": "larad",
"email": "alejandro.fuentes@yahoo.com",
"full_name": "Alejandro Fuentes",
"age": 45,
"country": "Japan",
"registered_date": "2024-01-20",
"status": "banned"
}
]
</script>
</monster-datasource-dom>
<monster-button-bar id="bb-r">
<monster-button>#1</monster-button>
<monster-button>#2</monster-button>
<monster-button>#3</monster-button>
<monster-button>#4</monster-button>
</monster-button-bar>
<monster-pagination
data-monster-option-datasource-selector="#ds272-r"
data-monster-option-objectsperpage="1"
></monster-pagination>
<hr>
<monster-dataset
id="ds-272"
data-monster-option-datasource-selector="#ds272-r">
<div style="display: grid; grid-template-columns: 1fr 1fr;gap: 0.1rem;width: 600px">
<div>ID</div>
<div data-monster-replace="path:data.id"></div>
<div>Username</div>
<div data-monster-replace="path:data.username"></div>
<div>Full Name</div>
<div data-monster-replace="path:data.full_name"></div>
<div>Email</div>
<div data-monster-replace="path:data.email"></div>
<div>Age</div>
<div data-monster-replace="path:data.age"></div>
<div>Country</div>
<div data-monster-replace="path:data.country"></div>
<div>Registered Date</div>
<div data-monster-replace="path:data.registered_date"></div>
<div>Status</div>
<div data-monster-replace="path:data.status"></div>
</div>
</monster-dataset>
<monster-pagination
data-monster-option-datasource-selector="#ds272-r"
data-monster-option-objectsperpage="1"
></monster-pagination>
<hr>
<hr>
<hr>
<hr>
<monster-pagination
data-monster-option-datasource-selector="#ds272-d"
data-monster-option-objectsperpage="1"
></monster-pagination>
<monster-button-bar id="bb-d">
<monster-button>#1</monster-button>
<monster-button>#2</monster-button>
<monster-button>#3</monster-button>
<monster-button>#4</monster-button>
</monster-button-bar>
<hr>
<monster-dataset
data-monster-option-mapping-data="" id="ds-272"
data-monster-option-datasource-selector="#ds272-d">
<div style="display: grid; grid-template-columns: 1fr 1fr;gap: 0.1rem;width: 600px">
<div>ID</div>
<div data-monster-replace="path:data.id"></div>
<div>Username</div>
<div data-monster-replace="path:data.username"></div>
<div>Full Name</div>
<div data-monster-replace="path:data.full_name"></div>
<div>Email</div>
<div data-monster-replace="path:data.email"></div>
<div>Age</div>
<div data-monster-replace="path:data.age"></div>
<div>Country</div>
<div data-monster-replace="path:data.country"></div>
<div>Registered Date</div>
<div data-monster-replace="path:data.registered_date"></div>
<div>Status</div>
<div data-monster-replace="path:data.status"></div>
</div>
</monster-dataset>
<monster-pagination
data-monster-option-datasource-selector="#ds272-d"
data-monster-option-objectsperpage="1"
></monster-pagination>
<hr>
<hr>
<hr>
<hr>
</main>
</body>
</html>
/**
* @file development/issues/open/272.mjs
* @url https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/272
* @description check and update data save button
* @issue 272
*/
import "../../../source/components/style/property.pcss";
import "../../../source/components/style/link.pcss";
import "../../../source/components/style/color.pcss";
import "../../../source/components/style/theme.pcss";
import "../../../source/components/style/normalize.pcss";
import "../../../source/components/style/typography.pcss";
import "../../../source/components/datatable/datasource/rest.mjs";
import "../../../source/components/datatable/datasource/dom.mjs";
import "../../../source/components/datatable/dataset.mjs";
import "../../../source/components/datatable/pagination.mjs";
import "../../../source/components/form/button.mjs";
import "../../../source/components/form/button-bar.mjs";
// DOM-Elemente für die Seiten-Datensätze
const pageData1 = document.getElementById("ds272-d");
const pageData2 = document.getElementById("ds272-r");
// Allgemeine Funktion zur Einstellung der Seitennummer
function setPage(dataElement, pageNum) {
dataElement.setParameters({page: pageNum});
}
// Initialisierung der Buttons und Event-Handler für die erste Datenquelle
const buttonBar1 = document.getElementById("bb-d");
['first', 'second', 'third', 'fourth'].forEach((label, index) => {
const button = buttonBar1.children[index];
button.setOption("actions.click", () => setPage(pageData1, index + 1));
});
// Initialisierung der Buttons und Event-Handler für die zweite Datenquelle
const buttonBar2 = document.getElementById("bb-r");
['first', 'second', 'third', 'fourth'].forEach((label, index) => {
const button = buttonBar2.children[index];
button.setOption("actions.click", () => setPage(pageData2, index + 1));
});
const json =
`[{
"id": 1,
"username": "wernerjennifer",
"email": "smithchristina@clark.biz",
"full_name": "Joshua Smith",
"age": 28,
"country": "Central African Republic",
"registered_date": "2020-01-17",
"status": "active"
},
{
"id": 2,
"username": "elizabethmurphy",
"email": "beverlywarren@gmail.com",
"full_name": "Sarah Snyder",
"age": 18,
"country": "Tajikistan",
"registered_date": "2023-05-10",
"status": "banned"
},
{
"id": 3,
"username": "ftaylor",
"email": "deckercassandra@conrad.com",
"full_name": "Rhonda Carroll",
"age": 34,
"country": "Australia",
"registered_date": "2022-07-31",
"status": "inactive"
},
{
"id": 4,
"username": "antoniocastillo",
"email": "tevans@hotmail.com",
"full_name": "Brad Brown",
"age": 39,
"country": "Nepal",
"registered_date": "2023-01-09",
"status": "banned"
},
{
"id": 5,
"username": "dylan46",
"email": "audreywalter@watts-conley.com",
"full_name": "Jacqueline Turner",
"age": 26,
"country": "United States Minor Outlying Islands",
"registered_date": "2024-10-14",
"status": "inactive"
},
{
"id": 6,
"username": "michael27",
"email": "thompsonsydney@gmail.com",
"full_name": "Stephanie Walls",
"age": 25,
"country": "Switzerland",
"registered_date": "2020-05-20",
"status": "inactive"
},
{
"id": 7,
"username": "vickie92",
"email": "mary35@jackson.com",
"full_name": "Colin Cohen",
"age": 23,
"country": "Saint Martin",
"registered_date": "2022-12-31",
"status": "active"
},
{
"id": 8,
"username": "fordomar",
"email": "hernandezbrian@gmail.com",
"full_name": "Christopher Garza",
"age": 65,
"country": "Antigua and Barbuda",
"registered_date": "2022-08-15",
"status": "banned"
},
{
"id": 9,
"username": "jerry82",
"email": "nwhite@yahoo.com",
"full_name": "Gabrielle Garza",
"age": 46,
"country": "Mauritania",
"registered_date": "2023-03-08",
"status": "inactive"
},
{
"id": 10,
"username": "alyssa54",
"email": "kevin11@hotmail.com",
"full_name": "Andrea Williams",
"age": 43,
"country": "Western Sahara",
"registered_date": "2023-04-19",
"status": "active"
},
{
"id": 11,
"username": "jacob30",
"email": "scottmary@yahoo.com",
"full_name": "Nicole Cunningham",
"age": 29,
"country": "French Polynesia",
"registered_date": "2022-02-21",
"status": "banned"
},
{
"id": 12,
"username": "ftucker",
"email": "simmonsrichard@jones.com",
"full_name": "Daniel Shelton",
"age": 42,
"country": "Cameroon",
"registered_date": "2024-04-20",
"status": "active"
},
{
"id": 13,
"username": "alvarezpaul",
"email": "ucannon@ortega.biz",
"full_name": "Matthew Poole",
"age": 44,
"country": "Chad",
"registered_date": "2021-09-22",
"status": "inactive"
},
{
"id": 14,
"username": "sarahunter",
"email": "allisoncharles@phillips-graves.com",
"full_name": "Nathan Fernandez",
"age": 40,
"country": "French Polynesia",
"registered_date": "2023-04-11",
"status": "inactive"
},
{
"id": 15,
"username": "sierra65",
"email": "hnicholson@gmail.com",
"full_name": "Michael Taylor",
"age": 27,
"country": "Indonesia",
"registered_date": "2021-08-15",
"status": "active"
},
{
"id": 16,
"username": "benjamin84",
"email": "zgallegos@hale-johnson.com",
"full_name": "Molly Santana",
"age": 32,
"country": "Holy See (Vatican City State)",
"registered_date": "2023-06-09",
"status": "inactive"
},
{
"id": 17,
"username": "peckpaul",
"email": "james03@hotmail.com",
"full_name": "Kelly Allen",
"age": 42,
"country": "Austria",
"registered_date": "2021-04-26",
"status": "active"
},
{
"id": 18,
"username": "jill42",
"email": "williamstephenson@hotmail.com",
"full_name": "Samuel Adkins",
"age": 22,
"country": "American Samoa",
"registered_date": "2024-10-04",
"status": "active"
},
{
"id": 19,
"username": "pottssavannah",
"email": "emily76@mckinney.com",
"full_name": "Jeremy Pearson",
"age": 42,
"country": "Lesotho",
"registered_date": "2020-06-15",
"status": "inactive"
},
{
"id": 20,
"username": "robertsdaniel",
"email": "robinsontodd@pineda.org",
"full_name": "Francis Castaneda",
"age": 58,
"country": "British Indian Ocean Territory (Chagos Archipelago)",
"registered_date": "2020-03-01",
"status": "inactive"
}
]
`;
// check if JSON is valid
const objects = JSON.parse(json)
if (!Array.isArray(objects)) {
throw new Error('Invalid JSON')
}
const requestDelay = 10
function wrapJsonWithPagination(data, page, limit) {
return JSON.stringify({
dataset: data,
sys: {
pagination: {
objectsPerPage: limit,
pages: Math.ceil(objects.length / limit),
currentPage: page
}
}
})
}
export default [
{
url: '/issue-272.json',
method: 'get',
rawResponse: async (req, res) => {
res.setHeader('Content-Type', 'application/json')
res.statusCode = 200
const url = new URL(req.url, `http://${req.headers.host}`)
const q = Object.fromEntries(url.searchParams)
let filtered = objects
if (q) {
let limit = 20
if (q.limit) {
limit = parseInt(q.limit)
}
if (q.page) {
const page = parseInt(q.page)
const start = (page - 1) * limit
const end = start + limit
filtered = objects.slice(start, end)
} else {
filtered = objects.slice(0, limit)
}
if (q.q) {
const query = q.q.toLowerCase()
filtered = objects.filter(item => item.name.toLowerCase().includes(query))
}
setTimeout(function () {
res.end(wrapJsonWithPagination(filtered, q.page || 1, limit))
}, requestDelay);
return
}
setTimeout(function () {
res.end(wrapJsonWithPagination(filtered, 1, 20))
}, requestDelay);
},
},
{
url: '/issue-272.json',
method: 'post',
rawResponse: async (req, res) => {
res.setHeader('Content-Type', 'application/json')
res.statusCode = 200
const jsonRespond = JSON.stringify({message: "Data has been successfully saved"})
res.end(jsonRespond)
}
}
];
\ No newline at end of file
...@@ -12,10 +12,8 @@ ...@@ -12,10 +12,8 @@
* SPDX-License-Identifier: AGPL-3.0 * SPDX-License-Identifier: AGPL-3.0
*/ */
import { instanceSymbol, internalSymbol } from "../../constants.mjs"; import {instanceSymbol} from "../../constants.mjs";
import {Pathfinder} from "../../data/pathfinder.mjs"; import {Pathfinder} from "../../data/pathfinder.mjs";
import { getLinkedObjects, hasObjectLink } from "../../dom/attributes.mjs";
import { customElementUpdaterLinkSymbol } from "../../dom/constants.mjs";
import { import {
assembleMethodSymbol, assembleMethodSymbol,
CustomElement, CustomElement,
...@@ -25,7 +23,6 @@ import { ...@@ -25,7 +23,6 @@ import {
import {findElementWithSelectorUpwards} from "../../dom/util.mjs"; import {findElementWithSelectorUpwards} from "../../dom/util.mjs";
import {isString} from "../../types/is.mjs"; import {isString} from "../../types/is.mjs";
import {Observer} from "../../types/observer.mjs"; import {Observer} from "../../types/observer.mjs";
import { clone } from "../../util/clone.mjs";
import { import {
ATTRIBUTE_DATASOURCE_SELECTOR, ATTRIBUTE_DATASOURCE_SELECTOR,
ATTRIBUTE_DATATABLE_INDEX, ATTRIBUTE_DATATABLE_INDEX,
...@@ -41,41 +38,17 @@ import { FormStyleSheet } from "../stylesheet/form.mjs"; ...@@ -41,41 +38,17 @@ import { FormStyleSheet } from "../stylesheet/form.mjs";
export {DataSet}; export {DataSet};
/** /**
* The data set component is used to show the data of a data source. * A data set component
* *
* <img src="./images/dataset.png"> * @fragments /fragments/components/datatable/dataset
* *
* You can create this control either by specifying the HTML tag <monster-dataset />` directly in the HTML or using * @example /examples/components/datatable/dataset-simple
* Javascript via the `document.createElement('monster-dataset');` method. * @example /examples/components/datatable/dataset-rest
* *
* ```html * @issue https://localhost.alvine.dev:8443/development/issues/closed/272.html
* <monster-dataset></monster-dataset>
* ```
*
* Or you can create this CustomControl directly in Javascript:
*
* ```js
* import '@schukai/component-datatable/source/dataset.mjs';
* document.createElement('monster-dataset');
* ```
*
* The Body should have a class "hidden" to ensure that the styles are applied correctly.
*
* ```css
* body.hidden {
* visibility: hidden;
* }
* ```
*
* @startuml dataset.png
* skinparam monochrome true
* skinparam shadowing false
* HTMLElement <|-- CustomElement
* CustomElement <|-- DataSet
* @enduml
* *
* @copyright schukai GmbH * @copyright schukai GmbH
* @summary A data set * @summary A dataset component that can be used to show the data of a data source
*/ */
class DataSet extends CustomElement { class DataSet extends CustomElement {
/** /**
...@@ -95,6 +68,7 @@ class DataSet extends CustomElement { ...@@ -95,6 +68,7 @@ class DataSet extends CustomElement {
static get observedAttributes() { static get observedAttributes() {
const attributes = super.observedAttributes; const attributes = super.observedAttributes;
attributes.push(ATTRIBUTE_DATATABLE_INDEX); attributes.push(ATTRIBUTE_DATATABLE_INDEX);
attributes.push("data-monster-option-mapping-index");
return attributes; return attributes;
} }
...@@ -111,7 +85,10 @@ class DataSet extends CustomElement { ...@@ -111,7 +85,10 @@ class DataSet extends CustomElement {
* @property {object} mapping The mapping * @property {object} mapping The mapping
* @property {string} mapping.data The data * @property {string} mapping.data The data
* @property {number} mapping.index The index * @property {number} mapping.index The index
* @property {Array} data The data * @property {object} features The features
* @property {boolean} features.refreshOnMutation Refresh on mutation
* @property {object} refreshOnMutation The refresh on mutation
* @property {string} refreshOnMutation.selector The selector
*/ */
get defaults() { get defaults() {
const obj = Object.assign({}, super.defaults, { const obj = Object.assign({}, super.defaults, {
...@@ -246,7 +223,7 @@ class DataSet extends CustomElement { ...@@ -246,7 +223,7 @@ class DataSet extends CustomElement {
[assembleMethodSymbol]() { [assembleMethodSymbol]() {
super[assembleMethodSymbol](); super[assembleMethodSymbol]();
initEventHandler.call(this); requestAnimationFrame(() => {
if (!this[datasourceLinkedElementSymbol]) { if (!this[datasourceLinkedElementSymbol]) {
const selector = this.getOption("datasource.selector"); const selector = this.getOption("datasource.selector");
...@@ -265,6 +242,8 @@ class DataSet extends CustomElement { ...@@ -265,6 +242,8 @@ class DataSet extends CustomElement {
element.datasource.attachObserver( element.datasource.attachObserver(
new Observer(handleDataSourceChanges.bind(this)), new Observer(handleDataSourceChanges.bind(this)),
); );
handleDataSourceChanges.call(this);
} else { } else {
throw new Error("the selector must be a string"); throw new Error("the selector must be a string");
} }
...@@ -276,6 +255,11 @@ class DataSet extends CustomElement { ...@@ -276,6 +255,11 @@ class DataSet extends CustomElement {
) { ) {
initMutationObserver.call(this); initMutationObserver.call(this);
} }
initEventHandler.call(this);
});
} }
/** /**
...@@ -290,12 +274,50 @@ class DataSet extends CustomElement { ...@@ -290,12 +274,50 @@ class DataSet extends CustomElement {
* @private * @private
*/ */
function initEventHandler() { function initEventHandler() {
this[attributeObserverSymbol][ATTRIBUTE_DATATABLE_INDEX] = () => {
this[attributeObserverSymbol][ATTRIBUTE_DATATABLE_INDEX] = () => { // @deprecated use data-monster-option-mapping-index
const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX); const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
if (index) { if (index) {
this.setOption("mapping.index", parseInt(index, 10)); this.setOption("mapping.index", parseInt(index, 10));
handleDataSourceChanges.call(this);
}
};
this[attributeObserverSymbol]["data-monster-option-mapping-index"] = () => {
const index = this.getAttribute("data-monster-option-mapping-index");
if (index !== null && index !== undefined && index !== "") {
this.setOption("mapping.index", parseInt(index, 10));
handleDataSourceChanges.call(this);
} }
}; };
if (this[datasourceLinkedElementSymbol]) {
this[datasourceLinkedElementSymbol].datasource.attachObserver(
new Observer(() => {
const page = this[datasourceLinkedElementSymbol]?.currentPage();
if (page !== null && page !== undefined && page !== "") {
const index = parseInt(page, 10) - 1;
this.setOption("mapping.index", index);
handleDataSourceChanges.call(this);
}
}),
);
this[datasourceLinkedElementSymbol].attachObserver(
new Observer(() => {
const page = this[datasourceLinkedElementSymbol]?.currentPage();
if (page !== null && page !== undefined && page !== "") {
const index = parseInt(page, 10) - 1;
this.setOption("mapping.index", index);
handleDataSourceChanges.call(this);
}
}),
);
handleDataSourceChanges.call(this);
}
} }
/** /**
...@@ -303,7 +325,7 @@ function initEventHandler() { ...@@ -303,7 +325,7 @@ function initEventHandler() {
* @param {Object} options * @param {Object} options
*/ */
function updateOptionsFromArguments(options) { function updateOptionsFromArguments(options) {
const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX); const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX); // @deprecated use data-monster-option-mapping-index
if (index !== null && index !== undefined) { if (index !== null && index !== undefined) {
options.mapping.index = parseInt(index, 10); options.mapping.index = parseInt(index, 10);
......
...@@ -30,21 +30,16 @@ const dataSourceSymbol = Symbol.for( ...@@ -30,21 +30,16 @@ const dataSourceSymbol = Symbol.for(
); );
/** /**
* The Datasource component is a basic class for the datatable component. * A datasource
* *
* <img src="./images/datasource.png"> * @fragments /fragments/components/datatable/datasource
* *
* Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library * @example /examples/components/datatable/datasource
* *
* @startuml datasource.png * @issue https://localhost.alvine.dev:8443/development/issues/closed/272.html
* skinparam monochrome true
* skinparam shadowing false
* HTMLElement <|-- CustomElement
* CustomElement <|-- Datasource
* @enduml
* *
* @copyright schukai GmbH * @copyright schukai GmbH
* @summary A abstract datasource * @summary A generic datasource
*/ */
class Datasource extends CustomElement { class Datasource extends CustomElement {
/** /**
...@@ -77,8 +72,7 @@ class Datasource extends CustomElement { ...@@ -77,8 +72,7 @@ class Datasource extends CustomElement {
} }
/** /**
* * @return {void}
* @return {Monster.Components.Form.Form}
*/ */
[assembleMethodSymbol]() { [assembleMethodSymbol]() {
super[assembleMethodSymbol](); super[assembleMethodSymbol]();
...@@ -93,7 +87,7 @@ class Datasource extends CustomElement { ...@@ -93,7 +87,7 @@ class Datasource extends CustomElement {
} }
/** /**
* set the data * set the data with proxy
* @param {Object} data * @param {Object} data
*/ */
set data(data) { set data(data) {
...@@ -101,18 +95,32 @@ class Datasource extends CustomElement { ...@@ -101,18 +95,32 @@ class Datasource extends CustomElement {
} }
/** /**
* Get the datasource * Get the base datasource
* @return {Monster.Data.Datasource} * @return {Datasource}
*/ */
get datasource() { get datasource() {
return this[dataSourceSymbol]; return this[dataSourceSymbol];
} }
/**
* Wrapper for the write method of the datasource
*/
write() { write() {
this[dataSourceSymbol].write(); this[dataSourceSymbol].write();
} }
/**
* Wrapper for the read method of the datasource
*/
read() { read() {
this[dataSourceSymbol].read(); this[dataSourceSymbol].read();
} }
/**
* @return {int}
* @throws {Error} this method must be implemented by derived classes.
*/
currentPage() {
throw new Error("this method must be implemented by derived classes");
}
} }
...@@ -53,6 +53,8 @@ class Dom extends Datasource { ...@@ -53,6 +53,8 @@ class Dom extends Datasource {
* *
* @property {Object} templates Template definitions * @property {Object} templates Template definitions
* @property {string} templates.main Main template * @property {string} templates.main Main template
* @property {Object} features Feature definitions
* @property {boolean} features.autoInit Automatically initializes the component
*/ */
get defaults() { get defaults() {
return Object.assign({}, super.defaults, { return Object.assign({}, super.defaults, {
...@@ -63,11 +65,19 @@ class Dom extends Datasource { ...@@ -63,11 +65,19 @@ class Dom extends Datasource {
features: { features: {
autoInit: true, autoInit: true,
}, },
/** @private */
sys: {
pagination: {
pages: 1,
objectsPerPage: 10,
currentPage: 1,
}
}
}); });
} }
/** /**
*
* @return {void} * @return {void}
*/ */
[assembleMethodSymbol]() { [assembleMethodSymbol]() {
...@@ -76,6 +86,17 @@ class Dom extends Datasource { ...@@ -76,6 +86,17 @@ class Dom extends Datasource {
updateDataSource.call(this); updateDataSource.call(this);
} }
/**
* This method set the current page of the pagination
*
* @param {string} page
* @return {Dom}
*/
setParameters({page}) {
this.setOption("sys.pagination.currentPage", page);
return this;
}
/** /**
* *
* @return {CSSStyleSheet[]} * @return {CSSStyleSheet[]}
...@@ -108,6 +129,13 @@ class Dom extends Datasource { ...@@ -108,6 +129,13 @@ class Dom extends Datasource {
updateDataSource.call(this); updateDataSource.call(this);
} }
} }
/**
* @return {int}
*/
currentPage() {
return this.getOption("sys.pagination.currentPage");
}
} }
/** /**
...@@ -170,7 +198,15 @@ function updateDataSource() { ...@@ -170,7 +198,15 @@ function updateDataSource() {
data = []; data = [];
} }
// set pagination
this.setOption("sys.pagination.objectsPerPage", 1 );
this.setOption("sys.pagination.pages", data.length);
this.setOption("sys.pagination.currentPage", 1);
/** call setter */
this.data = data; this.data = data;
} }
/** /**
......
...@@ -64,26 +64,19 @@ const intersectionObserverObserverSymbol = Symbol( ...@@ -64,26 +64,19 @@ const intersectionObserverObserverSymbol = Symbol(
const filterObserverSymbol = Symbol("filterObserver"); const filterObserverSymbol = Symbol("filterObserver");
/** /**
* The Datasource component is a basic class for the datatable component. * A rest api datasource
* *
* <img src="./images/rest.png"> * @fragments /fragments/components/datatable/datasource/rest
* *
* Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library * @example /examples/components/datatable/datasource-rest-simple
* @example /examples/components/datatable/datasource-rest-auto-init
* @example /examples/components/datatable/datasource-rest-do-fetch
* *
* @startuml rest.png * @issue https://localhost.alvine.dev:8443/development/issues/closed/272.html
* skinparam monochrome true
* skinparam shadowing false
* HTMLElement <|-- CustomElement
* CustomElement <|-- Datasource
* Datasource <|-- Rest
* @enduml
* *
* @copyright schukai GmbH * @copyright schukai GmbH
* @summary A rest api datasource * @summary A rest api datasource for the datatable or other components
*/ */
class Rest extends Datasource { class Rest extends Datasource {
/** /**
* the constructor of the class * the constructor of the class
...@@ -117,8 +110,6 @@ class Rest extends Datasource { ...@@ -117,8 +110,6 @@ class Rest extends Datasource {
* @property {boolean} autoInit.oneTime If true, the intersection observer is initialized only once * @property {boolean} autoInit.oneTime If true, the intersection observer is initialized only once
* @property {Object} filter Filter definitions * @property {Object} filter Filter definitions
* @property {string} filter.id The id of the filter control * @property {string} filter.id The id of the filter control
* @property {Object} datatable Datatable definitions
* @property {string} datatable.id The id of the datatable control
* @property {Object} response Response definitions * @property {Object} response Response definitions
* @property {Object} response.path Path definitions (changed in 3.56.0) * @property {Object} response.path Path definitions (changed in 3.56.0)
* @property {string} response.path.message Path to the message (changed in 3.56.0) * @property {string} response.path.message Path to the message (changed in 3.56.0)
...@@ -129,17 +120,23 @@ class Rest extends Datasource { ...@@ -129,17 +120,23 @@ class Rest extends Datasource {
* @property {Object} read.parameters.filter The filter of the rest api * @property {Object} read.parameters.filter The filter of the rest api
* @property {Object} read.parameters.orderBy The order by of the rest api * @property {Object} read.parameters.orderBy The order by of the rest api
* @property {Object} read.parameters.page The page of the rest api * @property {Object} read.parameters.page The page of the rest api
* @property {string} read.mapping.currentPage The current page
* @property {Object} write Write configuration
* @property {string} write.url The url of the rest api
* @property {string} write.method The method of the rest api
* @property {Object} write Write configuration * @property {Object} write Write configuration
*/ */
get defaults() { get defaults() {
const restOptions = new RestAPI().defaults; const restOptions = new RestAPI().defaults;
restOptions.read.parameters = { restOptions.read.parameters = {
filter: undefined, filter: null,
oderBy: undefined, oderBy: null,
page: "1", page: "1",
}; };
restOptions.read.mapping.currentPage = "sys.pagination.currentPage";
return Object.assign({}, super.defaults, restOptions, { return Object.assign({}, super.defaults, restOptions, {
templates: { templates: {
main: getTemplate(), main: getTemplate(),
...@@ -156,12 +153,12 @@ class Rest extends Datasource { ...@@ -156,12 +153,12 @@ class Rest extends Datasource {
}, },
filter: { filter: {
id: undefined, id: null,
}, },
datatable: { /*datatable: {
id: undefined, id: undefined, // not used?
}, }, */
response: { response: {
path: { path: {
...@@ -173,6 +170,8 @@ class Rest extends Datasource { ...@@ -173,6 +170,8 @@ class Rest extends Datasource {
} }
/** /**
* With this method, you can set the parameters for the rest api. The parameters are
* used for building the url.
* *
* @param {string} page * @param {string} page
* @param {string} query * @param {string} query
...@@ -194,67 +193,35 @@ class Rest extends Datasource { ...@@ -194,67 +193,35 @@ class Rest extends Datasource {
} }
/** /**
* @private
* @return {void} * @return {void}
*/ */
[assembleMethodSymbol]() { [assembleMethodSymbol]() {
super[assembleMethodSymbol](); super[assembleMethodSymbol]();
initEventHandler.call(this); initEventHandler.call(this);
initAutoInit.call(this); initAutoInit.call(this);
} }
/** /**
* This method reloads the data from the rest api, this method is deprecated.
* You should use the method `read` instead.
*
* @deprecated 2023-06-25 * @deprecated 2023-06-25
* @return {Promise<never>|*} * @return {Promise<never>|*}
*/ */
reload() { reload() {
return this.fetch(); return this.read();
} }
/** /**
* Fetches the data from the rest api * Fetches the data from the rest api, this method is deprecated.
* You should use the method `read` instead.
*
* @deprecated 2024-12-24
* @return {Promise<never>|*} * @return {Promise<never>|*}
*/ */
fetch() { fetch() {
const opt = clone(this.getOption("read")); return this.read();
this[dataSourceSymbol].setOption("read", opt);
let url = this.getOption("read.url");
const formatter = new Formatter(this.getOption("read.parameters"));
if (!url) {
return Promise.reject(new Error("No url defined"));
}
url = formatter.format(url);
this[dataSourceSymbol].setOption("read.url", url);
return new Promise((resolve, reject) => {
fireCustomEvent(this, "monster-datasource-fetch", {
datasource: this,
});
queueMicrotask(() => {
this[dataSourceSymbol]
.read()
.then((response) => {
fireCustomEvent(this, "monster-datasource-fetched", {
datasource: this,
});
resolve(response);
})
.catch((error) => {
fireCustomEvent(this, "monster-datasource-error", {
error: error,
});
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
reject(error);
});
});
});
} }
/** /**
...@@ -277,7 +244,7 @@ class Rest extends Datasource { ...@@ -277,7 +244,7 @@ class Rest extends Datasource {
* This method activates the intersection observer manually. * This method activates the intersection observer manually.
* For this purpose, the option `autoInit.intersectionObserver` must be set to `false`. * For this purpose, the option `autoInit.intersectionObserver` must be set to `false`.
* *
* @return {Monster.Components.Datatable.Datasource.Rest} * @return {Rest}
*/ */
initIntersectionObserver() { initIntersectionObserver() {
initIntersectionObserver.call(this); initIntersectionObserver.call(this);
...@@ -306,15 +273,59 @@ class Rest extends Datasource { ...@@ -306,15 +273,59 @@ class Rest extends Datasource {
} }
/** /**
* @return {Promise<never>|*} * This method reads the data from the rest api.
* The data is stored in the internal dataset object.
*
* @return {Promise}
* @fires monster-datasource-fetch
* @fires monster-datasource-fetched
* @fires monster-datasource-error
*/ */
read() { read() {
return this.fetch(); const opt = clone(this.getOption("read"));
this[dataSourceSymbol].setOption("read", opt);
let url = this.getOption("read.url");
const formatter = new Formatter(this.getOption("read.parameters"));
if (!url) {
return Promise.reject(new Error("No url defined"));
}
url = formatter.format(url);
this[dataSourceSymbol].setOption("read.url", url);
return new Promise((resolve, reject) => {
fireCustomEvent(this, "monster-datasource-fetch", {
datasource: this,
});
queueMicrotask(() => {
this[dataSourceSymbol]
.read()
.then((response) => {
fireCustomEvent(this, "monster-datasource-fetched", {
datasource: this,
});
resolve(response);
})
.catch((error) => {
fireCustomEvent(this, "monster-datasource-error", {
error: error,
});
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
reject(error);
});
});
});
} }
/** /**
* Fetches the data from the rest api * Fetches the data from the rest api.
* @return {Promise<never>|*} * @return {Promise}
*/ */
write() { write() {
const opt = clone(this.getOption("write")); const opt = clone(this.getOption("write"));
...@@ -357,6 +368,26 @@ class Rest extends Datasource { ...@@ -357,6 +368,26 @@ class Rest extends Datasource {
}); });
}); });
} }
// /**
// * @return {int}
// */
// currentPage() {
//
// const key = this.getOption("read.mapping.currentPage")
// if (key === undefined) {
// return 1;
// }
//
// const pf = new Pathfinder(this.data);
// if (pf.exists(key)) {
// return parseInt(pf.getVia(key), 10);
// }
//
// return 1;
//
// }
} }
/** /**
...@@ -501,7 +532,8 @@ function initAutoInit() { ...@@ -501,7 +532,8 @@ function initAutoInit() {
} }
queueMicrotask(() => { queueMicrotask(() => {
this.fetch().catch(() => {}); this.fetch().catch(() => {
});
}); });
} }
......
...@@ -42,10 +42,21 @@ class EmbeddedPagination extends Pagination { ...@@ -42,10 +42,21 @@ class EmbeddedPagination extends Pagination {
return Symbol.for("@schukai/monster/components/embedded-pagination"); return Symbol.for("@schukai/monster/components/embedded-pagination");
} }
/**
* @private
*/
[assembleMethodSymbol]() { [assembleMethodSymbol]() {
super[assembleMethodSymbol](); super[assembleMethodSymbol]();
} }
/**
*
* @property {Object} classes Class definitions
* @property {string} classes.spinner Spinner class
* @property {string} classes.spinnerContainer Spinner container class
* @property {string} classes.error Error class
* @property {string} classes.errorContainer Error container class
*/
get defaults() { get defaults() {
return Object.assign({}, super.defaults, { return Object.assign({}, super.defaults, {
classes: { classes: {
......
...@@ -71,7 +71,11 @@ const sizeDataSymbol = Symbol("sizeData"); ...@@ -71,7 +71,11 @@ const sizeDataSymbol = Symbol("sizeData");
const debounceSizeSymbol = Symbol("debounceSize"); const debounceSizeSymbol = Symbol("debounceSize");
/** /**
* The Pagination component * A Pagination component
*
* @fragments /fragments/components/datatable/pagination
*
* @example /examples/components/datatable/pagination-simple
* *
* @copyright schukai GmbH * @copyright schukai GmbH
* @summary The Pagination component is used to show the current page and the total number of pages. * @summary The Pagination component is used to show the current page and the total number of pages.
...@@ -116,7 +120,6 @@ class Pagination extends CustomElement { ...@@ -116,7 +120,6 @@ class Pagination extends CustomElement {
* @property {string} mapping.pages Pages mapping * @property {string} mapping.pages Pages mapping
* @property {string} mapping.objectsPerPage Objects per page mapping * @property {string} mapping.objectsPerPage Objects per page mapping
* @property {string} mapping.currentPage Current page mapping * @property {string} mapping.currentPage Current page mapping
* @property {Object} pagination Pagination
*/ */
get defaults() { get defaults() {
return Object.assign( return Object.assign(
...@@ -141,9 +144,9 @@ class Pagination extends CustomElement { ...@@ -141,9 +144,9 @@ class Pagination extends CustomElement {
href: "page-${page}", href: "page-${page}",
currentPage: undefined, pages: null,
pages: undefined,
objectsPerPage: 20, objectsPerPage: 20,
currentPage: null,
mapping: { mapping: {
pages: "sys.pagination.pages", pages: "sys.pagination.pages",
...@@ -151,6 +154,7 @@ class Pagination extends CustomElement { ...@@ -151,6 +154,7 @@ class Pagination extends CustomElement {
currentPage: "sys.pagination.currentPage", currentPage: "sys.pagination.currentPage",
}, },
/* @private */
pagination: { pagination: {
items: [], items: [],
}, },
...@@ -188,6 +192,13 @@ class Pagination extends CustomElement { ...@@ -188,6 +192,13 @@ class Pagination extends CustomElement {
return; return;
} }
try {
handleDataSourceChanges.call(this);
} catch (e) {
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e?.message || `${e}`);
}
requestAnimationFrame(() => {
const parentParentNode = parentNode?.parentNode || parentNode; const parentParentNode = parentNode?.parentNode || parentNode;
const parentWidth = parentParentNode.offsetWidth; const parentWidth = parentParentNode.offsetWidth;
...@@ -195,14 +206,11 @@ class Pagination extends CustomElement { ...@@ -195,14 +206,11 @@ class Pagination extends CustomElement {
this[sizeDataSymbol] = { this[sizeDataSymbol] = {
last: { last: {
parentWidth: parentParentNode.offsetWidth || 0, parentWidth: 0,
}, },
showNumbers: ownWidth < parentWidth, showNumbers: ownWidth < parentWidth,
}; };
handleDataSourceChanges.call(this);
setTimeout(() => {
this[resizeObserverSymbol] = new ResizeObserver((entries) => { this[resizeObserverSymbol] = new ResizeObserver((entries) => {
if (this[debounceSizeSymbol] instanceof DeadMansSwitch) { if (this[debounceSizeSymbol] instanceof DeadMansSwitch) {
try { try {
...@@ -226,14 +234,14 @@ class Pagination extends CustomElement { ...@@ -226,14 +234,14 @@ class Pagination extends CustomElement {
parentWidth: parentWidth, parentWidth: parentWidth,
}; };
this[sizeDataSymbol].showNumbers = ownWidth < parentWidth; this[sizeDataSymbol].showNumbers = ownWidth <= parentWidth;
handleDataSourceChanges.call(this); handleDataSourceChanges.call(this);
}); });
}); });
}); });
this[resizeObserverSymbol].observe(this?.parentNode?.parentNode); this[resizeObserverSymbol].observe(this?.parentNode?.parentNode);
}, 500); });
} }
/** /**
...@@ -262,6 +270,10 @@ class Pagination extends CustomElement { ...@@ -262,6 +270,10 @@ class Pagination extends CustomElement {
new Observer(handleDataSourceChanges.bind(this)), new Observer(handleDataSourceChanges.bind(this)),
); );
element.attachObserver(
new Observer(handleDataSourceChanges.bind(this)),
);
handleDataSourceChanges.call(this); handleDataSourceChanges.call(this);
} }
} }
...@@ -315,6 +327,7 @@ function initEventHandler() { ...@@ -315,6 +327,7 @@ function initEventHandler() {
ATTRIBUTE_ROLE, ATTRIBUTE_ROLE,
"pagination-item", "pagination-item",
); );
if (!element) { if (!element) {
element = findTargetElementFromEvent( element = findTargetElementFromEvent(
event, event,
...@@ -344,7 +357,6 @@ function initEventHandler() { ...@@ -344,7 +357,6 @@ function initEventHandler() {
} }
page = element.getAttribute("data-page-no"); page = element.getAttribute("data-page-no");
event.preventDefault();
if ( if (
!page || !page ||
...@@ -361,6 +373,7 @@ function initEventHandler() { ...@@ -361,6 +373,7 @@ function initEventHandler() {
return; return;
} }
event.preventDefault();
datasource.setParameters({page}); datasource.setParameters({page});
if (typeof datasource.reload !== "function") { if (typeof datasource.reload !== "function") {
...@@ -404,18 +417,23 @@ function handleDataSourceChanges() { ...@@ -404,18 +417,23 @@ function handleDataSourceChanges() {
} }
const mapping = this.getOption("mapping"); const mapping = this.getOption("mapping");
const pf = new Pathfinder(this[datasourceLinkedElementSymbol].data);
for (const key in mapping) { for (const key in mapping) {
const path = mapping[key]; const path = mapping[key];
let value; if (pf.exists(path)) {
try { const value = pf.getVia(
value = new Pathfinder(this[datasourceLinkedElementSymbol].data).getVia(
path, path,
); );
this.setOption(key, value); this.setOption(key, value);
} catch (e) {
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
} }
const o = this[datasourceLinkedElementSymbol].getOption(path);
if (o !== undefined && o !== null) {
this.setOption(key, o);
}
} }
pagination = buildPagination.call( pagination = buildPagination.call(
...@@ -440,6 +458,10 @@ function handleDataSourceChanges() { ...@@ -440,6 +458,10 @@ function handleDataSourceChanges() {
* @return {object} * @return {object}
*/ */
function buildPagination(current, max) { function buildPagination(current, max) {
current = parseInt(current, 10);
max = parseInt(max, 10);
let prev = current === 1 ? null : current - 1; let prev = current === 1 ? null : current - 1;
let next = current === max ? null : current + 1; let next = current === max ? null : current + 1;
const itemList = [1]; const itemList = [1];
......
...@@ -89,7 +89,7 @@ class DatasourceStatus extends CustomElement { ...@@ -89,7 +89,7 @@ class DatasourceStatus extends CustomElement {
*/ */
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for( return Symbol.for(
"@schukai/monster/components/datatables/status@@instance", "@schukai/monster/components/datatable/status@@instance",
); );
} }
......
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
& ul li a { & ul li a {
@mixin button; @mixin button;
background-color: var(--monster-theme-control-bg-color); background-color: var(--monster-bg-color-primary-1);
color: var(--monster-theme-control-color); color: var(--monster-theme-control-color);
border-color: var(--monster-theme-control-bg-color); border-color: var(--monster-bg-color-primary-1);
width: max-content; width: max-content;
&.current { &.current {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
export { PaginationStyleSheet }; export {PaginationStyleSheet}
/** /**
* @private * @private
...@@ -22,17 +22,10 @@ export { PaginationStyleSheet }; ...@@ -22,17 +22,10 @@ export { PaginationStyleSheet };
const PaginationStyleSheet = new CSSStyleSheet(); const PaginationStyleSheet = new CSSStyleSheet();
try { try {
PaginationStyleSheet.insertRule( PaginationStyleSheet.insertRule(`
`
@layer pagination { @layer pagination {
:where(html){line-height:1.15;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}:where(h1){font-size:2em;margin-block-end:.67em;margin-block-start:.67em}:where(dl,ol,ul) :where(dl,ol,ul){margin-block-end:0;margin-block-start:0}:where(hr){box-sizing:content-box;color:inherit;height:0}:where(abbr[title]){text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}:where(b,strong){font-weight:bolder}:where(code,kbd,pre,samp){font-family:monospace,monospace;font-size:1em}:where(small){font-size:80%}:where(table){border-color:currentColor;text-indent:0}:where(button,input,select){margin:0}:where(button){text-transform:none}:where(button,input:is([type=button i],[type=reset i],[type=submit i])){-webkit-appearance:button}:where(progress){vertical-align:baseline}:where(select){text-transform:none}:where(textarea){margin:0}:where(input[type=search i]){-webkit-appearance:textfield;outline-offset:-2px}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}:where(button,input:is([type=button i],[type=color i],[type=reset i],[type=submit i]))::-moz-focus-inner{border-style:none;padding:0}:where(button,input:is([type=button i],[type=color i],[type=reset i],[type=submit i]))::-moz-focusring{outline:1px dotted ButtonText}:where(:-moz-ui-invalid){box-shadow:none}:where(dialog){background-color:#fff;border:solid;color:#000;height:-moz-fit-content;height:fit-content;left:0;margin:auto;padding:1em;position:absolute;right:0;width:-moz-fit-content;width:fit-content}:where(dialog:not([open])){display:none}:where(summary){display:list-item}html{height:100%}body,html{min-height:calc(100vh - 40px)}body{box-sizing:border-box;margin:0;padding:0;word-break:break-word}.block{display:block}.inline{display:inline}.inline-block{display:inline-block}.grid{display:grid}.inline-grid{display:inline-grid}.flex{display:flex}.inline-flex{display:inline-flex}.hidden,.hide,.none{display:none}.visible{visibility:visible}.invisible{visibility:hidden}.monster-button-primary,button{align-items:center;background-color:var(--monster-bg-color-primary-1);background-position:50%;border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);color:var(--monster-color-primary-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-primary{background-color:var(--monster-bg-color-primary-4);border-color:var(--monster-bg-color-primary-4);color:var(--monster-color-primary-4)}.monster-button-secondary{background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-bg-color-secondary-4);border-color:var(--monster-bg-color-secondary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-primary-1);color:var(--monster-color-secondary-4)}.monster-button-secondary,.monster-button-tertiary{align-items:center;background-position:50%;box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-tertiary{background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-bg-color-tertiary-4);border-color:var(--monster-bg-color-tertiary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-primary-1);color:var(--monster-color-tertiary-4)}.monster-button-outline-primary{background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-color-primary-4);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-primary-1);color:var(--monster-bg-color-primary-4)}.monster-button-outline-primary,.monster-button-outline-secondary{align-items:center;background-position:50%;box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-outline-secondary{background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-color-secondary-4);border-color:var(--monster-bg-color-secondary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-primary-1);color:var(--monster-bg-color-secondary-4)}.monster-button-outline-tertiary{align-items:center;background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-color-tertiary-4);background-position:50%;border-color:var(--monster-bg-color-tertiary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);color:var(--monster-color-primary-1);color:var(--monster-bg-color-tertiary-4);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}button:active,button:hover{box-shadow:var(--monster-box-shadow-2);transition:background .8s,color .25s .0833333333s}button:active{z-index:var(--monster-z-index-outline)}.monster-button-bar,.monster-button-group{align-content:center;align-items:stretch;display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-between}.monster-button-group{box-sizing:border-box;gap:0;margin:1rem 0}.monster-button-group>:not(:last-child){margin-right:calc(var(--monster-border-width)*-1)}.monster-button-group :hover{box-shadow:none}button:focus{outline:1px dashed var(--monster-color-selection-4);outline-offset:2px;z-index:var(--monster-z-index-outline)}@media (prefers-color-scheme:light){button:focus{outline:1px dashed var(--monster-color-selection-3);outline-offset:2px;z-index:var(--monster-z-index-outline)}}[data-monster-role=control]{box-sizing:border-box;outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}:after,:before,:root{--monster-font-family:-apple-system,BlinkMacSystemFont,\"Quicksand\",\"Segoe UI\",\"Roboto\",\"Oxygen\",\"Ubuntu\",\"Cantarell\",\"Fira Sans\",\"Droid Sans\",\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";--monster-font-family-monospace:\"Consolas\",\"Courier New\",\"Roboto Mono\",\"Source Code Pro\",\"Fira Mono\",monospace;--monster-color-primary-1:var(--monster-color-gray-6);--monster-color-primary-2:var(--monster-color-gray-6);--monster-color-primary-3:var(--monster-color-cinnamon-1);--monster-color-primary-4:var(--monster-color-cinnamon-1);--monster-bg-color-primary-1:var(--monster-color-gray-1);--monster-bg-color-primary-2:var(--monster-color-gray-2);--monster-bg-color-primary-3:var(--monster-color-gray-6);--monster-bg-color-primary-4:var(--monster-color-gray-4)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-primary-1:var(--monster-color-gray-1);--monster-color-primary-2:var(--monster-color-gray-1);--monster-color-primary-3:var(--monster-color-gray-6);--monster-color-primary-4:var(--monster-color-gray-6);--monster-bg-color-primary-1:var(--monster-color-gray-6);--monster-bg-color-primary-2:var(--monster-color-gray-3);--monster-bg-color-primary-3:var(--monster-color-gray-2);--monster-bg-color-primary-4:var(--monster-color-gray-1)}}:after,:before,:root{--monster-color-secondary-1:var(--monster-color-red-4);--monster-color-secondary-2:var(--monster-color-red-4);--monster-color-secondary-3:var(--monster-color-red-1);--monster-color-secondary-4:var(--monster-color-red-1);--monster-bg-color-secondary-1:var(--monster-color-gray-1);--monster-bg-color-secondary-2:var(--monster-color-red-2);--monster-bg-color-secondary-3:var(--monster-color-red-3);--monster-bg-color-secondary-4:var(--monster-color-red-6)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-secondary-1:var(--monster-color-red-1);--monster-color-secondary-2:var(--monster-color-red-1);--monster-color-secondary-3:var(--monster-color-red-6);--monster-color-secondary-4:var(--monster-color-red-4);--monster-bg-color-secondary-1:var(--monster-color-gray-6);--monster-bg-color-secondary-2:var(--monster-color-red-3);--monster-bg-color-secondary-3:var(--monster-color-red-2);--monster-bg-color-secondary-4:var(--monster-color-red-1)}}:after,:before,:root{--monster-color-tertiary-1:var(--monster-color-magenta-4);--monster-color-tertiary-2:var(--monster-color-magenta-4);--monster-color-tertiary-3:var(--monster-color-magenta-6);--monster-color-tertiary-4:var(--monster-color-magenta-1);--monster-bg-color-tertiary-1:var(--monster-color-gray-1);--monster-bg-color-tertiary-2:var(--monster-color-magenta-1);--monster-bg-color-tertiary-3:var(--monster-color-magenta-2);--monster-bg-color-tertiary-4:var(--monster-color-magenta-6)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-tertiary-1:var(--monster-color-magenta-1);--monster-color-tertiary-2:var(--monster-color-magenta-6);--monster-color-tertiary-3:var(--monster-color-magenta-4);--monster-color-tertiary-4:var(--monster-color-magenta-4);--monster-bg-color-tertiary-1:var(--monster-color-gray-6);--monster-bg-color-tertiary-2:var(--monster-color-magenta-2);--monster-bg-color-tertiary-3:var(--monster-color-magenta-1);--monster-bg-color-tertiary-4:var(--monster-color-magenta-1)}}:after,:before,:root{--monster-color-destructive-1:var(--monster-color-red-1);--monster-color-destructive-2:var(--monster-color-red-4);--monster-color-destructive-3:var(--monster-color-red-6);--monster-color-destructive-4:var(--monster-color-red-1);--monster-bg-color-destructive-1:var(--monster-color-red-4);--monster-bg-color-destructive-2:var(--monster-color-gray-1);--monster-bg-color-destructive-3:var(--monster-color-red-2);--monster-bg-color-destructive-4:var(--monster-color-red-5)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-destructive-1:var(--monster-color-red-1);--monster-color-destructive-2:var(--monster-color-red-3);--monster-color-destructive-3:var(--monster-color-red-4);--monster-color-destructive-4:var(--monster-color-red-1);--monster-bg-color-destructive-1:var(--monster-color-red-5);--monster-bg-color-destructive-2:var(--monster-color-gray-6);--monster-bg-color-destructive-3:var(--monster-color-red-1);--monster-bg-color-destructive-4:var(--monster-color-red-4)}}:after,:before,:root{--monster-color-success-1:var(--monster-color-green-1);--monster-color-success-2:var(--monster-color-green-4);--monster-color-success-3:var(--monster-color-green-6);--monster-color-success-4:var(--monster-color-green-1);--monster-bg-color-success-1:var(--monster-color-green-3);--monster-bg-color-success-2:var(--monster-color-gray-1);--monster-bg-color-success-3:var(--monster-color-green-2);--monster-bg-color-success-4:var(--monster-color-green-5)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-success-1:var(--monster-color-green-1);--monster-color-success-2:var(--monster-color-green-2);--monster-color-success-3:var(--monster-color-green-4);--monster-color-success-4:var(--monster-color-green-1);--monster-bg-color-success-1:var(--monster-color-green-5);--monster-bg-color-success-2:var(--monster-color-gray-6);--monster-bg-color-success-3:var(--monster-color-green-1);--monster-bg-color-success-4:var(--monster-color-green-3)}}:after,:before,:root{--monster-color-warning-1:var(--monster-color-orange-1);--monster-color-warning-2:var(--monster-color-orange-4);--monster-color-warning-3:var(--monster-color-orange-6);--monster-color-warning-4:var(--monster-color-orange-1);--monster-bg-color-warning-1:var(--monster-color-orange-3);--monster-bg-color-warning-2:var(--monster-color-gray-1);--monster-bg-color-warning-3:var(--monster-color-orange-2);--monster-bg-color-warning-4:var(--monster-color-orange-5)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-warning-1:var(--monster-color-orange-1);--monster-color-warning-2:var(--monster-color-orange-3);--monster-color-warning-3:var(--monster-color-orange-4);--monster-color-warning-4:var(--monster-color-orange-1);--monster-bg-color-warning-1:var(--monster-color-orange-5);--monster-bg-color-warning-2:var(--monster-color-gray-6);--monster-bg-color-warning-3:var(--monster-color-orange-1);--monster-bg-color-warning-4:var(--monster-color-orange-3)}}:after,:before,:root{--monster-color-error-1:var(--monster-color-red-1);--monster-color-error-2:var(--monster-color-red-4);--monster-color-error-3:var(--monster-color-red-6);--monster-color-error-4:var(--monster-color-red-1);--monster-bg-color-error-1:var(--monster-color-red-4);--monster-bg-color-error-2:var(--monster-color-gray-1);--monster-bg-color-error-3:var(--monster-color-red-2);--monster-bg-color-error-4:var(--monster-color-red-5)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-error-1:var(--monster-color-red-1);--monster-color-error-2:var(--monster-color-red-3);--monster-color-error-3:var(--monster-color-red-4);--monster-color-error-4:var(--monster-color-red-1);--monster-bg-color-error-1:var(--monster-color-red-5);--monster-bg-color-error-2:var(--monster-color-gray-6);--monster-bg-color-error-3:var(--monster-color-red-1);--monster-bg-color-error-4:var(--monster-color-red-4)}}:after,:before,:root{--monster-color-selection-1:var(--monster-color-gray-6);--monster-color-selection-2:var(--monster-color-gray-6);--monster-color-selection-3:var(--monster-color-gray-6);--monster-color-selection-4:var(--monster-color-gray-1);--monster-bg-color-selection-1:var(--monster-color-yellow-2);--monster-bg-color-selection-2:var(--monster-color-yellow-1);--monster-bg-color-selection-3:var(--monster-color-yellow-2);--monster-bg-color-selection-4:var(--monster-color-yellow-6)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-selection-1:var(--monster-color-gray-6);--monster-color-selection-2:var(--monster-color-gray-6);--monster-color-selection-3:var(--monster-color-gray-6);--monster-color-selection-4:var(--monster-color-gray-1);--monster-bg-color-selection-1:var(--monster-color-yellow-2);--monster-bg-color-selection-2:var(--monster-color-yellow-1);--monster-bg-color-selection-3:var(--monster-color-yellow-2);--monster-bg-color-selection-4:var(--monster-color-yellow-6)}}:after,:before,:root{--monster-color-primary-disabled-1:var(--monster-color-gray-4);--monster-color-primary-disabled-2:var(--monster-color-gray-4);--monster-color-primary-disabled-3:var(--monster-color-gray-4);--monster-color-primary-disabled-4:var(--monster-color-gray-4);--monster-bg-color-primary-disabled-1:var(--monster-color-gray-1);--monster-bg-color-primary-disabled-2:var(--monster-color-gray-2);--monster-bg-color-primary-disabled-3:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-4:var(--monster-color-gray-6)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-primary-disabled-1:var(--monster-color-gray-4);--monster-color-primary-disabled-2:var(--monster-color-gray-4);--monster-color-primary-disabled-3:var(--monster-color-gray-3);--monster-color-primary-disabled-4:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-1:var(--monster-color-gray-6);--monster-bg-color-primary-disabled-2:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-3:var(--monster-color-gray-2);--monster-bg-color-primary-disabled-4:var(--monster-color-gray-1)}}:after,:before,:root{--monster-color-gradient-1:#833ab4;--monster-color-gradient-2:#fd1d1d;--monster-color-gradient-3:#fcb045;--monster-box-shadow-1:none;--monster-box-shadow-2:-1px 1px 10px 1px hsla(0,0%,76%,.61);--monster-text-shadow:none;--monster-theme-control-bg-color:var(--monster-color-seashell-1);--monster-theme-control-color:var(--monster-color-seashell-6);--monster-theme-control-hover-color:var(--monster-color-seashell-6);--monster-theme-control-hover-bg-color:var(--monster-color-seashell-2);--monster-theme-control-border-width:2px;--monster-theme-control-border-style:solid;--monster-theme-control-border-radius:0;--monster-theme-control-border-color:var(--monster-color-primary-1)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-theme-control-bg-color:var(--monster-color-gray-5);--monster-theme-control-color:var(--monster-color-gray-1);--monster-theme-control-border-color:var(--monster-color-gray-3);--monster-theme-control-hover-color:var(--monster-color-gray-1);--monster-theme-control-hover-bg-color:var(--monster-color-gray-6)}}:after,:before,:root{--monster-theme-on-color:var(--monster-color-green-1);--monster-theme-on-bg-color:var(--monster-color-green-5);--monster-theme-off-color:var(--monster-color-gray-1);--monster-theme-off-bg-color:var(--monster-color-gray-4)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-theme-on-color:var(--monster-color-gray-6);--monster-theme-on-bg-color:var(--monster-color-gray-1);--monster-theme-off-color:var(--monster-color-gray-1);--monster-theme-off-bg-color:var(--monster-color-gray-5)}}:after,:before,:root{--monster-border-style:solid;--monster-border-width:3px;--monster-border-radius:0;--monster-popper-witharrrow-distance:-4px;--monster-z-index-default:0;--monster-z-index-outline:10;--monster-z-index-dropdown:200;--monster-z-index-dropdown-overlay:210;--monster-z-index-sticky:300;--monster-z-index-sticky-overlay:310;--monster-z-index-fixed:400;--monster-z-index-fixed-overlay:410;--monster-z-index-modal-backdrop:500;--monster-z-index-modal-backdrop-overlay:510;--monster-z-index-offcanvas:600;--monster-z-index-offcanvas-overlay:610;--monster-z-index-modal:700;--monster-z-index-modal-overlay:710;--monster-z-index-popover:800;--monster-z-index-popover-overlay:810;--monster-z-index-tooltip:800;--monster-z-index-tooltip-overlay:910;--monster-space-0:0;--monster-space-1:2px;--monster-space-2:4px;--monster-space-3:6px;--monster-space-4:10px;--monster-space-5:16px;--monster-space-6:26px;--monster-space-7:42px;--monster-breakpoint-0:480px;--monster-breakpoint-4:480px;--monster-breakpoint-7:768px;--monster-breakpoint-9:992px;--monster-breakpoint-12:1200px;--monster-dragger-width:2px;--monster-dragger-handle-width:4px;--monster-dragger-handle-height:50px}span.monster-fx-ripple{animation:monster-fx-ripple .6s linear;background-color:hsla(0,0%,100%,.7);border-radius:50%;position:absolute;transform:scale(0)}@keyframes monster-fx-ripple{to{opacity:0;transform:scale(4)}}[data-monster-role=pagination]{box-sizing:border-box;display:flex;font-size:1rem;font-weight:400;justify-content:center;line-height:1.6}[data-monster-role=pagination] ul{align-items:center;display:flex;flex-wrap:wrap;justify-content:center;list-style:none;margin:20px 0;padding-left:0}[data-monster-role=pagination] ul li{margin:0 1px}[data-monster-role=pagination] ul li a{align-items:center;background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-theme-control-bg-color);background-position:50%;border-color:var(--monster-theme-control-bg-color);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);color:var(--monster-color-primary-1);color:var(--monster-theme-control-color);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch;width:-moz-max-content;width:max-content}.current:is([data-monster-role=pagination] ul li a){background-color:var(--monster-bg-color-primary-4);border-color:var(--monster-bg-color-primary-4);color:var(--monster-color-primary-4);cursor:unset}.disabled:is([data-monster-role=pagination] ul li a){background-color:var(--monster-bg-color-primary-disabled-1);color:var(--monster-color-primary-disabled-1);cursor:not-allowed} :where(html){line-height:1.15;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}:where(h1){font-size:2em;margin-block-end:.67em;margin-block-start:.67em}:where(dl,ol,ul) :where(dl,ol,ul){margin-block-end:0;margin-block-start:0}:where(hr){box-sizing:content-box;color:inherit;height:0}:where(abbr[title]){text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}:where(b,strong){font-weight:bolder}:where(code,kbd,pre,samp){font-family:monospace,monospace;font-size:1em}:where(small){font-size:80%}:where(table){border-color:currentColor;text-indent:0}:where(button,input,select){margin:0}:where(button){text-transform:none}:where(button,input:is([type=button i],[type=reset i],[type=submit i])){-webkit-appearance:button}:where(progress){vertical-align:baseline}:where(select){text-transform:none}:where(textarea){margin:0}:where(input[type=search i]){-webkit-appearance:textfield;outline-offset:-2px}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}:where(button,input:is([type=button i],[type=color i],[type=reset i],[type=submit i]))::-moz-focus-inner{border-style:none;padding:0}:where(button,input:is([type=button i],[type=color i],[type=reset i],[type=submit i]))::-moz-focusring{outline:1px dotted ButtonText}:where(:-moz-ui-invalid){box-shadow:none}:where(dialog){background-color:#fff;border:solid;color:#000;height:-moz-fit-content;height:fit-content;left:0;margin:auto;padding:1em;position:absolute;right:0;width:-moz-fit-content;width:fit-content}:where(dialog:not([open])){display:none}:where(summary){display:list-item}html{height:100%}body,html{min-height:calc(100vh - 40px)}body{box-sizing:border-box;margin:0;padding:0;word-break:break-word}body:focus-visible{outline:none}:focus-visible{outline:none}.block{display:block}.inline{display:inline}.inline-block{display:inline-block}.grid{display:grid}.inline-grid{display:inline-grid}.flex{display:flex}.inline-flex{display:inline-flex}.hidden,.hide,.none{display:none}.visible{visibility:visible}.invisible{visibility:hidden}.monster-button-primary,button{align-items:center;background-color:var(--monster-bg-color-primary-1);background-position:50%;border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);color:var(--monster-color-primary-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-primary{background-color:var(--monster-bg-color-primary-4);border-color:var(--monster-bg-color-primary-4);color:var(--monster-color-primary-4)}.monster-button-secondary{background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-bg-color-secondary-4);border-color:var(--monster-bg-color-secondary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-primary-1);color:var(--monster-color-secondary-4)}.monster-button-secondary,.monster-button-tertiary{align-items:center;background-position:50%;box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-tertiary{background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-bg-color-tertiary-4);border-color:var(--monster-bg-color-tertiary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-primary-1);color:var(--monster-color-tertiary-4)}.monster-button-outline-primary{background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-color-primary-4);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-primary-1);color:var(--monster-bg-color-primary-4)}.monster-button-outline-primary,.monster-button-outline-secondary{align-items:center;background-position:50%;box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-outline-secondary{background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-color-secondary-4);border-color:var(--monster-bg-color-secondary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-primary-1);color:var(--monster-bg-color-secondary-4)}.monster-button-outline-tertiary{align-items:center;background-color:var(--monster-bg-color-primary-1);background-color:var(--monster-color-tertiary-4);background-position:50%;border-color:var(--monster-bg-color-tertiary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);color:var(--monster-color-primary-1);color:var(--monster-bg-color-tertiary-4);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}button:active,button:hover{box-shadow:var(--monster-box-shadow-2);transition:background .8s,color .25s .0833333333s}button:active{z-index:var(--monster-z-index-outline)}.monster-button-bar,.monster-button-group{align-content:center;align-items:stretch;display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-between}.monster-button-group{box-sizing:border-box;gap:0;margin:1rem 0}.monster-button-group>:not(:last-child){margin-right:calc(var(--monster-border-width)*-1)}.monster-button-group :hover{box-shadow:none}button:focus{outline:1px dashed var(--monster-color-selection-4);outline-offset:2px;z-index:var(--monster-z-index-outline)}@media (prefers-color-scheme:light){button:focus{outline:1px dashed var(--monster-color-selection-3);outline-offset:2px;z-index:var(--monster-z-index-outline)}}[data-monster-role=control]{box-sizing:border-box;outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}:after,:before,:root{--monster-font-family:-apple-system,BlinkMacSystemFont,\"Quicksand\",\"Segoe UI\",\"Roboto\",\"Oxygen\",\"Ubuntu\",\"Cantarell\",\"Fira Sans\",\"Droid Sans\",\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";--monster-font-family-monospace:\"Consolas\",\"Courier New\",\"Roboto Mono\",\"Source Code Pro\",\"Fira Mono\",monospace;--monster-color-primary-1:var(--monster-color-gray-6);--monster-color-primary-2:var(--monster-color-gray-6);--monster-color-primary-3:var(--monster-color-cinnamon-1);--monster-color-primary-4:var(--monster-color-cinnamon-1);--monster-bg-color-primary-1:var(--monster-color-gray-1);--monster-bg-color-primary-2:var(--monster-color-gray-2);--monster-bg-color-primary-3:var(--monster-color-gray-6);--monster-bg-color-primary-4:var(--monster-color-gray-4)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-primary-1:var(--monster-color-gray-1);--monster-color-primary-2:var(--monster-color-gray-1);--monster-color-primary-3:var(--monster-color-gray-6);--monster-color-primary-4:var(--monster-color-gray-6);--monster-bg-color-primary-1:var(--monster-color-gray-6);--monster-bg-color-primary-2:var(--monster-color-gray-3);--monster-bg-color-primary-3:var(--monster-color-gray-2);--monster-bg-color-primary-4:var(--monster-color-gray-1)}}:after,:before,:root{--monster-color-secondary-1:var(--monster-color-red-4);--monster-color-secondary-2:var(--monster-color-red-4);--monster-color-secondary-3:var(--monster-color-red-1);--monster-color-secondary-4:var(--monster-color-red-1);--monster-bg-color-secondary-1:var(--monster-color-gray-1);--monster-bg-color-secondary-2:var(--monster-color-red-2);--monster-bg-color-secondary-3:var(--monster-color-red-3);--monster-bg-color-secondary-4:var(--monster-color-red-6)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-secondary-1:var(--monster-color-red-1);--monster-color-secondary-2:var(--monster-color-red-1);--monster-color-secondary-3:var(--monster-color-red-6);--monster-color-secondary-4:var(--monster-color-red-4);--monster-bg-color-secondary-1:var(--monster-color-gray-6);--monster-bg-color-secondary-2:var(--monster-color-red-3);--monster-bg-color-secondary-3:var(--monster-color-red-2);--monster-bg-color-secondary-4:var(--monster-color-red-1)}}:after,:before,:root{--monster-color-tertiary-1:var(--monster-color-magenta-4);--monster-color-tertiary-2:var(--monster-color-magenta-4);--monster-color-tertiary-3:var(--monster-color-magenta-6);--monster-color-tertiary-4:var(--monster-color-magenta-1);--monster-bg-color-tertiary-1:var(--monster-color-gray-1);--monster-bg-color-tertiary-2:var(--monster-color-magenta-1);--monster-bg-color-tertiary-3:var(--monster-color-magenta-2);--monster-bg-color-tertiary-4:var(--monster-color-magenta-6)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-tertiary-1:var(--monster-color-magenta-1);--monster-color-tertiary-2:var(--monster-color-magenta-6);--monster-color-tertiary-3:var(--monster-color-magenta-4);--monster-color-tertiary-4:var(--monster-color-magenta-4);--monster-bg-color-tertiary-1:var(--monster-color-gray-6);--monster-bg-color-tertiary-2:var(--monster-color-magenta-2);--monster-bg-color-tertiary-3:var(--monster-color-magenta-1);--monster-bg-color-tertiary-4:var(--monster-color-magenta-1)}}:after,:before,:root{--monster-color-destructive-1:var(--monster-color-red-1);--monster-color-destructive-2:var(--monster-color-red-4);--monster-color-destructive-3:var(--monster-color-red-6);--monster-color-destructive-4:var(--monster-color-red-1);--monster-bg-color-destructive-1:var(--monster-color-red-4);--monster-bg-color-destructive-2:var(--monster-color-gray-1);--monster-bg-color-destructive-3:var(--monster-color-red-2);--monster-bg-color-destructive-4:var(--monster-color-red-5)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-destructive-1:var(--monster-color-red-1);--monster-color-destructive-2:var(--monster-color-red-3);--monster-color-destructive-3:var(--monster-color-red-4);--monster-color-destructive-4:var(--monster-color-red-1);--monster-bg-color-destructive-1:var(--monster-color-red-5);--monster-bg-color-destructive-2:var(--monster-color-gray-6);--monster-bg-color-destructive-3:var(--monster-color-red-1);--monster-bg-color-destructive-4:var(--monster-color-red-4)}}:after,:before,:root{--monster-color-success-1:var(--monster-color-green-1);--monster-color-success-2:var(--monster-color-green-4);--monster-color-success-3:var(--monster-color-green-6);--monster-color-success-4:var(--monster-color-green-1);--monster-bg-color-success-1:var(--monster-color-green-3);--monster-bg-color-success-2:var(--monster-color-gray-1);--monster-bg-color-success-3:var(--monster-color-green-2);--monster-bg-color-success-4:var(--monster-color-green-5)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-success-1:var(--monster-color-green-1);--monster-color-success-2:var(--monster-color-green-2);--monster-color-success-3:var(--monster-color-green-4);--monster-color-success-4:var(--monster-color-green-1);--monster-bg-color-success-1:var(--monster-color-green-5);--monster-bg-color-success-2:var(--monster-color-gray-6);--monster-bg-color-success-3:var(--monster-color-green-1);--monster-bg-color-success-4:var(--monster-color-green-3)}}:after,:before,:root{--monster-color-warning-1:var(--monster-color-orange-1);--monster-color-warning-2:var(--monster-color-orange-4);--monster-color-warning-3:var(--monster-color-orange-6);--monster-color-warning-4:var(--monster-color-orange-1);--monster-bg-color-warning-1:var(--monster-color-orange-3);--monster-bg-color-warning-2:var(--monster-color-gray-1);--monster-bg-color-warning-3:var(--monster-color-orange-2);--monster-bg-color-warning-4:var(--monster-color-orange-5)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-warning-1:var(--monster-color-orange-1);--monster-color-warning-2:var(--monster-color-orange-3);--monster-color-warning-3:var(--monster-color-orange-4);--monster-color-warning-4:var(--monster-color-orange-1);--monster-bg-color-warning-1:var(--monster-color-orange-5);--monster-bg-color-warning-2:var(--monster-color-gray-6);--monster-bg-color-warning-3:var(--monster-color-orange-1);--monster-bg-color-warning-4:var(--monster-color-orange-3)}}:after,:before,:root{--monster-color-error-1:var(--monster-color-red-1);--monster-color-error-2:var(--monster-color-red-4);--monster-color-error-3:var(--monster-color-red-6);--monster-color-error-4:var(--monster-color-red-1);--monster-bg-color-error-1:var(--monster-color-red-4);--monster-bg-color-error-2:var(--monster-color-gray-1);--monster-bg-color-error-3:var(--monster-color-red-2);--monster-bg-color-error-4:var(--monster-color-red-5)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-error-1:var(--monster-color-red-1);--monster-color-error-2:var(--monster-color-red-3);--monster-color-error-3:var(--monster-color-red-4);--monster-color-error-4:var(--monster-color-red-1);--monster-bg-color-error-1:var(--monster-color-red-5);--monster-bg-color-error-2:var(--monster-color-gray-6);--monster-bg-color-error-3:var(--monster-color-red-1);--monster-bg-color-error-4:var(--monster-color-red-4)}}:after,:before,:root{--monster-color-selection-1:var(--monster-color-gray-6);--monster-color-selection-2:var(--monster-color-gray-6);--monster-color-selection-3:var(--monster-color-gray-6);--monster-color-selection-4:var(--monster-color-gray-1);--monster-bg-color-selection-1:var(--monster-color-yellow-2);--monster-bg-color-selection-2:var(--monster-color-yellow-1);--monster-bg-color-selection-3:var(--monster-color-yellow-2);--monster-bg-color-selection-4:var(--monster-color-yellow-6)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-selection-1:var(--monster-color-gray-6);--monster-color-selection-2:var(--monster-color-gray-6);--monster-color-selection-3:var(--monster-color-gray-6);--monster-color-selection-4:var(--monster-color-gray-1);--monster-bg-color-selection-1:var(--monster-color-yellow-2);--monster-bg-color-selection-2:var(--monster-color-yellow-1);--monster-bg-color-selection-3:var(--monster-color-yellow-2);--monster-bg-color-selection-4:var(--monster-color-yellow-6)}}:after,:before,:root{--monster-color-primary-disabled-1:var(--monster-color-gray-4);--monster-color-primary-disabled-2:var(--monster-color-gray-4);--monster-color-primary-disabled-3:var(--monster-color-gray-4);--monster-color-primary-disabled-4:var(--monster-color-gray-4);--monster-bg-color-primary-disabled-1:var(--monster-color-gray-1);--monster-bg-color-primary-disabled-2:var(--monster-color-gray-2);--monster-bg-color-primary-disabled-3:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-4:var(--monster-color-gray-6)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-primary-disabled-1:var(--monster-color-gray-4);--monster-color-primary-disabled-2:var(--monster-color-gray-4);--monster-color-primary-disabled-3:var(--monster-color-gray-3);--monster-color-primary-disabled-4:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-1:var(--monster-color-gray-6);--monster-bg-color-primary-disabled-2:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-3:var(--monster-color-gray-2);--monster-bg-color-primary-disabled-4:var(--monster-color-gray-1)}}:after,:before,:root{--monster-color-gradient-1:#833ab4;--monster-color-gradient-2:#fd1d1d;--monster-color-gradient-3:#fcb045;--monster-box-shadow-1:none;--monster-box-shadow-2:-1px 1px 10px 1px hsla(0,0%,76%,.61);--monster-text-shadow:none;--monster-theme-control-bg-color:var(--monster-color-seashell-1);--monster-theme-control-color:var(--monster-color-seashell-6);--monster-theme-control-hover-color:var(--monster-color-seashell-6);--monster-theme-control-hover-bg-color:var(--monster-color-seashell-2);--monster-theme-control-border-width:2px;--monster-theme-control-border-style:solid;--monster-theme-control-border-radius:0;--monster-theme-control-border-color:var(--monster-color-primary-1)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-theme-control-bg-color:var(--monster-color-gray-5);--monster-theme-control-color:var(--monster-color-gray-1);--monster-theme-control-border-color:var(--monster-color-gray-3);--monster-theme-control-hover-color:var(--monster-color-gray-1);--monster-theme-control-hover-bg-color:var(--monster-color-gray-6)}}:after,:before,:root{--monster-theme-on-color:var(--monster-color-green-1);--monster-theme-on-bg-color:var(--monster-color-green-5);--monster-theme-off-color:var(--monster-color-gray-1);--monster-theme-off-bg-color:var(--monster-color-gray-4)}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-theme-on-color:var(--monster-color-gray-6);--monster-theme-on-bg-color:var(--monster-color-gray-1);--monster-theme-off-color:var(--monster-color-gray-1);--monster-theme-off-bg-color:var(--monster-color-gray-5)}}:after,:before,:root{--monster-border-style:solid;--monster-border-width:3px;--monster-border-radius:0;--monster-outline-width:1px;--monster-popper-witharrrow-distance:-4px;--monster-z-index-default:0;--monster-z-index-outline:10;--monster-z-index-dropdown:200;--monster-z-index-dropdown-overlay:210;--monster-z-index-sticky:300;--monster-z-index-sticky-overlay:310;--monster-z-index-fixed:400;--monster-z-index-fixed-overlay:410;--monster-z-index-modal-backdrop:500;--monster-z-index-modal-backdrop-overlay:510;--monster-z-index-offcanvas:600;--monster-z-index-offcanvas-overlay:610;--monster-z-index-modal:700;--monster-z-index-modal-overlay:710;--monster-z-index-popover:800;--monster-z-index-popover-overlay:810;--monster-z-index-tooltip:800;--monster-z-index-tooltip-overlay:910;--monster-space-0:0;--monster-space-1:2px;--monster-space-2:4px;--monster-space-3:6px;--monster-space-4:10px;--monster-space-5:16px;--monster-space-6:26px;--monster-space-7:42px;--monster-breakpoint-0:480px;--monster-breakpoint-4:480px;--monster-breakpoint-7:768px;--monster-breakpoint-9:992px;--monster-breakpoint-12:1200px;--monster-dragger-width:2px;--monster-dragger-handle-width:4px;--monster-dragger-handle-height:50px}span.monster-fx-ripple{animation:monster-fx-ripple .6s linear;background-color:hsla(0,0%,100%,.7);border-radius:50%;position:absolute;transform:scale(0)}@keyframes monster-fx-ripple{to{opacity:0;transform:scale(4)}}[data-monster-role=pagination]{box-sizing:border-box;display:flex;font-size:1rem;font-weight:400;justify-content:center;line-height:1.6}[data-monster-role=pagination] ul{align-items:center;display:flex;flex-wrap:wrap;justify-content:center;list-style:none;margin:20px 0;padding-left:0}[data-monster-role=pagination] ul li{margin:0 1px}[data-monster-role=pagination] ul li a{align-items:center;background-color:var(--monster-bg-color-primary-1);background-position:50%;border-color:var(--monster-bg-color-primary-1);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);color:var(--monster-color-primary-1);color:var(--monster-theme-control-color);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch;width:-moz-max-content;width:max-content}.current:is([data-monster-role=pagination] ul li a){background-color:var(--monster-bg-color-primary-4);border-color:var(--monster-bg-color-primary-4);color:var(--monster-color-primary-4);cursor:unset}.disabled:is([data-monster-role=pagination] ul li a){background-color:var(--monster-bg-color-primary-disabled-1);color:var(--monster-color-primary-disabled-1);cursor:not-allowed}
}`, }`, 0);
0,
);
} catch (e) { } catch (e) {
addAttributeToken( addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
document.getRootNode().querySelector("html"),
ATTRIBUTE_ERRORMESSAGE,
e + "",
);
} }
...@@ -29,6 +29,7 @@ const datasourceLinkedElementSymbol = Symbol("datasourceLinkedElement"); ...@@ -29,6 +29,7 @@ const datasourceLinkedElementSymbol = Symbol("datasourceLinkedElement");
* @private * @private
*/ */
function handleDataSourceChanges() { function handleDataSourceChanges() {
if (!this[datasourceLinkedElementSymbol]) { if (!this[datasourceLinkedElementSymbol]) {
return; return;
} }
......
...@@ -238,12 +238,10 @@ function clearObjectStore() { ...@@ -238,12 +238,10 @@ function clearObjectStore() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const req = store.clear(); const req = store.clear();
req.onsuccess = function (evt) { req.onsuccess = function (evt) {
console.log("clearObjectStore completed");
resolve(); resolve();
}; };
req.onerror = function (evt) { req.onerror = function (evt) {
console.error("clearObjectStore:", evt.target.errorCode); reject(evt.target?.errorCode);
reject(evt.target.errorCode);
}; };
}); });
} }
......
...@@ -125,6 +125,7 @@ function doDiff(obj) { ...@@ -125,6 +125,7 @@ function doDiff(obj) {
*/ */
function doTransform(type, obj) { function doTransform(type, obj) {
const transformation = this.getOption(`${type}.mapping.transformer`); const transformation = this.getOption(`${type}.mapping.transformer`);
if (transformation !== undefined && transformation !== null) { if (transformation !== undefined && transformation !== null) {
const pipe = new Pipe(transformation); const pipe = new Pipe(transformation);
const callbacks = this.getOption(`${type}.mapping.callbacks`); const callbacks = this.getOption(`${type}.mapping.callbacks`);
......
...@@ -18,6 +18,7 @@ import { diff } from "../../diff.mjs"; ...@@ -18,6 +18,7 @@ import { diff } from "../../diff.mjs";
import { Server } from "../server.mjs"; import { Server } from "../server.mjs";
import { WriteError } from "./restapi/writeerror.mjs"; import { WriteError } from "./restapi/writeerror.mjs";
import { DataFetchError } from "./restapi/data-fetch-error.mjs"; import { DataFetchError } from "./restapi/data-fetch-error.mjs";
import {clone} from "../../../util/clone.mjs";
export { RestAPI }; export { RestAPI };
...@@ -63,7 +64,7 @@ class RestAPI extends Server { ...@@ -63,7 +64,7 @@ class RestAPI extends Server {
/** /**
* @property {Object} write={} Options * @property {Object} write={} Options
* @property {Object} write.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor} * @property {Object} write.init={} An option object, containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor}
* @property {string} write.init.method=POST * @property {string} write.init.method=POST
* @property {Object} write.init.headers Object containing any custom headers that you want to apply to the request. * @property {Object} write.init.headers Object containing any custom headers that you want to apply to the request.
* @property {string} write.responseCallback Callback function to be executed after the request has been completed. * @property {string} write.responseCallback Callback function to be executed after the request has been completed.
...@@ -71,7 +72,7 @@ class RestAPI extends Server { ...@@ -71,7 +72,7 @@ class RestAPI extends Server {
* @property {string} write.url URL * @property {string} write.url URL
* @property {Object} write.mapping the mapping is applied before writing. * @property {Object} write.mapping the mapping is applied before writing.
* @property {String} write.mapping.transformer Transformer to select the appropriate entries * @property {String} write.mapping.transformer Transformer to select the appropriate entries
* @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing. * @property {exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing.
* @property {Object} write.report * @property {Object} write.report
* @property {String} write.report.path Path to validations * @property {String} write.report.path Path to validations
* @property {Object} write.partial * @property {Object} write.partial
...@@ -80,13 +81,13 @@ class RestAPI extends Server { ...@@ -80,13 +81,13 @@ class RestAPI extends Server {
* @property {Object} write.sheathing.object Object to be wrapped * @property {Object} write.sheathing.object Object to be wrapped
* @property {string} write.sheathing.path Path to the data * @property {string} write.sheathing.path Path to the data
* @property {Object} read={} Options * @property {Object} read={} Options
* @property {Object} read.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor} * @property {Object} read.init={} An option object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor}
* @property {string} read.init.method=GET * @property {string} read.init.method=GET
* @property {string} read.acceptedStatus=[200] * @property {array} read.acceptedStatus=[200]
* @property {string} read.url URL * @property {string} read.url URL
* @property {Object} read.mapping the mapping is applied after reading. * @property {Object} read.mapping the mapping is applied after reading.
* @property {String} read.mapping.transformer Transformer to select the appropriate entries * @property {String} read.mapping.transformer Transformer to select the appropriate entries
* @property {Monster.Data.Datasource~exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading. * @property {exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading.
*/ */
get defaults() { get defaults() {
return Object.assign({}, super.defaults, { return Object.assign({}, super.defaults, {
...@@ -94,19 +95,19 @@ class RestAPI extends Server { ...@@ -94,19 +95,19 @@ class RestAPI extends Server {
init: { init: {
method: "POST", method: "POST",
}, },
responseCallback: undefined, responseCallback: null,
acceptedStatus: [200, 201], acceptedStatus: [200, 201],
url: null, url: null,
mapping: { mapping: {
transformer: undefined, transformer: null,
callbacks: [], callbacks: [],
}, },
sheathing: { sheathing: {
object: undefined, object: null,
path: undefined, path: null,
}, },
report: { report: {
path: undefined, path: null,
}, },
partial: { partial: {
...@@ -118,11 +119,11 @@ class RestAPI extends Server { ...@@ -118,11 +119,11 @@ class RestAPI extends Server {
method: "GET", method: "GET",
}, },
path: null, path: null,
responseCallback: undefined, responseCallback: null,
acceptedStatus: [200], acceptedStatus: [200],
url: null, url: null,
mapping: { mapping: {
transformer: undefined, transformer: null,
callbacks: [], callbacks: [],
}, },
}, },
...@@ -175,10 +176,16 @@ class RestAPI extends Server { ...@@ -175,10 +176,16 @@ class RestAPI extends Server {
* @return {RestAPI} * @return {RestAPI}
*/ */
getClone() { getClone() {
return new RestAPI( const api = new RestAPI();
this[internalSymbol].getRealSubject()["options"].read,
this[internalSymbol].getRealSubject()["options"].write, const read = clone(this[internalSymbol].getRealSubject()["options"].read);
); const write = clone(this[internalSymbol].getRealSubject()["options"].write);
api.setOption("read", read);
api.setOption("write", write);
return api;
} }
} }
......
...@@ -219,6 +219,40 @@ class CustomElement extends HTMLElement { ...@@ -219,6 +219,40 @@ class CustomElement extends HTMLElement {
return Symbol.for("@schukai/monster/dom/custom-element@@instance"); return Symbol.for("@schukai/monster/dom/custom-element@@instance");
} }
// /**
// * This method is called by the `instanceof` operator.
// *
// * @param instance
// * @returns {arg is any[]}
// */
// static [Symbol.hasInstance](instance) {
// if (!isObject(instance)) {
// return false;
// }
// debugger
// const instanceSym = instance?.[instanceSymbol];
// if (instanceSym === undefined) {
// return false;
// }
//
// // Direktes Matching des Symbols
// if (instanceSym === this[instanceSymbol]) {
// return true;
// }
//
// // Prüfe den Prototypenbaum des Objekts für eine Übereinstimmung
// let proto = Object.getPrototypeOf(instance);
// while (proto) {
// const protoSymbol = proto.constructor?.[instanceSymbol];
// if (protoSymbol === this[instanceSymbol]) {
// return true;
// }
// proto = Object.getPrototypeOf(proto); // Gehe weiter den Prototypenbaum entlang
// }
//
// return false;
// }
/** /**
* This method determines which attributes are to be * This method determines which attributes are to be
* monitored by `attributeChangedCallback()`. Unfortunately, this method is static. * monitored by `attributeChangedCallback()`. Unfortunately, this method is static.
......
/**
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*
* SPDX-License-Identifier: AGPL-3.0
*/
export {
hasImplementation
};
/**
* With this function, you can check if a value is iterable.
*
* @param object
* @param methods
* @returns {boolean}
*/
function hasImplementation(object, methods) {
return methods.every(method => typeof object[method] === 'function');
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment