@schukai/monster 3.99.4 → 3.99.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,46 +12,46 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
- import {instanceSymbol} from "../../constants.mjs";
15
+ import { instanceSymbol } from "../../constants.mjs";
16
16
  import {
17
- findTargetElementFromEvent,
18
- fireCustomEvent,
17
+ findTargetElementFromEvent,
18
+ fireCustomEvent,
19
19
  } from "../../dom/events.mjs";
20
20
  import {
21
- findElementWithIdUpwards,
22
- findElementWithSelectorUpwards,
21
+ findElementWithIdUpwards,
22
+ findElementWithSelectorUpwards,
23
23
  } from "../../dom/util.mjs";
24
24
  import {
25
- assembleMethodSymbol,
26
- CustomElement,
27
- getSlottedElements,
28
- registerCustomElement,
25
+ assembleMethodSymbol,
26
+ CustomElement,
27
+ getSlottedElements,
28
+ registerCustomElement,
29
29
  } from "../../dom/customelement.mjs";
30
- import {ID} from "../../types/id.mjs";
31
- import {Settings} from "./filter/settings.mjs";
32
- import {FilterStyleSheet} from "./stylesheet/filter.mjs";
33
- import {getDocument, getWindow} from "../../dom/util.mjs";
34
- import {getGlobal} from "../../types/global.mjs";
35
- import {isInstance, isFunction, isObject, isArray} from "../../types/is.mjs";
36
- import {Host} from "../host/host.mjs";
37
- import {addAttributeToken} from "../../dom/attributes.mjs";
38
- import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
30
+ import { ID } from "../../types/id.mjs";
31
+ import { Settings } from "./filter/settings.mjs";
32
+ import { FilterStyleSheet } from "./stylesheet/filter.mjs";
33
+ import { getDocument, getWindow } from "../../dom/util.mjs";
34
+ import { getGlobal } from "../../types/global.mjs";
35
+ import { isInstance, isFunction, isObject, isArray } from "../../types/is.mjs";
36
+ import { Host } from "../host/host.mjs";
37
+ import { addAttributeToken } from "../../dom/attributes.mjs";
38
+ import { ATTRIBUTE_ERRORMESSAGE } from "../../dom/constants.mjs";
39
39
  import "../form/message-state-button.mjs";
40
- import {Formatter} from "../../text/formatter.mjs";
41
- import {generateRangeComparisonExpression} from "../../text/util.mjs";
40
+ import { Formatter } from "../../text/formatter.mjs";
41
+ import { generateRangeComparisonExpression } from "../../text/util.mjs";
42
42
 
43
43
  import {
44
- parseBracketedKeyValueHash,
45
- createBracketedKeyValueHash,
44
+ parseBracketedKeyValueHash,
45
+ createBracketedKeyValueHash,
46
46
  } from "../../text/bracketed-key-value-hash.mjs";
47
- import {ThemeStyleSheet} from "../stylesheet/theme.mjs";
48
- import {SpaceStyleSheet} from "../stylesheet/space.mjs";
49
- import {FormStyleSheet} from "../stylesheet/form.mjs";
47
+ import { ThemeStyleSheet } from "../stylesheet/theme.mjs";
48
+ import { SpaceStyleSheet } from "../stylesheet/space.mjs";
49
+ import { FormStyleSheet } from "../stylesheet/form.mjs";
50
50
 
51
51
  import {
52
- getStoredFilterConfigKey,
53
- getFilterConfigKey,
54
- parseDateInput,
52
+ getStoredFilterConfigKey,
53
+ getFilterConfigKey,
54
+ parseDateInput,
55
55
  } from "./filter/util.mjs";
56
56
 
57
57
  import "./filter/select.mjs";
@@ -64,9 +64,9 @@ import "../form/context-help.mjs";
64
64
  import "../form/context-error.mjs";
65
65
  import "../form/message-state-button.mjs";
66
66
 
67
- import {getLocaleOfDocument} from "../../dom/locale.mjs";
67
+ import { getLocaleOfDocument } from "../../dom/locale.mjs";
68
68
 
69
- export {Filter};
69
+ export { Filter };
70
70
 
71
71
  /**
72
72
  * @private
@@ -103,7 +103,7 @@ const filterControlElementSymbol = Symbol("filterControlElement");
103
103
  * @type {symbol}
104
104
  */
105
105
  const filterSaveActionButtonElementSymbol = Symbol(
106
- "filterSaveActionButtonElement",
106
+ "filterSaveActionButtonElement",
107
107
  );
108
108
 
109
109
  /**
@@ -163,226 +163,224 @@ const hashChangeSymbol = Symbol("hashChange");
163
163
  * @summary The Filter component is used to show and handle the filter values.
164
164
  */
165
165
  class Filter extends CustomElement {
166
- /**
167
- *
168
- */
169
- constructor() {
170
- super();
171
- this[settingsSymbol] = new Settings();
172
-
173
- // debounce the hash change event if doSearch is called by click the search button
174
- this[hashChangeSymbol] = 0;
175
- }
176
-
177
- /**
178
- * This method is called by the `instanceof` operator.
179
- * @return {symbol}
180
- */
181
- static get [instanceSymbol]() {
182
- return Symbol.for("@schukai/monster/components/filter@@instance");
183
- }
184
-
185
- /**
186
- *
187
- * @param {string} message
188
- * @return {Filter}
189
- */
190
- showFailureMessage(message) {
191
- this[searchButtonElementSymbol].setState(
192
- "failed",
193
- this.getOption("timeouts.message", 4000),
194
- );
195
- this[searchButtonElementSymbol]
196
- .setMessage(message.toString())
197
- .showMessage(this.getOption("timeouts.message", 4000));
198
- return this;
199
- }
200
-
201
- /**
202
- *
203
- * @return {Filter}
204
- */
205
- resetFailureMessage() {
206
- this[searchButtonElementSymbol].hideMessage();
207
- this[searchButtonElementSymbol].removeState();
208
- return this;
209
- }
210
-
211
- /**
212
- *
213
- * @return {Filter}
214
- */
215
- showSuccess() {
216
- this[searchButtonElementSymbol].setState(
217
- "successful",
218
- this.getOption("timeouts.message", 4000),
219
- );
220
- return this;
221
- }
222
-
223
- /**
224
- * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
225
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
226
- *
227
- * The individual configuration values can be found in the table.
228
- *
229
- * @property {Object} templates Template definitions
230
- * @property {string} templates.main Main template
231
- * @property {Object} labels Label definitions
232
- * @property {string} labels.search Search button label
233
- * @property {string} labels.reset Reset button label
234
- * @property {string} labels.save Save button label
235
- * @property {string} labels.filter-name Filter name label
236
- * @property {string} labels.empty-query-and-no-default Empty query and no default query label
237
- * @property {string} labels.query-not-changed Query not changed label
238
- * @property {Object} formatter Formatter definitions
239
- * @property {Object} formatter.marker Marker definitions
240
- * @property {Object} formatter.marker.open Marker open
241
- * @property {Object} formatter.marker.close Marker close
242
- * @property {Object} features Feature definitions
243
- * @property {boolean} features.storedConfig Stored configuration, this replaces the setting `storedConfig.enabled` @since 3.97.0
244
- * @property {Object} storedConfig Stored configuration
245
- * @property {boolean} storedConfig.enabled The store has been enabled, this option will no longer have any effect. @deprecated 20250101
246
- * @property {string} storedConfig.selector Selector
247
- * @property {Object} timeouts Timeout definitions
248
- * @property {number} timeouts.message Message timeout
249
- * @property {Object} queries Query definitions
250
- * @property {Function} queries.wrap Wrap callback
251
- * @property {Function} queries.join Join callback
252
- * @property {string} query Query
253
- * @property {string} defaultQuery Default query
254
- * @property {boolean} eventProcessing Event processing
255
- */
256
- get defaults() {
257
- return Object.assign({}, super.defaults, {
258
- templates: {
259
- main: getTemplate(),
260
- },
261
-
262
- formatter: {
263
- marker: {
264
- open: null,
265
- close: null,
266
- },
267
- },
268
-
269
- labels: getTranslations(),
270
-
271
- templateMapping: {
272
- "filter-save-label": null,
273
- "filter-name-label": name,
274
- },
275
-
276
- features: {
277
- storedConfig: false,
278
- },
279
-
280
- storedConfig: {
281
- enabled: true,
282
- selector: "",
283
- },
284
-
285
- timeouts: {
286
- message: 4000,
287
- },
288
-
289
- queries: {
290
- wrap: (value, definition) => {
291
- return value;
292
- },
293
- join: (queries) => {
294
- if (queries.length === 0) {
295
- return "";
296
- }
297
- return queries.join(" AND ");
298
- },
299
- },
300
-
301
- query: null,
302
- defaultQuery: null,
303
- eventProcessing: true,
304
- });
305
- }
306
-
307
- /**
308
- *
309
- * @return {string}
310
- */
311
- static getTag() {
312
- return "monster-datatable-filter";
313
- }
314
-
315
- /**
316
- * @return {FilterButton}
317
- * @fires monster-filter-initialized
318
- */
319
- [assembleMethodSymbol]() {
320
- this.setOption(
321
- "templateMapping.filter-save-label",
322
- this.getOption("labels.save"),
323
- );
324
-
325
- this.setOption(
326
- "templateMapping.filter-name-label",
327
- this.getOption("labels.filter-name"),
328
- );
329
-
330
- super[assembleMethodSymbol]();
331
-
332
- initControlReferences.call(this);
333
- getWindow().requestAnimationFrame(() => {
334
- initEventHandler.call(this);
335
- });
336
-
337
- initFromConfig
338
- .call(this)
339
- .then(() => {
340
- })
341
- .catch((error) => {
342
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error?.message);
343
- })
344
- .finally(() => {
345
- initFilter.call(this);
346
- updateFilterTabs.call(this);
347
- doSearch
348
- .call(this, {showEffect: false})
349
- .then(() => {
350
- fireCustomEvent(this, "monster-filter-initialized");
351
- })
352
- .catch(() => {
353
- });
354
- });
355
- }
356
-
357
- /**
358
- *
359
- */
360
- connectedCallback() {
361
- super.connectedCallback();
362
- getWindow().addEventListener(
363
- "hashchange",
364
- this[locationChangeHandlerSymbol],
365
- );
366
- }
367
-
368
- /**
369
- *
370
- */
371
- disconnectedCallback() {
372
- super.disconnectedCallback();
373
-
374
- getWindow().removeEventListener(
375
- "hashchange",
376
- this[locationChangeHandlerSymbol],
377
- );
378
- }
379
-
380
- /**
381
- * @return {Array<CSSStyleSheet>}
382
- */
383
- static getCSSStyleSheet() {
384
- return [FilterStyleSheet, FormStyleSheet, ThemeStyleSheet, SpaceStyleSheet];
385
- }
166
+ /**
167
+ *
168
+ */
169
+ constructor() {
170
+ super();
171
+ this[settingsSymbol] = new Settings();
172
+
173
+ // debounce the hash change event if doSearch is called by click the search button
174
+ this[hashChangeSymbol] = 0;
175
+ }
176
+
177
+ /**
178
+ * This method is called by the `instanceof` operator.
179
+ * @return {symbol}
180
+ */
181
+ static get [instanceSymbol]() {
182
+ return Symbol.for("@schukai/monster/components/filter@@instance");
183
+ }
184
+
185
+ /**
186
+ *
187
+ * @param {string} message
188
+ * @return {Filter}
189
+ */
190
+ showFailureMessage(message) {
191
+ this[searchButtonElementSymbol].setState(
192
+ "failed",
193
+ this.getOption("timeouts.message", 4000),
194
+ );
195
+ this[searchButtonElementSymbol]
196
+ .setMessage(message.toString())
197
+ .showMessage(this.getOption("timeouts.message", 4000));
198
+ return this;
199
+ }
200
+
201
+ /**
202
+ *
203
+ * @return {Filter}
204
+ */
205
+ resetFailureMessage() {
206
+ this[searchButtonElementSymbol].hideMessage();
207
+ this[searchButtonElementSymbol].removeState();
208
+ return this;
209
+ }
210
+
211
+ /**
212
+ *
213
+ * @return {Filter}
214
+ */
215
+ showSuccess() {
216
+ this[searchButtonElementSymbol].setState(
217
+ "successful",
218
+ this.getOption("timeouts.message", 4000),
219
+ );
220
+ return this;
221
+ }
222
+
223
+ /**
224
+ * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
225
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
226
+ *
227
+ * The individual configuration values can be found in the table.
228
+ *
229
+ * @property {Object} templates Template definitions
230
+ * @property {string} templates.main Main template
231
+ * @property {Object} labels Label definitions
232
+ * @property {string} labels.search Search button label
233
+ * @property {string} labels.reset Reset button label
234
+ * @property {string} labels.save Save button label
235
+ * @property {string} labels.filter-name Filter name label
236
+ * @property {string} labels.empty-query-and-no-default Empty query and no default query label
237
+ * @property {string} labels.query-not-changed Query not changed label
238
+ * @property {Object} formatter Formatter definitions
239
+ * @property {Object} formatter.marker Marker definitions
240
+ * @property {Object} formatter.marker.open Marker open
241
+ * @property {Object} formatter.marker.close Marker close
242
+ * @property {Object} features Feature definitions
243
+ * @property {boolean} features.storedConfig Stored configuration, this replaces the setting `storedConfig.enabled` @since 3.97.0
244
+ * @property {Object} storedConfig Stored configuration
245
+ * @property {boolean} storedConfig.enabled The store has been enabled, this option will no longer have any effect. @deprecated 20250101
246
+ * @property {string} storedConfig.selector Selector
247
+ * @property {Object} timeouts Timeout definitions
248
+ * @property {number} timeouts.message Message timeout
249
+ * @property {Object} queries Query definitions
250
+ * @property {Function} queries.wrap Wrap callback
251
+ * @property {Function} queries.join Join callback
252
+ * @property {string} query Query
253
+ * @property {string} defaultQuery Default query
254
+ * @property {boolean} eventProcessing Event processing
255
+ */
256
+ get defaults() {
257
+ return Object.assign({}, super.defaults, {
258
+ templates: {
259
+ main: getTemplate(),
260
+ },
261
+
262
+ formatter: {
263
+ marker: {
264
+ open: null,
265
+ close: null,
266
+ },
267
+ },
268
+
269
+ labels: getTranslations(),
270
+
271
+ templateMapping: {
272
+ "filter-save-label": null,
273
+ "filter-name-label": name,
274
+ },
275
+
276
+ features: {
277
+ storedConfig: false,
278
+ },
279
+
280
+ storedConfig: {
281
+ enabled: true,
282
+ selector: "",
283
+ },
284
+
285
+ timeouts: {
286
+ message: 4000,
287
+ },
288
+
289
+ queries: {
290
+ wrap: (value, definition) => {
291
+ return value;
292
+ },
293
+ join: (queries) => {
294
+ if (queries.length === 0) {
295
+ return "";
296
+ }
297
+ return queries.join(" AND ");
298
+ },
299
+ },
300
+
301
+ query: null,
302
+ defaultQuery: null,
303
+ eventProcessing: true,
304
+ });
305
+ }
306
+
307
+ /**
308
+ *
309
+ * @return {string}
310
+ */
311
+ static getTag() {
312
+ return "monster-datatable-filter";
313
+ }
314
+
315
+ /**
316
+ * @return {FilterButton}
317
+ * @fires monster-filter-initialized
318
+ */
319
+ [assembleMethodSymbol]() {
320
+ this.setOption(
321
+ "templateMapping.filter-save-label",
322
+ this.getOption("labels.save"),
323
+ );
324
+
325
+ this.setOption(
326
+ "templateMapping.filter-name-label",
327
+ this.getOption("labels.filter-name"),
328
+ );
329
+
330
+ super[assembleMethodSymbol]();
331
+
332
+ initControlReferences.call(this);
333
+ getWindow().requestAnimationFrame(() => {
334
+ initEventHandler.call(this);
335
+ });
336
+
337
+ initFromConfig
338
+ .call(this)
339
+ .then(() => {})
340
+ .catch((error) => {
341
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error?.message);
342
+ })
343
+ .finally(() => {
344
+ initFilter.call(this);
345
+ updateFilterTabs.call(this);
346
+ doSearch
347
+ .call(this, { showEffect: false })
348
+ .then(() => {
349
+ fireCustomEvent(this, "monster-filter-initialized");
350
+ })
351
+ .catch(() => {});
352
+ });
353
+ }
354
+
355
+ /**
356
+ *
357
+ */
358
+ connectedCallback() {
359
+ super.connectedCallback();
360
+ getWindow().addEventListener(
361
+ "hashchange",
362
+ this[locationChangeHandlerSymbol],
363
+ );
364
+ }
365
+
366
+ /**
367
+ *
368
+ */
369
+ disconnectedCallback() {
370
+ super.disconnectedCallback();
371
+
372
+ getWindow().removeEventListener(
373
+ "hashchange",
374
+ this[locationChangeHandlerSymbol],
375
+ );
376
+ }
377
+
378
+ /**
379
+ * @return {Array<CSSStyleSheet>}
380
+ */
381
+ static getCSSStyleSheet() {
382
+ return [FilterStyleSheet, FormStyleSheet, ThemeStyleSheet, SpaceStyleSheet];
383
+ }
386
384
  }
387
385
 
388
386
  /**
@@ -390,109 +388,109 @@ class Filter extends CustomElement {
390
388
  * @returns {object}
391
389
  */
392
390
  function getTranslations() {
393
- const locale = getLocaleOfDocument();
394
- switch (locale.language) {
395
- case "de":
396
- return {
397
- search: "Suchen",
398
- reset: "Zurücksetzen",
399
- save: "Speichern",
400
- "filter-name": "Filtername",
401
- "empty-query-and-no-default":
402
- "Die Abfrage ist leer und es gibt keine Standardabfrage.",
403
- "query-not-changed":
404
- "Die Suchanfrage hat sich nicht verändert, daher ist keine Suche erforderlich.",
405
- };
406
- case "fr":
407
- return {
408
- search: "Chercher",
409
- reset: "Réinitialiser",
410
- save: "Sauvegarder",
411
- "filter-name": "Nom du filtre",
412
- "empty-query-and-no-default":
413
- "La requête est vide et il n'y a pas de requête par défaut.",
414
- "query-not-changed":
415
- "La requête de recherche n'a pas changé, donc aucune recherche n'est nécessaire.",
416
- };
417
- case "sp":
418
- return {
419
- search: "Buscar",
420
- reset: "Restablecer",
421
- save: "Guardar",
422
- "filter-name": "Nombre del filtro",
423
- "empty-query-and-no-default":
424
- "La consulta está vacía y no hay una consulta predeterminada.",
425
- "query-not-changed":
426
- "La solicitud de búsqueda no ha cambiado, por lo que no se requiere búsqueda.",
427
- };
428
- case "it":
429
- return {
430
- search: "Cerca",
431
- reset: "Reimposta",
432
- save: "Salva",
433
- "filter-name": "Nome del filtro",
434
- "empty-query-and-no-default":
435
- "La query è vuota e non c'è una query predefinita.",
436
- "query-not-changed":
437
- "La richiesta di ricerca non è cambiata, quindi non è necessaria una ricerca.",
438
- };
439
- case "pl":
440
- return {
441
- search: "Szukaj",
442
- reset: "Resetuj",
443
- save: "Zapisz",
444
- "filter-name": "Nazwa filtra",
445
- "empty-query-and-no-default":
446
- "Zapytanie jest puste i nie ma domyślnego zapytania.",
447
- "query-not-changed":
448
- "Żądanie wyszukiwania nie zmieniło się, więc wyszukiwanie nie jest wymagane.",
449
- };
450
- case "no":
451
- return {
452
- search: "Søk",
453
- reset: "Tilbakestill",
454
- save: "Lagre",
455
- "filter-name": "Filternavn",
456
- "empty-query-and-no-default":
457
- "Spørringen er tom og det er ingen standardspørring.",
458
- "query-not-changed":
459
- "Søkeforespørselen har ikke endret seg, så ingen søk er nødvendig.",
460
- };
461
- case "dk":
462
- return {
463
- search: "Søg",
464
- reset: "Nulstil",
465
- save: "Gem",
466
- "filter-name": "Filternavn",
467
- "empty-query-and-no-default":
468
- "Forespørgslen er tom og der er ingen standardforespørgsel.",
469
- "query-not-changed":
470
- "Søgeanmodningen er ikke ændret, så ingen søgning er nødvendig.",
471
- };
472
- case "sw":
473
- return {
474
- search: "Sök",
475
- reset: "Återställ",
476
- save: "Spara",
477
- "filter-name": "Filternamn",
478
- "empty-query-and-no-default":
479
- "Förfrågan är tom och det finns ingen standardförfrågan.",
480
- "query-not-changed":
481
- "Sökförfrågan har inte ändrats, så ingen sökning krävs.",
482
- };
483
- default:
484
- case "en":
485
- return {
486
- search: "Search",
487
- reset: "Reset",
488
- save: "Save",
489
- "filter-name": "Filter name",
490
- "empty-query-and-no-default":
491
- "The query is empty and there is no default query.",
492
- "query-not-changed":
493
- "The search request has not changed, so no search is required.",
494
- };
495
- }
391
+ const locale = getLocaleOfDocument();
392
+ switch (locale.language) {
393
+ case "de":
394
+ return {
395
+ search: "Suchen",
396
+ reset: "Zurücksetzen",
397
+ save: "Speichern",
398
+ "filter-name": "Filtername",
399
+ "empty-query-and-no-default":
400
+ "Die Abfrage ist leer und es gibt keine Standardabfrage.",
401
+ "query-not-changed":
402
+ "Die Suchanfrage hat sich nicht verändert, daher ist keine Suche erforderlich.",
403
+ };
404
+ case "fr":
405
+ return {
406
+ search: "Chercher",
407
+ reset: "Réinitialiser",
408
+ save: "Sauvegarder",
409
+ "filter-name": "Nom du filtre",
410
+ "empty-query-and-no-default":
411
+ "La requête est vide et il n'y a pas de requête par défaut.",
412
+ "query-not-changed":
413
+ "La requête de recherche n'a pas changé, donc aucune recherche n'est nécessaire.",
414
+ };
415
+ case "sp":
416
+ return {
417
+ search: "Buscar",
418
+ reset: "Restablecer",
419
+ save: "Guardar",
420
+ "filter-name": "Nombre del filtro",
421
+ "empty-query-and-no-default":
422
+ "La consulta está vacía y no hay una consulta predeterminada.",
423
+ "query-not-changed":
424
+ "La solicitud de búsqueda no ha cambiado, por lo que no se requiere búsqueda.",
425
+ };
426
+ case "it":
427
+ return {
428
+ search: "Cerca",
429
+ reset: "Reimposta",
430
+ save: "Salva",
431
+ "filter-name": "Nome del filtro",
432
+ "empty-query-and-no-default":
433
+ "La query è vuota e non c'è una query predefinita.",
434
+ "query-not-changed":
435
+ "La richiesta di ricerca non è cambiata, quindi non è necessaria una ricerca.",
436
+ };
437
+ case "pl":
438
+ return {
439
+ search: "Szukaj",
440
+ reset: "Resetuj",
441
+ save: "Zapisz",
442
+ "filter-name": "Nazwa filtra",
443
+ "empty-query-and-no-default":
444
+ "Zapytanie jest puste i nie ma domyślnego zapytania.",
445
+ "query-not-changed":
446
+ "Żądanie wyszukiwania nie zmieniło się, więc wyszukiwanie nie jest wymagane.",
447
+ };
448
+ case "no":
449
+ return {
450
+ search: "Søk",
451
+ reset: "Tilbakestill",
452
+ save: "Lagre",
453
+ "filter-name": "Filternavn",
454
+ "empty-query-and-no-default":
455
+ "Spørringen er tom og det er ingen standardspørring.",
456
+ "query-not-changed":
457
+ "Søkeforespørselen har ikke endret seg, så ingen søk er nødvendig.",
458
+ };
459
+ case "dk":
460
+ return {
461
+ search: "Søg",
462
+ reset: "Nulstil",
463
+ save: "Gem",
464
+ "filter-name": "Filternavn",
465
+ "empty-query-and-no-default":
466
+ "Forespørgslen er tom og der er ingen standardforespørgsel.",
467
+ "query-not-changed":
468
+ "Søgeanmodningen er ikke ændret, så ingen søgning er nødvendig.",
469
+ };
470
+ case "sw":
471
+ return {
472
+ search: "Sök",
473
+ reset: "Återställ",
474
+ save: "Spara",
475
+ "filter-name": "Filternamn",
476
+ "empty-query-and-no-default":
477
+ "Förfrågan är tom och det finns ingen standardförfrågan.",
478
+ "query-not-changed":
479
+ "Sökförfrågan har inte ändrats, så ingen sökning krävs.",
480
+ };
481
+ default:
482
+ case "en":
483
+ return {
484
+ search: "Search",
485
+ reset: "Reset",
486
+ save: "Save",
487
+ "filter-name": "Filter name",
488
+ "empty-query-and-no-default":
489
+ "The query is empty and there is no default query.",
490
+ "query-not-changed":
491
+ "The search request has not changed, so no search is required.",
492
+ };
493
+ }
496
494
  }
497
495
 
498
496
  /**
@@ -500,51 +498,51 @@ function getTranslations() {
500
498
  * @return {FilterButton}
501
499
  */
502
500
  function initControlReferences() {
503
- if (!this.shadowRoot) {
504
- throw new Error("no shadow-root is defined");
505
- }
506
-
507
- this[filterControlElementSymbol] = this.shadowRoot.querySelector(
508
- "[data-monster-role=control]",
509
- );
510
- this[filterSelectElementSymbol] = this.shadowRoot.querySelector(
511
- "[data-monster-role=filter-select]",
512
- );
513
- this[searchButtonElementSymbol] = this.shadowRoot.querySelector(
514
- "[data-monster-role=search-button]",
515
- );
516
- this[resetButtonElementSymbol] = this.shadowRoot.querySelector(
517
- "[data-monster-role=reset-button]",
518
- );
519
-
520
- this[saveButtonElementSymbol] = this.shadowRoot.querySelector(
521
- "[data-monster-role=save-button]",
522
- );
523
-
524
- this[filterSaveActionButtonElementSymbol] = this.shadowRoot.querySelector(
525
- "[data-monster-role=save-action-button]",
526
- );
527
-
528
- this[filterTabElementSymbol] = findElementWithSelectorUpwards(
529
- this,
530
- this.getOption("storedConfig.selector", ""),
531
- );
532
-
533
- return this;
501
+ if (!this.shadowRoot) {
502
+ throw new Error("no shadow-root is defined");
503
+ }
504
+
505
+ this[filterControlElementSymbol] = this.shadowRoot.querySelector(
506
+ "[data-monster-role=control]",
507
+ );
508
+ this[filterSelectElementSymbol] = this.shadowRoot.querySelector(
509
+ "[data-monster-role=filter-select]",
510
+ );
511
+ this[searchButtonElementSymbol] = this.shadowRoot.querySelector(
512
+ "[data-monster-role=search-button]",
513
+ );
514
+ this[resetButtonElementSymbol] = this.shadowRoot.querySelector(
515
+ "[data-monster-role=reset-button]",
516
+ );
517
+
518
+ this[saveButtonElementSymbol] = this.shadowRoot.querySelector(
519
+ "[data-monster-role=save-button]",
520
+ );
521
+
522
+ this[filterSaveActionButtonElementSymbol] = this.shadowRoot.querySelector(
523
+ "[data-monster-role=save-action-button]",
524
+ );
525
+
526
+ this[filterTabElementSymbol] = findElementWithSelectorUpwards(
527
+ this,
528
+ this.getOption("storedConfig.selector", ""),
529
+ );
530
+
531
+ return this;
534
532
  }
535
533
 
536
534
  function updateFilterSelections() {
537
- queueMicrotask(() => {
538
- const options = this[settingsSymbol].getOptions();
539
- this[filterSelectElementSymbol].setOption("options", options);
540
-
541
- setTimeout(() => {
542
- window.requestAnimationFrame(() => {
543
- this[filterSelectElementSymbol].value =
544
- this[settingsSymbol].getSelected();
545
- });
546
- }, 0);
547
- });
535
+ queueMicrotask(() => {
536
+ const options = this[settingsSymbol].getOptions();
537
+ this[filterSelectElementSymbol].setOption("options", options);
538
+
539
+ setTimeout(() => {
540
+ window.requestAnimationFrame(() => {
541
+ this[filterSelectElementSymbol].value =
542
+ this[settingsSymbol].getSelected();
543
+ });
544
+ }, 0);
545
+ });
548
546
  }
549
547
 
550
548
  /**
@@ -552,65 +550,64 @@ function updateFilterSelections() {
552
550
  * @throws {Error} no filter label is defined
553
551
  */
554
552
  function initFilter() {
555
- const storedSetting = this[settingsSymbol];
556
- this[settingsSymbol] = new Settings();
557
-
558
- const result = parseBracketedKeyValueHash(getGlobal().location.hash);
559
- let valuesFromHash = {};
560
- if (isObject(result) && result?.[this.id]) {
561
- valuesFromHash = result[this.id];
562
- }
563
-
564
- getSlottedElements
565
- .call(this, "label[data-monster-label]")
566
- .forEach((element) => {
567
- const label = element.getAttribute("data-monster-label");
568
- if (!label) {
569
- addAttributeToken(
570
- this,
571
- ATTRIBUTE_ERRORMESSAGE,
572
- "no filter label is defined",
573
- );
574
- return;
575
- }
576
-
577
- let value = element.id;
578
- if (!value) {
579
- const prefix = label.replace(/\W/g, "-");
580
- prefix.charAt(0).match(/[\d_]/g)?.length ? `f${prefix}` : prefix;
581
-
582
- value = new ID(prefix + "-").toString();
583
- element.id = value;
584
- }
585
-
586
- let setting = storedSetting.get(value);
587
-
588
- if (setting) {
589
- this[settingsSymbol].set(setting);
590
- }
591
-
592
- if (valuesFromHash?.[element.id]) {
593
- const v = escapeAttributeValue(valuesFromHash[element.id]);
594
- const searchInput = element.firstElementChild;
595
- try {
596
- searchInput.value = v;
597
- } catch (error) {
598
- }
599
- }
600
-
601
- setting = this[settingsSymbol].get(value);
602
- let visible = false;
603
- if (setting) {
604
- setSlotAttribute(element, setting.visible);
605
- visible = setting.visible;
606
- } else {
607
- visible = getVisibilityFromSlotAttribute(element);
608
- }
609
-
610
- this[settingsSymbol].set({value, label, visible});
611
- });
612
-
613
- updateFilterSelections.call(this);
553
+ const storedSetting = this[settingsSymbol];
554
+ this[settingsSymbol] = new Settings();
555
+
556
+ const result = parseBracketedKeyValueHash(getGlobal().location.hash);
557
+ let valuesFromHash = {};
558
+ if (isObject(result) && result?.[this.id]) {
559
+ valuesFromHash = result[this.id];
560
+ }
561
+
562
+ getSlottedElements
563
+ .call(this, "label[data-monster-label]")
564
+ .forEach((element) => {
565
+ const label = element.getAttribute("data-monster-label");
566
+ if (!label) {
567
+ addAttributeToken(
568
+ this,
569
+ ATTRIBUTE_ERRORMESSAGE,
570
+ "no filter label is defined",
571
+ );
572
+ return;
573
+ }
574
+
575
+ let value = element.id;
576
+ if (!value) {
577
+ const prefix = label.replace(/\W/g, "-");
578
+ prefix.charAt(0).match(/[\d_]/g)?.length ? `f${prefix}` : prefix;
579
+
580
+ value = new ID(prefix + "-").toString();
581
+ element.id = value;
582
+ }
583
+
584
+ let setting = storedSetting.get(value);
585
+
586
+ if (setting) {
587
+ this[settingsSymbol].set(setting);
588
+ }
589
+
590
+ if (valuesFromHash?.[element.id]) {
591
+ const v = escapeAttributeValue(valuesFromHash[element.id]);
592
+ const searchInput = element.firstElementChild;
593
+ try {
594
+ searchInput.value = v;
595
+ } catch (error) {}
596
+ }
597
+
598
+ setting = this[settingsSymbol].get(value);
599
+ let visible = false;
600
+ if (setting) {
601
+ setSlotAttribute(element, setting.visible);
602
+ visible = setting.visible;
603
+ } else {
604
+ visible = getVisibilityFromSlotAttribute(element);
605
+ }
606
+
607
+ this[settingsSymbol].set({ value, label, visible });
608
+ });
609
+
610
+ updateFilterSelections.call(this);
614
611
  }
615
612
 
616
613
  /**
@@ -619,16 +616,16 @@ function initFilter() {
619
616
  * @return {*}
620
617
  */
621
618
  function escapeAttributeValue(input) {
622
- if (input === undefined || input === null) {
623
- return input;
624
- }
625
-
626
- return input
627
- .replace(/&/g, "&amp;")
628
- .replace(/"/g, "&quot;")
629
- .replace(/'/g, "&#x27;")
630
- .replace(/</g, "&lt;")
631
- .replace(/>/g, "&gt;");
619
+ if (input === undefined || input === null) {
620
+ return input;
621
+ }
622
+
623
+ return input
624
+ .replace(/&/g, "&amp;")
625
+ .replace(/"/g, "&quot;")
626
+ .replace(/'/g, "&#x27;")
627
+ .replace(/</g, "&lt;")
628
+ .replace(/>/g, "&gt;");
632
629
  }
633
630
 
634
631
  /**
@@ -637,9 +634,9 @@ function escapeAttributeValue(input) {
637
634
  * @return {boolean}
638
635
  */
639
636
  function getVisibilityFromSlotAttribute(element) {
640
- return !(
641
- element.hasAttribute("slot") && element.getAttribute("slot") === "hidden"
642
- );
637
+ return !(
638
+ element.hasAttribute("slot") && element.getAttribute("slot") === "hidden"
639
+ );
643
640
  }
644
641
 
645
642
  /**
@@ -648,376 +645,369 @@ function getVisibilityFromSlotAttribute(element) {
648
645
  * @param {boolean} visible
649
646
  */
650
647
  function setSlotAttribute(element, visible) {
651
- if (visible) {
652
- element.removeAttribute("slot");
653
- return;
654
- }
648
+ if (visible) {
649
+ element.removeAttribute("slot");
650
+ return;
651
+ }
655
652
 
656
- element.setAttribute("slot", "hidden");
653
+ element.setAttribute("slot", "hidden");
657
654
  }
658
655
 
659
656
  /**
660
657
  * @private
661
658
  */
662
659
  function initEventHandler() {
663
- const self = this;
664
-
665
- let lastHash = getGlobal().location.hash;
666
- self[locationChangeHandlerSymbol] = () => {
667
- if (lastHash === getGlobal().location.hash) {
668
- return;
669
- }
670
-
671
- /**
672
- * debounce the hash change event if doSearch
673
- * is called by click the search button
674
- */
675
- if (self[hashChangeSymbol] > 0) {
676
- self[hashChangeSymbol]--;
677
- return;
678
- }
679
-
680
- initFilter.call(this);
681
-
682
- doSearch
683
- .call(self)
684
- .then(() => {
685
- })
686
- .catch((error) => {
687
- })
688
- .finally(() => {
689
- lastHash = getGlobal().location.hash;
690
- });
691
- };
692
-
693
- /**
694
- * Monster.Components.Form.event:monster-selection-cleared
695
- */
696
- if (self[filterSelectElementSymbol]) {
697
- self[filterSelectElementSymbol].addEventListener(
698
- "monster-selection-cleared",
699
- function () {
700
- const settings = self[settingsSymbol].getOptions();
701
-
702
- for (const setting of settings) {
703
- const filterElement = findElementWithIdUpwards(self, setting.value);
704
- if (filterElement) {
705
- setSlotAttribute(filterElement, false);
706
-
707
- self[settingsSymbol].set({value: setting.value, visible: false});
708
- }
709
- }
710
-
711
- updateConfig.call(self);
712
- },
713
- );
714
-
715
- self[filterSelectElementSymbol].addEventListener(
716
- "monster-changed",
717
- function (event) {
718
- const filterElement = findElementWithIdUpwards(
719
- self,
720
- event.detail.value,
721
- );
722
- if (filterElement) {
723
- setSlotAttribute(filterElement, event.detail.checked);
724
- }
725
-
726
- self[settingsSymbol].set({
727
- value: event.detail.value,
728
- visible: event.detail.checked,
729
- });
730
-
731
- updateConfig.call(self);
732
- },
733
- );
734
- }
735
-
736
- /** save the current filter */
737
- if (self[filterSaveActionButtonElementSymbol]) {
738
- self[filterSaveActionButtonElementSymbol].setOption(
739
- "actions.click",
740
- function (event) {
741
- const button = findTargetElementFromEvent(
742
- event,
743
- "data-monster-role",
744
- "save-action-button",
745
- );
746
- const form = button.closest("[data-monster-role=form]");
747
-
748
- if (!form) {
749
- button.setState("failed", self.getOption("timeouts.message", 4000));
750
- return;
751
- }
752
-
753
- const input = form.querySelector("input[name=filter-name]");
754
- if (!input) {
755
- button.setState("failed", self.getOption("timeouts.message", 4000));
756
- return;
757
- }
758
-
759
- const name = input.value;
760
- if (!name) {
761
- button.setState("failed", self.getOption("timeouts.message", 4000));
762
- button.setMessage("Please enter a name").showMessage();
763
- return;
764
- }
765
-
766
- doSearch
767
- .call(self, {showEffect: false})
768
- .then(() => {
769
- const configKey = getStoredFilterConfigKey.call(self);
770
- const host = getDocument().querySelector("monster-host");
771
- if (!host) {
772
- return;
773
- }
774
-
775
- const query = self.getOption("query");
776
- if (!query) {
777
- button.setState(
778
- "failed",
779
- self.getOption(
780
- "timeouts.message",
781
- self.getOption("timeouts.message", 4000),
782
- ),
783
- );
784
- button
785
- .setMessage("No query found")
786
- .showMessage(self.getOption("timeouts.message", 4000));
787
- return;
788
- }
789
-
790
- host
791
- .hasConfig(configKey)
792
- .then((hasConfig) => {
793
- return new Promise((resolve, reject) => {
794
- if (hasConfig) {
795
- host.getConfig(configKey).then(resolve).catch(reject);
796
- return;
797
- }
798
- return resolve({});
799
- });
800
- })
801
- .then((config) => {
802
- config[name] = query;
803
- return host.setConfig(configKey, {
804
- ...config,
805
- });
806
- })
807
- .then(() => {
808
- button.setState(
809
- "successful",
810
- self.getOption("timeouts.message", 4000),
811
- );
812
- updateFilterTabs.call(self);
813
- })
814
- .catch((error) => {
815
- button.setState(
816
- "failed",
817
- self.getOption("timeouts.message", 4000),
818
- );
819
- button
820
- .setMessage(error.message)
821
- .showMessage(self.getOption("timeouts.message", 4000));
822
- });
823
- })
824
- .catch((error) => {
825
- button.setState("failed", self.getOption("timeouts.message", 4000));
826
- const msg = error.message || error;
827
- button
828
- .setMessage(msg)
829
- .showMessage(self.getOption("timeouts.message", 4000));
830
- });
831
- },
832
- );
833
- }
834
-
835
- self[searchButtonElementSymbol].setOption("actions.click", () => {
836
- self[hashChangeSymbol] = 1;
837
-
838
- doSearch
839
- .call(self)
840
- .then(() => {
841
- })
842
- .catch((error) => {
843
- });
844
- });
845
-
846
- // the reset button should reset the filter and the search query
847
- // all input elements should be reset to their default values
848
- // which is the empty string. we search for all input elements
849
- // in the filter and reset them to their default value
850
- self[resetButtonElementSymbol].setOption("actions.click", () => {
851
- getSlottedElements
852
- .call(self, "label[data-monster-label]")
853
- .forEach((element) => {
854
- const label = element.getAttribute("data-monster-label");
855
- if (!label) {
856
- return;
857
- }
858
-
859
- const input = element.firstElementChild;
860
-
861
- if (input) {
862
- input.value = "";
863
- }
864
- });
865
-
866
- doSearch
867
- .call(self, {showEffect: false})
868
- .then(() => {
869
- })
870
- .catch((e) => addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message));
871
- });
872
-
873
- self.addEventListener("keyup", (event) => {
874
- const path = event.composedPath();
875
- if (path.length === 0) {
876
- return;
877
- }
878
-
879
- if (!(path[0] instanceof HTMLInputElement)) {
880
- return;
881
- }
882
-
883
- if (event.keyCode === 13) {
884
- doSearch
885
- .call(self, {showEffect: false})
886
- .then(() => {
887
- })
888
- .catch((error) => {
889
- });
890
- }
891
- });
892
-
893
- // tabs
894
- const element = this[filterTabElementSymbol];
895
- if (element) {
896
- initTabEvents.call(this);
897
- }
660
+ const self = this;
661
+
662
+ let lastHash = getGlobal().location.hash;
663
+ self[locationChangeHandlerSymbol] = () => {
664
+ if (lastHash === getGlobal().location.hash) {
665
+ return;
666
+ }
667
+
668
+ /**
669
+ * debounce the hash change event if doSearch
670
+ * is called by click the search button
671
+ */
672
+ if (self[hashChangeSymbol] > 0) {
673
+ self[hashChangeSymbol]--;
674
+ return;
675
+ }
676
+
677
+ initFilter.call(this);
678
+
679
+ doSearch
680
+ .call(self)
681
+ .then(() => {})
682
+ .catch((error) => {})
683
+ .finally(() => {
684
+ lastHash = getGlobal().location.hash;
685
+ });
686
+ };
687
+
688
+ /**
689
+ * Monster.Components.Form.event:monster-selection-cleared
690
+ */
691
+ if (self[filterSelectElementSymbol]) {
692
+ self[filterSelectElementSymbol].addEventListener(
693
+ "monster-selection-cleared",
694
+ function () {
695
+ const settings = self[settingsSymbol].getOptions();
696
+
697
+ for (const setting of settings) {
698
+ const filterElement = findElementWithIdUpwards(self, setting.value);
699
+ if (filterElement) {
700
+ setSlotAttribute(filterElement, false);
701
+
702
+ self[settingsSymbol].set({ value: setting.value, visible: false });
703
+ }
704
+ }
705
+
706
+ updateConfig.call(self);
707
+ },
708
+ );
709
+
710
+ self[filterSelectElementSymbol].addEventListener(
711
+ "monster-changed",
712
+ function (event) {
713
+ const filterElement = findElementWithIdUpwards(
714
+ self,
715
+ event.detail.value,
716
+ );
717
+ if (filterElement) {
718
+ setSlotAttribute(filterElement, event.detail.checked);
719
+ }
720
+
721
+ self[settingsSymbol].set({
722
+ value: event.detail.value,
723
+ visible: event.detail.checked,
724
+ });
725
+
726
+ updateConfig.call(self);
727
+ },
728
+ );
729
+ }
730
+
731
+ /** save the current filter */
732
+ if (self[filterSaveActionButtonElementSymbol]) {
733
+ self[filterSaveActionButtonElementSymbol].setOption(
734
+ "actions.click",
735
+ function (event) {
736
+ const button = findTargetElementFromEvent(
737
+ event,
738
+ "data-monster-role",
739
+ "save-action-button",
740
+ );
741
+ const form = button.closest("[data-monster-role=form]");
742
+
743
+ if (!form) {
744
+ button.setState("failed", self.getOption("timeouts.message", 4000));
745
+ return;
746
+ }
747
+
748
+ const input = form.querySelector("input[name=filter-name]");
749
+ if (!input) {
750
+ button.setState("failed", self.getOption("timeouts.message", 4000));
751
+ return;
752
+ }
753
+
754
+ const name = input.value;
755
+ if (!name) {
756
+ button.setState("failed", self.getOption("timeouts.message", 4000));
757
+ button.setMessage("Please enter a name").showMessage();
758
+ return;
759
+ }
760
+
761
+ doSearch
762
+ .call(self, { showEffect: false })
763
+ .then(() => {
764
+ const configKey = getStoredFilterConfigKey.call(self);
765
+ const host = getDocument().querySelector("monster-host");
766
+ if (!host) {
767
+ return;
768
+ }
769
+
770
+ const query = self.getOption("query");
771
+ if (!query) {
772
+ button.setState(
773
+ "failed",
774
+ self.getOption(
775
+ "timeouts.message",
776
+ self.getOption("timeouts.message", 4000),
777
+ ),
778
+ );
779
+ button
780
+ .setMessage("No query found")
781
+ .showMessage(self.getOption("timeouts.message", 4000));
782
+ return;
783
+ }
784
+
785
+ host
786
+ .hasConfig(configKey)
787
+ .then((hasConfig) => {
788
+ return new Promise((resolve, reject) => {
789
+ if (hasConfig) {
790
+ host.getConfig(configKey).then(resolve).catch(reject);
791
+ return;
792
+ }
793
+ return resolve({});
794
+ });
795
+ })
796
+ .then((config) => {
797
+ config[name] = query;
798
+ return host.setConfig(configKey, {
799
+ ...config,
800
+ });
801
+ })
802
+ .then(() => {
803
+ button.setState(
804
+ "successful",
805
+ self.getOption("timeouts.message", 4000),
806
+ );
807
+ updateFilterTabs.call(self);
808
+ })
809
+ .catch((error) => {
810
+ button.setState(
811
+ "failed",
812
+ self.getOption("timeouts.message", 4000),
813
+ );
814
+ button
815
+ .setMessage(error.message)
816
+ .showMessage(self.getOption("timeouts.message", 4000));
817
+ });
818
+ })
819
+ .catch((error) => {
820
+ button.setState("failed", self.getOption("timeouts.message", 4000));
821
+ const msg = error.message || error;
822
+ button
823
+ .setMessage(msg)
824
+ .showMessage(self.getOption("timeouts.message", 4000));
825
+ });
826
+ },
827
+ );
828
+ }
829
+
830
+ self[searchButtonElementSymbol].setOption("actions.click", () => {
831
+ self[hashChangeSymbol] = 1;
832
+
833
+ doSearch
834
+ .call(self)
835
+ .then(() => {})
836
+ .catch((error) => {});
837
+ });
838
+
839
+ // the reset button should reset the filter and the search query
840
+ // all input elements should be reset to their default values
841
+ // which is the empty string. we search for all input elements
842
+ // in the filter and reset them to their default value
843
+ self[resetButtonElementSymbol].setOption("actions.click", () => {
844
+ getSlottedElements
845
+ .call(self, "label[data-monster-label]")
846
+ .forEach((element) => {
847
+ const label = element.getAttribute("data-monster-label");
848
+ if (!label) {
849
+ return;
850
+ }
851
+
852
+ const input = element.firstElementChild;
853
+
854
+ if (input) {
855
+ input.value = "";
856
+ }
857
+ });
858
+
859
+ doSearch
860
+ .call(self, { showEffect: false })
861
+ .then(() => {})
862
+ .catch((e) => addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message));
863
+ });
864
+
865
+ self.addEventListener("keyup", (event) => {
866
+ const path = event.composedPath();
867
+ if (path.length === 0) {
868
+ return;
869
+ }
870
+
871
+ if (!(path[0] instanceof HTMLInputElement)) {
872
+ return;
873
+ }
874
+
875
+ if (event.keyCode === 13) {
876
+ doSearch
877
+ .call(self, { showEffect: false })
878
+ .then(() => {})
879
+ .catch((error) => {});
880
+ }
881
+ });
882
+
883
+ // tabs
884
+ const element = this[filterTabElementSymbol];
885
+ if (element) {
886
+ initTabEvents.call(this);
887
+ }
898
888
  }
899
889
 
900
890
  function initTabEvents() {
901
- const self = this;
902
- this[filterTabElementSymbol].addEventListener(
903
- "monster-tab-changed",
904
- (event) => {
905
- const query = event?.detail?.data?.["data-monster-query"];
906
- const q = this.getOption("query");
907
- if (query !== q) {
908
- this.setOption("query", query);
909
- }
910
- },
911
- );
912
-
913
- this[filterTabElementSymbol].addEventListener(
914
- "monster-tab-remove",
915
- (event) => {
916
- const labels = [];
917
- const buttons = this[filterTabElementSymbol].getOption("buttons");
918
-
919
- const keys = ["popper", "standard"];
920
- for (let i = 0; i < keys.length; i++) {
921
- const key = keys[i];
922
-
923
- for (const button of buttons[key]) {
924
- if (button.label !== event.detail.label) {
925
- labels.push(button.label);
926
- }
927
- }
928
- }
929
-
930
- const host = findElementWithSelectorUpwards(this, "monster-host");
931
- if (!(host && this.id)) {
932
- return;
933
- }
934
-
935
- const configKey = getStoredFilterConfigKey.call(this);
936
- host
937
- .hasConfig(configKey)
938
- .then((hasConfig) => {
939
- if (!hasConfig) {
940
- return;
941
- }
942
-
943
- return host.getConfig(configKey);
944
- })
945
- .then((config) => {
946
- for (const [name, query] of Object.entries(config)) {
947
- if (labels.includes(name)) {
948
- continue;
949
- }
950
-
951
- delete config[name];
952
- }
953
-
954
- return host.setConfig(configKey, {
955
- ...config,
956
- });
957
- });
958
- },
959
- );
891
+ const self = this;
892
+ this[filterTabElementSymbol].addEventListener(
893
+ "monster-tab-changed",
894
+ (event) => {
895
+ const query = event?.detail?.data?.["data-monster-query"];
896
+ const q = this.getOption("query");
897
+ if (query !== q) {
898
+ this.setOption("query", query);
899
+ }
900
+ },
901
+ );
902
+
903
+ this[filterTabElementSymbol].addEventListener(
904
+ "monster-tab-remove",
905
+ (event) => {
906
+ const labels = [];
907
+ const buttons = this[filterTabElementSymbol].getOption("buttons");
908
+
909
+ const keys = ["popper", "standard"];
910
+ for (let i = 0; i < keys.length; i++) {
911
+ const key = keys[i];
912
+
913
+ for (const button of buttons[key]) {
914
+ if (button.label !== event.detail.label) {
915
+ labels.push(button.label);
916
+ }
917
+ }
918
+ }
919
+
920
+ const host = findElementWithSelectorUpwards(this, "monster-host");
921
+ if (!(host && this.id)) {
922
+ return;
923
+ }
924
+
925
+ const configKey = getStoredFilterConfigKey.call(this);
926
+ host
927
+ .hasConfig(configKey)
928
+ .then((hasConfig) => {
929
+ if (!hasConfig) {
930
+ return;
931
+ }
932
+
933
+ return host.getConfig(configKey);
934
+ })
935
+ .then((config) => {
936
+ for (const [name, query] of Object.entries(config)) {
937
+ if (labels.includes(name)) {
938
+ continue;
939
+ }
940
+
941
+ delete config[name];
942
+ }
943
+
944
+ return host.setConfig(configKey, {
945
+ ...config,
946
+ });
947
+ });
948
+ },
949
+ );
960
950
  }
961
951
 
962
952
  /**
963
953
  * @private
964
954
  */
965
955
  function updateFilterTabs() {
966
- const element = this[filterTabElementSymbol];
967
- if (!element) {
968
- return;
969
- }
970
-
971
- const host = findElementWithSelectorUpwards(this, "monster-host");
972
- if (!(host && this.id)) {
973
- return;
974
- }
975
-
976
- const configKey = getStoredFilterConfigKey.call(this);
977
- host
978
- .hasConfig(configKey)
979
- .then((hasConfig) => {
980
- if (!hasConfig) {
981
- return;
982
- }
983
-
984
- return host.getConfig(configKey);
985
- })
986
- .then((config) => {
987
- for (const [name, query] of Object.entries(config)) {
988
- const found = element.querySelector(
989
- `[data-monster-button-label="${name}"]`,
990
- );
991
- if (found) {
992
- continue;
993
- }
994
-
995
- if (query === undefined || query === null) {
996
- continue;
997
- }
998
-
999
- const escapedQuery = escapeAttributeValue(query);
1000
-
1001
- element.insertAdjacentHTML(
1002
- "beforeend",
1003
- `<div data-monster-button-label="${name}"
956
+ const element = this[filterTabElementSymbol];
957
+ if (!element) {
958
+ return;
959
+ }
960
+
961
+ const host = findElementWithSelectorUpwards(this, "monster-host");
962
+ if (!(host && this.id)) {
963
+ return;
964
+ }
965
+
966
+ const configKey = getStoredFilterConfigKey.call(this);
967
+ host
968
+ .hasConfig(configKey)
969
+ .then((hasConfig) => {
970
+ if (!hasConfig) {
971
+ return;
972
+ }
973
+
974
+ return host.getConfig(configKey);
975
+ })
976
+ .then((config) => {
977
+ for (const [name, query] of Object.entries(config)) {
978
+ const found = element.querySelector(
979
+ `[data-monster-button-label="${name}"]`,
980
+ );
981
+ if (found) {
982
+ continue;
983
+ }
984
+
985
+ if (query === undefined || query === null) {
986
+ continue;
987
+ }
988
+
989
+ const escapedQuery = escapeAttributeValue(query);
990
+
991
+ element.insertAdjacentHTML(
992
+ "beforeend",
993
+ `<div data-monster-button-label="${name}"
1004
994
  data-monster-removable="true"
1005
995
  data-monster-query="${escapedQuery}" data-monster-role="filter-tab" >
1006
996
  </div>`,
1007
- );
1008
- }
1009
- })
1010
- .catch((error) => {
1011
- if (error instanceof Error) {
1012
- addAttributeToken(
1013
- this,
1014
- ATTRIBUTE_ERRORMESSAGE,
1015
- error.message + " " + error.stack,
1016
- );
1017
- } else {
1018
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error + "");
1019
- }
1020
- });
997
+ );
998
+ }
999
+ })
1000
+ .catch((error) => {
1001
+ if (error instanceof Error) {
1002
+ addAttributeToken(
1003
+ this,
1004
+ ATTRIBUTE_ERRORMESSAGE,
1005
+ error.message + " " + error.stack,
1006
+ );
1007
+ } else {
1008
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error + "");
1009
+ }
1010
+ });
1021
1011
  }
1022
1012
 
1023
1013
  /**
@@ -1025,89 +1015,89 @@ function updateFilterTabs() {
1025
1015
  * @param showEffect
1026
1016
  * @return {Promise}
1027
1017
  */
1028
- function doSearch({showEffect} = {showEffect: true}) {
1029
- this.resetFailureMessage();
1030
-
1031
- if (showEffect) {
1032
- this[searchButtonElementSymbol].setState(
1033
- "activity",
1034
- this.getOption("timeouts.message", 4000),
1035
- );
1036
- }
1037
-
1038
- return collectSearchQueries
1039
- .call(this)
1040
- .then((query) => {
1041
- const buildQuery = buildSearchQuery.call(this, query);
1042
- if (buildQuery === null) {
1043
- const msg = this.getOption("labels.empty-query-and-no-default");
1044
- if (showEffect) {
1045
- this[searchButtonElementSymbol].removeState();
1046
- this[searchButtonElementSymbol]
1047
- .setMessage(msg)
1048
- .showMessage(this.getOption("timeouts.message", 4000));
1049
- }
1050
- return Promise.reject(new Error(msg));
1051
- }
1052
-
1053
- if (buildQuery === "" && this.getOption("defaultQuery") === null) {
1054
- const msg = this.getOption("labels.empty-query-and-no-default");
1055
-
1056
- if (showEffect) {
1057
- this[searchButtonElementSymbol].removeState();
1058
- this[searchButtonElementSymbol]
1059
- .setMessage(msg)
1060
- .showMessage(this.getOption("timeouts.message", 4000));
1061
- }
1062
-
1063
- return Promise.reject(new Error(msg));
1064
- }
1065
-
1066
- if (buildQuery === this.getOption("query")) {
1067
- const msg = this.getOption("labels.query-not-changed");
1068
-
1069
- if (showEffect) {
1070
- this[searchButtonElementSymbol].removeState();
1071
- this[searchButtonElementSymbol]
1072
- .setMessage(msg)
1073
- .showMessage(this.getOption("timeouts.message", 4000));
1074
- }
1075
-
1076
- return Promise.reject(new Error(msg));
1077
- }
1078
-
1079
- if (showEffect) {
1080
- this[searchButtonElementSymbol].setState(
1081
- "activity",
1082
- this.getOption("timeouts.message", 4000),
1083
- );
1084
- }
1085
-
1086
- this.setOption("query", buildSearchQuery.call(this, query));
1087
-
1088
- return Promise.resolve();
1089
- })
1090
- .catch((error) => {
1091
- if (error instanceof Error) {
1092
- addAttributeToken(
1093
- this,
1094
- ATTRIBUTE_ERRORMESSAGE,
1095
- error.message + " " + error.stack,
1096
- );
1097
- } else {
1098
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
1099
- }
1100
-
1101
- if (showEffect) {
1102
- this[searchButtonElementSymbol].setState(
1103
- "failed",
1104
- this.getOption("timeouts.message", 4000),
1105
- );
1106
- this[searchButtonElementSymbol].setMessage(error.message).showMessage();
1107
- }
1108
-
1109
- return Promise.reject(error);
1110
- });
1018
+ function doSearch({ showEffect } = { showEffect: true }) {
1019
+ this.resetFailureMessage();
1020
+
1021
+ if (showEffect) {
1022
+ this[searchButtonElementSymbol].setState(
1023
+ "activity",
1024
+ this.getOption("timeouts.message", 4000),
1025
+ );
1026
+ }
1027
+
1028
+ return collectSearchQueries
1029
+ .call(this)
1030
+ .then((query) => {
1031
+ const buildQuery = buildSearchQuery.call(this, query);
1032
+ if (buildQuery === null) {
1033
+ const msg = this.getOption("labels.empty-query-and-no-default");
1034
+ if (showEffect) {
1035
+ this[searchButtonElementSymbol].removeState();
1036
+ this[searchButtonElementSymbol]
1037
+ .setMessage(msg)
1038
+ .showMessage(this.getOption("timeouts.message", 4000));
1039
+ }
1040
+ return Promise.reject(new Error(msg));
1041
+ }
1042
+
1043
+ if (buildQuery === "" && this.getOption("defaultQuery") === null) {
1044
+ const msg = this.getOption("labels.empty-query-and-no-default");
1045
+
1046
+ if (showEffect) {
1047
+ this[searchButtonElementSymbol].removeState();
1048
+ this[searchButtonElementSymbol]
1049
+ .setMessage(msg)
1050
+ .showMessage(this.getOption("timeouts.message", 4000));
1051
+ }
1052
+
1053
+ return Promise.reject(new Error(msg));
1054
+ }
1055
+
1056
+ if (buildQuery === this.getOption("query")) {
1057
+ const msg = this.getOption("labels.query-not-changed");
1058
+
1059
+ if (showEffect) {
1060
+ this[searchButtonElementSymbol].removeState();
1061
+ this[searchButtonElementSymbol]
1062
+ .setMessage(msg)
1063
+ .showMessage(this.getOption("timeouts.message", 4000));
1064
+ }
1065
+
1066
+ return Promise.reject(new Error(msg));
1067
+ }
1068
+
1069
+ if (showEffect) {
1070
+ this[searchButtonElementSymbol].setState(
1071
+ "activity",
1072
+ this.getOption("timeouts.message", 4000),
1073
+ );
1074
+ }
1075
+
1076
+ this.setOption("query", buildSearchQuery.call(this, query));
1077
+
1078
+ return Promise.resolve();
1079
+ })
1080
+ .catch((error) => {
1081
+ if (error instanceof Error) {
1082
+ addAttributeToken(
1083
+ this,
1084
+ ATTRIBUTE_ERRORMESSAGE,
1085
+ error.message + " " + error.stack,
1086
+ );
1087
+ } else {
1088
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
1089
+ }
1090
+
1091
+ if (showEffect) {
1092
+ this[searchButtonElementSymbol].setState(
1093
+ "failed",
1094
+ this.getOption("timeouts.message", 4000),
1095
+ );
1096
+ this[searchButtonElementSymbol].setMessage(error.message).showMessage();
1097
+ }
1098
+
1099
+ return Promise.reject(error);
1100
+ });
1111
1101
  }
1112
1102
 
1113
1103
  /**
@@ -1116,21 +1106,21 @@ function doSearch({showEffect} = {showEffect: true}) {
1116
1106
  * @return {*|string}
1117
1107
  */
1118
1108
  function buildSearchQuery(queries) {
1119
- if (!isArray(queries) || queries.length === 0) {
1120
- return this.getOption("defaultQuery");
1121
- }
1109
+ if (!isArray(queries) || queries.length === 0) {
1110
+ return this.getOption("defaultQuery");
1111
+ }
1122
1112
 
1123
- const joinCallback = this.getOption("queries.join");
1124
- if (isFunction(joinCallback)) {
1125
- return joinCallback(queries);
1126
- }
1113
+ const joinCallback = this.getOption("queries.join");
1114
+ if (isFunction(joinCallback)) {
1115
+ return joinCallback(queries);
1116
+ }
1127
1117
 
1128
- const q = queries.join(" ").trim();
1129
- if (q.length === 0) {
1130
- return this.getOption("defaultQuery");
1131
- }
1118
+ const q = queries.join(" ").trim();
1119
+ if (q.length === 0) {
1120
+ return this.getOption("defaultQuery");
1121
+ }
1132
1122
 
1133
- return q;
1123
+ return q;
1134
1124
  }
1135
1125
 
1136
1126
  /**
@@ -1138,107 +1128,107 @@ function buildSearchQuery(queries) {
1138
1128
  * @return {Promise<unknown>}
1139
1129
  */
1140
1130
  function collectSearchQueries() {
1141
- const currentHash = parseBracketedKeyValueHash(getGlobal().location.hash);
1142
- const self = this;
1143
-
1144
- return new Promise((resolve, reject) => {
1145
- const query = [];
1146
- const wrapCallback = this.getOption("queries.wrap");
1147
-
1148
- let hasNoIdError = false;
1149
-
1150
- getSlottedElements
1151
- .call(this, "label[data-monster-label]")
1152
- .forEach((element) => {
1153
- const label = element.getAttribute("data-monster-label");
1154
- if (!label) {
1155
- throw new Error("no filter label is defined");
1156
- }
1157
-
1158
- const id = element.id;
1159
- if (!id) {
1160
- hasNoIdError = true;
1161
- return;
1162
- }
1163
-
1164
- const visible = getVisibilityFromSlotAttribute(element);
1165
- if (!visible) {
1166
- return;
1167
- }
1168
-
1169
- let template = element.getAttribute("data-monster-template");
1170
- if (!template) {
1171
- template = "${id}=${value}";
1172
- }
1173
-
1174
- const controlValue = getControlValuesFromLabel(element);
1175
- if (!controlValue) {
1176
- if (controlValue === "" && currentHash?.[this.id]?.[id]) {
1177
- delete currentHash[this.id][id];
1178
- }
1179
-
1180
- return;
1181
- }
1182
-
1183
- if (!isObject(currentHash[this.id])) {
1184
- currentHash[this.id] = {};
1185
- }
1186
- currentHash[this.id][id] = controlValue;
1187
-
1188
- const mapping = {
1189
- id,
1190
- value: controlValue,
1191
- label,
1192
- };
1193
-
1194
- const formatter = new Formatter(mapping, {
1195
- callbacks: {
1196
- range: (value, key) => {
1197
- return generateRangeComparisonExpression(value, key, {
1198
- urlEncode: true,
1199
- andOp: "AND",
1200
- orOp: "OR",
1201
- eqOp: "=",
1202
- gtOp: ">",
1203
- ltOp: "<",
1204
- });
1205
- },
1206
- "date-range": (value, key) => {
1207
- const query = parseDateInput(value, key);
1208
- if (!query || query === "false") {
1209
- return "";
1210
- }
1211
-
1212
- // return query as url encoded
1213
- return encodeURIComponent(query);
1214
- },
1215
- },
1216
- });
1217
-
1218
- if (self.getOption("formatter.marker.open")) {
1219
- formatter.setMarker(
1220
- self.getOption("formatter.marker.open"),
1221
- self.getOption("formatter.marker.close"),
1222
- );
1223
- }
1224
-
1225
- let queryPart = formatter.format(template);
1226
- if (queryPart) {
1227
- if (isFunction(wrapCallback)) {
1228
- queryPart = wrapCallback(queryPart, mapping);
1229
- }
1230
- query.push(queryPart);
1231
- }
1232
- });
1233
-
1234
- if (hasNoIdError) {
1235
- reject(new Error("some or all filter elements have no id"));
1236
- return;
1237
- }
1238
-
1239
- getGlobal().location.hash = createBracketedKeyValueHash(currentHash);
1240
- resolve(query);
1241
- });
1131
+ const currentHash = parseBracketedKeyValueHash(getGlobal().location.hash);
1132
+ const self = this;
1133
+
1134
+ return new Promise((resolve, reject) => {
1135
+ const query = [];
1136
+ const wrapCallback = this.getOption("queries.wrap");
1137
+
1138
+ let hasNoIdError = false;
1139
+
1140
+ getSlottedElements
1141
+ .call(this, "label[data-monster-label]")
1142
+ .forEach((element) => {
1143
+ const label = element.getAttribute("data-monster-label");
1144
+ if (!label) {
1145
+ throw new Error("no filter label is defined");
1146
+ }
1147
+
1148
+ const id = element.id;
1149
+ if (!id) {
1150
+ hasNoIdError = true;
1151
+ return;
1152
+ }
1153
+
1154
+ const visible = getVisibilityFromSlotAttribute(element);
1155
+ if (!visible) {
1156
+ return;
1157
+ }
1158
+
1159
+ let template = element.getAttribute("data-monster-template");
1160
+ if (!template) {
1161
+ template = "${id}=${value}";
1162
+ }
1163
+
1164
+ const controlValue = getControlValuesFromLabel(element);
1165
+ if (!controlValue) {
1166
+ if (controlValue === "" && currentHash?.[this.id]?.[id]) {
1167
+ delete currentHash[this.id][id];
1168
+ }
1169
+
1170
+ return;
1171
+ }
1172
+
1173
+ if (!isObject(currentHash[this.id])) {
1174
+ currentHash[this.id] = {};
1175
+ }
1176
+ currentHash[this.id][id] = controlValue;
1177
+
1178
+ const mapping = {
1179
+ id,
1180
+ value: controlValue,
1181
+ label,
1182
+ };
1183
+
1184
+ const formatter = new Formatter(mapping, {
1185
+ callbacks: {
1186
+ range: (value, key) => {
1187
+ return generateRangeComparisonExpression(value, key, {
1188
+ urlEncode: true,
1189
+ andOp: "AND",
1190
+ orOp: "OR",
1191
+ eqOp: "=",
1192
+ gtOp: ">",
1193
+ ltOp: "<",
1194
+ });
1195
+ },
1196
+ "date-range": (value, key) => {
1197
+ const query = parseDateInput(value, key);
1198
+ if (!query || query === "false") {
1199
+ return "";
1200
+ }
1201
+
1202
+ // return query as url encoded
1203
+ return encodeURIComponent(query);
1204
+ },
1205
+ },
1206
+ });
1207
+
1208
+ if (self.getOption("formatter.marker.open")) {
1209
+ formatter.setMarker(
1210
+ self.getOption("formatter.marker.open"),
1211
+ self.getOption("formatter.marker.close"),
1212
+ );
1213
+ }
1214
+
1215
+ let queryPart = formatter.format(template);
1216
+ if (queryPart) {
1217
+ if (isFunction(wrapCallback)) {
1218
+ queryPart = wrapCallback(queryPart, mapping);
1219
+ }
1220
+ query.push(queryPart);
1221
+ }
1222
+ });
1223
+
1224
+ if (hasNoIdError) {
1225
+ reject(new Error("some or all filter elements have no id"));
1226
+ return;
1227
+ }
1228
+
1229
+ getGlobal().location.hash = createBracketedKeyValueHash(currentHash);
1230
+ resolve(query);
1231
+ });
1242
1232
  }
1243
1233
 
1244
1234
  /**
@@ -1247,41 +1237,41 @@ function collectSearchQueries() {
1247
1237
  * @return {null|Array|undefined|string}
1248
1238
  */
1249
1239
  function getControlValuesFromLabel(label) {
1250
- // finde das erste Kind-Element vom type input
1251
- // wenn es ein input-Element ist, dann @todo
1252
-
1253
- const foundControl = label.firstElementChild;
1254
-
1255
- if (foundControl) {
1256
- if (foundControl.tagName === "INPUT") {
1257
- if (foundControl.type === "checkbox") {
1258
- const checkedControls = label.querySelectorAll(
1259
- `${foundControl}:checked`,
1260
- );
1261
- const values = [];
1262
-
1263
- checkedControls.forEach((checkedControl) => {
1264
- values.push(checkedControl.value);
1265
- });
1266
-
1267
- return values;
1268
- } else if (foundControl.type === "radio") {
1269
- const checkedControl = label.querySelector(`${foundControl}:checked`);
1270
-
1271
- if (checkedControl) {
1272
- return checkedControl.value;
1273
- } else {
1274
- return null;
1275
- }
1276
- } else {
1277
- return foundControl.value;
1278
- }
1279
- } else {
1280
- return foundControl.value;
1281
- }
1282
- }
1283
-
1284
- return null;
1240
+ // finde das erste Kind-Element vom type input
1241
+ // wenn es ein input-Element ist, dann @todo
1242
+
1243
+ const foundControl = label.firstElementChild;
1244
+
1245
+ if (foundControl) {
1246
+ if (foundControl.tagName === "INPUT") {
1247
+ if (foundControl.type === "checkbox") {
1248
+ const checkedControls = label.querySelectorAll(
1249
+ `${foundControl}:checked`,
1250
+ );
1251
+ const values = [];
1252
+
1253
+ checkedControls.forEach((checkedControl) => {
1254
+ values.push(checkedControl.value);
1255
+ });
1256
+
1257
+ return values;
1258
+ } else if (foundControl.type === "radio") {
1259
+ const checkedControl = label.querySelector(`${foundControl}:checked`);
1260
+
1261
+ if (checkedControl) {
1262
+ return checkedControl.value;
1263
+ } else {
1264
+ return null;
1265
+ }
1266
+ } else {
1267
+ return foundControl.value;
1268
+ }
1269
+ } else {
1270
+ return foundControl.value;
1271
+ }
1272
+ }
1273
+
1274
+ return null;
1285
1275
  }
1286
1276
 
1287
1277
  /**
@@ -1289,60 +1279,60 @@ function getControlValuesFromLabel(label) {
1289
1279
  * @return {Promise<unknown>}
1290
1280
  */
1291
1281
  function initFromConfig() {
1292
- const host = findElementWithSelectorUpwards(this, "monster-host");
1293
-
1294
- if (!(isInstance(host, Host) && this.id)) {
1295
- return Promise.resolve();
1296
- }
1297
-
1298
- const configKey = getFilterConfigKey.call(this);
1299
-
1300
- return new Promise((resolve, reject) => {
1301
- host
1302
- .getConfig(configKey)
1303
- .then((config) => {
1304
- if ((config && isObject(config)) || isArray(config)) {
1305
- this[settingsSymbol].setOptions(config);
1306
- }
1307
- resolve();
1308
- })
1309
- .catch((error) => {
1310
- if (error === undefined) {
1311
- resolve();
1312
- return;
1313
- }
1314
-
1315
- // config not written
1316
- if (error?.message?.match(/is not defined/)) {
1317
- resolve();
1318
- return;
1319
- }
1320
-
1321
- addAttributeToken(
1322
- this,
1323
- ATTRIBUTE_ERRORMESSAGE,
1324
- error?.message || error,
1325
- );
1326
- reject(error);
1327
- });
1328
- });
1282
+ const host = findElementWithSelectorUpwards(this, "monster-host");
1283
+
1284
+ if (!(isInstance(host, Host) && this.id)) {
1285
+ return Promise.resolve();
1286
+ }
1287
+
1288
+ const configKey = getFilterConfigKey.call(this);
1289
+
1290
+ return new Promise((resolve, reject) => {
1291
+ host
1292
+ .getConfig(configKey)
1293
+ .then((config) => {
1294
+ if ((config && isObject(config)) || isArray(config)) {
1295
+ this[settingsSymbol].setOptions(config);
1296
+ }
1297
+ resolve();
1298
+ })
1299
+ .catch((error) => {
1300
+ if (error === undefined) {
1301
+ resolve();
1302
+ return;
1303
+ }
1304
+
1305
+ // config not written
1306
+ if (error?.message?.match(/is not defined/)) {
1307
+ resolve();
1308
+ return;
1309
+ }
1310
+
1311
+ addAttributeToken(
1312
+ this,
1313
+ ATTRIBUTE_ERRORMESSAGE,
1314
+ error?.message || error,
1315
+ );
1316
+ reject(error);
1317
+ });
1318
+ });
1329
1319
  }
1330
1320
 
1331
1321
  /**
1332
1322
  * @private
1333
1323
  */
1334
1324
  function updateConfig() {
1335
- const host = findElementWithSelectorUpwards(this, "monster-host");
1336
- if (!(host && this.id)) {
1337
- return;
1338
- }
1339
- const configKey = getFilterConfigKey.call(this);
1340
-
1341
- try {
1342
- host.setConfig(configKey, this[settingsSymbol].getOptions());
1343
- } catch (error) {
1344
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error?.message || error);
1345
- }
1325
+ const host = findElementWithSelectorUpwards(this, "monster-host");
1326
+ if (!(host && this.id)) {
1327
+ return;
1328
+ }
1329
+ const configKey = getFilterConfigKey.call(this);
1330
+
1331
+ try {
1332
+ host.setConfig(configKey, this[settingsSymbol].getOptions());
1333
+ } catch (error) {
1334
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error?.message || error);
1335
+ }
1346
1336
  }
1347
1337
 
1348
1338
  /**
@@ -1350,8 +1340,8 @@ function updateConfig() {
1350
1340
  * @return {string}
1351
1341
  */
1352
1342
  function getTemplate() {
1353
- // language=HTML
1354
- return `
1343
+ // language=HTML
1344
+ return `
1355
1345
  <div data-monster-role="control" part="control">
1356
1346
  <div data-monster-role="container">
1357
1347
  <div data-monster-role="layout">